Skip to content

Instantly share code, notes, and snippets.

@wahyd4
Created April 23, 2019 04:49
Show Gist options
  • Select an option

  • Save wahyd4/b5b31bd7287198aecc24768ceed93c9c to your computer and use it in GitHub Desktop.

Select an option

Save wahyd4/b5b31bd7287198aecc24768ceed93c9c to your computer and use it in GitHub Desktop.

Revisions

  1. wahyd4 created this gist Apr 23, 2019.
    135 changes: 135 additions & 0 deletions oz-lotto-multiple-goroutine
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,135 @@
    package main

    import (
    "flag"
    "fmt"
    "math/rand"
    "sort"
    "sync"
    "time"
    )

    // const
    const (
    NumberCount = 7
    MaximumResults = 50
    Routines = 10
    )

    var (
    syncWinners sync.Map
    signals = make(chan bool, 100)
    )

    func main() {
    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
    }