2020-11-16 09:40:45 -09:00

58 lines
1.4 KiB
Go

package main
import (
"fmt"
"math"
"math/rand"
"time"
)
// "given"
func dice6() int {
return rand.Intn(6) + 1
}
// function specified by task "Seven-sided dice from five-sided dice"
func dice16() (i int) {
for {
i = 6*dice6() - dice6()
if i < 32 {
break
}
}
return (i / 2) + 1
}
// function specified by task "Verify distribution uniformity/Naive"
//
// Parameter "f" is expected to return a random integer in the range 1..n.
// (Values out of range will cause an unceremonious crash.)
// "Max" is returned as an "indication of distribution achieved."
// It is the maximum delta observed from the count representing a perfectly
// uniform distribution.
// Also returned is a boolean, true if "max" is less than threshold
// parameter "delta."
func distCheck(f func() int, n int,
repeats int, delta float64) (max float64, flatEnough bool) {
count := make([]int, n)
for i := 0; i < repeats; i++ {
count[f()-1]++
}
expected := float64(repeats) / float64(n)
for _, c := range count {
max = math.Max(max, math.Abs(float64(c)-expected))
}
fmt.Println(count)
return max, max < delta
}
// Driver, produces output satisfying both tasks.
func main() {
rand.Seed(time.Now().UnixNano())
const calls = 1000000
max, flatEnough := distCheck(dice16, 16, calls, 500)
fmt.Println("Max delta:", max, "Flat enough:", flatEnough)
max, flatEnough = distCheck(dice16, 16, calls, 500)
fmt.Println("Max delta:", max, "Flat enough:", flatEnough)
}