2020-11-14 15:44:42 +00:00
package main
import (
"bufio"
"fmt"
"log"
"math"
"math/rand"
"os"
"runtime"
"time"
)
const (
randomMin = 0
randomMax = 9999999999999999
numSamples = 10000000
)
func main ( ) {
results := [ 9 ] int { } // There are 9 possible leading digits and 0 does not count, offset by 1 for index to actual value. Examples: To access 1 use [0]. To access 5 use [4]. To access 9 use [8].
currentSample := 0
statusTicker := time . NewTicker ( time . Second )
go func ( ) {
for {
<- statusTicker . C
percentCompleted := ( currentSample * 100 ) / numSamples
2020-11-14 17:25:49 +00:00
log . Printf ( "%d%% completed generating and analyzing samples" , percentCompleted )
2020-11-14 15:44:42 +00:00
}
} ( )
log . Printf ( "generating numbers..." )
rand . Seed ( time . Now ( ) . UnixNano ( ) )
generatedNumbers := make ( chan int , 1024 )
for i := 0 ; i < runtime . NumCPU ( ) ; i ++ {
go generatorWorker ( generatedNumbers )
}
for currentSample = 0 ; currentSample < numSamples ; currentSample ++ {
results [ firstDigit ( <- generatedNumbers ) - 1 ] ++
}
statusTicker . Stop ( )
log . Printf ( "done." )
// output results
for digitMinusOne , count := range results {
2020-11-14 17:25:49 +00:00
fmt . Printf ( "%d: %d (%f%%)\n" , digitMinusOne + 1 , count , float64 ( count * 100 ) / float64 ( numSamples ) )
2020-11-14 15:44:42 +00:00
}
fmt . Print ( "Press 'Enter' to continue..." )
bufio . NewReader ( os . Stdin ) . ReadBytes ( '\n' )
}
func generatorWorker ( returnChannel chan int ) {
for {
returnChannel <- rand . Intn ( randomMax - randomMin + 1 ) + randomMin // We must use Intn instead of Int because from Base10's perspective, integers cut off at a really weird spot
}
}
2020-11-14 17:25:49 +00:00
// firstDigit returns the first/leftmost digit of the base10 representation of an integer
2020-11-14 15:44:42 +00:00
func firstDigit ( x int ) int {
return int ( math . Abs ( float64 ( x ) ) / math . Pow ( 10 , float64 ( numDigits ( x ) - 1 ) ) )
}
2020-11-14 17:25:49 +00:00
// numDigits returns the number of digits
2020-11-14 15:44:42 +00:00
func numDigits ( x int ) int {
if x == 0 {
return 1
}
return int ( math . Floor ( math . Log10 ( math . Abs ( float64 ( x ) ) ) ) ) + 1
}