58 lines
1.4 KiB
Go
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)
|
|
}
|