74 lines
1.6 KiB
Go
74 lines
1.6 KiB
Go
|
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
|
||
|
log.Printf("%d %% completed generating and analyzing samples", percentCompleted)
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
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 {
|
||
|
fmt.Printf("%d: %d\n", digitMinusOne+1, count)
|
||
|
}
|
||
|
|
||
|
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
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func firstDigit(x int) int {
|
||
|
return int(math.Abs(float64(x)) / math.Pow(10, float64(numDigits(x)-1)))
|
||
|
}
|
||
|
|
||
|
func numDigits(x int) int {
|
||
|
if x == 0 {
|
||
|
return 1
|
||
|
}
|
||
|
return int(math.Floor(math.Log10(math.Abs(float64(x))))) + 1
|
||
|
}
|