sundries

Assorted little morsels for your enjoyment

git clone https://code.pdelong.com/sundries.git

 1package main
 2
 3import (
 4	"fmt"
 5	"math/rand"
 6	"os"
 7	"runtime"
 8	"strconv"
 9)
10
11type simulationOutput struct {
12	each int
13	num  int64
14}
15
16func simulateOnce(each int, r *rand.Rand) int {
17	nWhite := each
18	nRed := each
19
20	for i := 0; i < 19; i++ {
21		if r.Intn(nWhite+nRed)+1 > nWhite {
22			nRed--
23		} else {
24			nWhite--
25		}
26	}
27
28	// pickedWhite - pickedRed == (each - nWhite) - (each - nRed) == nRed - nWhite
29	return nRed - nWhite
30}
31
32func simulateNTimes(each, n int, r *rand.Rand) int64 {
33	var count int64 = 0
34	for i := 0; i < n; i++ {
35		if simulateOnce(each, r) == 3 {
36			count++
37		}
38	}
39
40	return count
41}
42
43func worker(workCh chan int, outCh chan simulationOutput, iters int) {
44	r := rand.New(rand.NewSource(rand.Int63()))
45	for each := range workCh {
46		outCh <- simulationOutput{
47			each: each,
48			num:  simulateNTimes(each, iters, r),
49		}
50	}
51}
52
53func main() {
54	if len(os.Args) != 3 {
55		fmt.Println("usage: count <MAX_BALLS> <ITERS>")
56		os.Exit(1)
57	}
58
59	maxBalls, err := strconv.Atoi(os.Args[1])
60	if err != nil {
61		fmt.Printf("Unable to convert %q to an int\n", os.Args[1])
62		os.Exit(1)
63	}
64
65	iters, err := strconv.Atoi(os.Args[2])
66	if err != nil {
67		fmt.Printf("Unable to convert %q to an int\n", os.Args[2])
68		os.Exit(1)
69	}
70
71	workCh := make(chan int)
72	outCh := make(chan simulationOutput)
73
74	for i := 0; i < runtime.NumCPU(); i++ {
75		go worker(workCh, outCh, iters)
76	}
77
78	go func() {
79		for i := 11; i <= maxBalls; i++ {
80			workCh <- i
81		}
82
83		close(workCh)
84	}()
85
86	for i := 11; i <= maxBalls; i++ {
87		out := <-outCh
88		fmt.Printf("%d %d\n", out.each, out.num)
89	}
90
91	close(outCh)
92}