Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 45
Good morning! Here's your coding interview problem for today.

This problem was asked by Two Sigma.

Using a function rand5() that returns an integer from 1 to 5 (inclusive) with uniform probability, implement a function rand7() that returns an integer from 1 to 7 (inclusive).

Pull request:
Day45
Resolves #101 .

Patch:
diff --git a/README.md b/README.md
index 63da496..7356bbb 100644
--- a/README.md
+++ b/README.md
@@ -57,3 +57,4 @@ problems from
 * [Day 42](https://github.com/vaskoz/dailycodingproblem-go/issues/93)
 * [Day 43](https://github.com/vaskoz/dailycodingproblem-go/issues/95)
 * [Day 44](https://github.com/vaskoz/dailycodingproblem-go/issues/99)
+* [Day 45](https://github.com/vaskoz/dailycodingproblem-go/issues/101)
diff --git a/day45/problem.go b/day45/problem.go
new file mode 100644
index 0000000..ab8b061
--- /dev/null
+++ b/day45/problem.go
@@ -0,0 +1,31 @@
+package day45
+
+import (
+	"math/rand"
+	"time"
+)
+
+var random *rand.Rand
+
+// GetRandom returns a *math.Rand.
+func GetRandom() *rand.Rand {
+	if random == nil {
+		random = rand.New(rand.NewSource(time.Now().UnixNano()))
+	}
+	return random
+}
+
+// Rand5 returns a random integer between 1 and 5 inclusive with uniform probability.
+func Rand5() int {
+	return GetRandom().Intn(5) + 1
+}
+
+// Rand7 returns a random integer between 1 and 7 inclusive with uniform probability.
+// The trick is using Rand5 to accomplish that.
+func Rand7() int {
+	twentyOne := 22
+	for twentyOne > 21 {
+		twentyOne = 5*Rand5() + Rand5() - 5
+	}
+	return (twentyOne % 7) + 1
+}


Test patch:
diff --git a/day45/problem_test.go b/day45/problem_test.go
new file mode 100644
index 0000000..475814e
--- /dev/null
+++ b/day45/problem_test.go
@@ -0,0 +1,24 @@
+package day45
+
+import "testing"
+
+func TestRand7(t *testing.T) {
+	t.Parallel()
+	counter := make([]int, 8) // we ignore 0, because 1-7 inclusive.
+	for i := 0; i < 1000000; i++ {
+		counter[Rand7()]++
+	}
+	uniform := 1000000 / 7
+	tolerance := 1500
+	for i := 1; i <= 7; i++ {
+		if counter[i] < uniform-tolerance || counter[i] > uniform+tolerance {
+			t.Errorf("Expected closer to uniform %d got %d", uniform, counter[i])
+		}
+	}
+}
+
+func BenchmarkRand7(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Rand7()
+	}
+}