mirror of
https://github.com/wahyd4/oz-lotto.git
synced 2026-08-08 21:07:36 +10:00
138 lines
2.6 KiB
Go
138 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"math/rand"
|
|
"runtime"
|
|
"sort"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// const
|
|
const (
|
|
NumberCount = 7
|
|
MaximumResults = 50
|
|
Routines = 10
|
|
)
|
|
|
|
var (
|
|
syncWinners sync.Map
|
|
signals = make(chan bool, Routines)
|
|
)
|
|
|
|
func main() {
|
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
|
timesInput := flag.Int("t", 100000, "an int")
|
|
flag.Parse()
|
|
times := *timesInput
|
|
|
|
now := time.Now()
|
|
|
|
startTime := now.Unix()
|
|
|
|
fmt.Printf("Started at %v to run lottery for %v times \n", now, times)
|
|
for routine := 0; routine < Routines; routine++ {
|
|
go func() {
|
|
for i := 0; i < times/Routines; i++ {
|
|
winner := run()
|
|
if currentTimes, ok := syncWinners.Load(winner); ok {
|
|
currentTimesInt := currentTimes.(int)
|
|
syncWinners.Store(winner, currentTimesInt+1)
|
|
} else {
|
|
syncWinners.Store(winner, 1)
|
|
}
|
|
}
|
|
signals <- true
|
|
}()
|
|
}
|
|
|
|
routineReturnTimes := 0
|
|
for range signals {
|
|
routineReturnTimes++
|
|
fmt.Println(routineReturnTimes)
|
|
if routineReturnTimes == Routines {
|
|
close(signals)
|
|
}
|
|
}
|
|
|
|
fmt.Printf("Calculation finished at : %v \n", time.Now())
|
|
// only print out top numbers
|
|
type kv struct {
|
|
Key [NumberCount]int
|
|
Value int
|
|
}
|
|
|
|
var ss []kv
|
|
|
|
syncWinners.Range(func(key interface{}, value interface{}) bool {
|
|
winningTimes := value.(int)
|
|
winningNumber := key.([7]int)
|
|
if winningTimes > 1 {
|
|
ss = append(ss, kv{winningNumber, winningTimes})
|
|
}
|
|
return true
|
|
})
|
|
|
|
sort.Slice(ss, func(i, j int) bool {
|
|
return ss[i].Value > ss[j].Value
|
|
})
|
|
|
|
fmt.Printf("Sorting finished at : %v \n", time.Now())
|
|
|
|
index := 0
|
|
for _, kv := range ss {
|
|
// only pick the top numbers
|
|
if index > MaximumResults {
|
|
break
|
|
}
|
|
fmt.Printf("%v, %d \n", kv.Key, kv.Value)
|
|
index++
|
|
}
|
|
fmt.Printf("The process takes about: %v seconds", time.Now().Unix()-startTime)
|
|
}
|
|
|
|
func run() [7]int {
|
|
var winNumbers []int
|
|
// generate the randomised numbers
|
|
list := rand.Perm(45)
|
|
// because perm generate [0,45) but we need [1,45]
|
|
for index, item := range list {
|
|
list[index] = item + 1
|
|
}
|
|
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
indexes := make([]int, 0)
|
|
|
|
for i := 0; i < NumberCount; i++ {
|
|
pickedIndex := pickIndex(indexes, len(list))
|
|
indexes = append(indexes, pickedIndex)
|
|
|
|
//pick random number
|
|
chosen := list[pickedIndex]
|
|
|
|
winNumbers = append(winNumbers, chosen)
|
|
}
|
|
|
|
sort.Ints(winNumbers)
|
|
var arr [NumberCount]int
|
|
copy(arr[:], winNumbers)
|
|
|
|
return arr
|
|
|
|
}
|
|
|
|
func pickIndex(indexes []int, length int) int {
|
|
chosen := rand.Intn(length - 1)
|
|
// make sure the index only exist once
|
|
for _, value := range indexes {
|
|
if value == chosen {
|
|
return pickIndex(indexes, length)
|
|
}
|
|
}
|
|
|
|
return chosen
|
|
}
|