diff --git a/cmd/rand-convert/main.go b/cmd/rand-convert/main.go new file mode 100644 index 0000000..45e1f43 --- /dev/null +++ b/cmd/rand-convert/main.go @@ -0,0 +1,57 @@ +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) +}