Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 178
Good morning! Here's your coding interview problem for today.

This problem was asked by Two Sigma.

Alice wants to join her school's Probability Student Club. Membership dues are computed via one of two simple probabilistic games.

The first game: roll a die repeatedly. Stop rolling once you get a five followed by a six. Your number of rolls is the amount you pay, in dollars.

The second game: same, except that the stopping condition is a five followed by a five.

Which of the two games should Alice elect to play? Does it even matter? Write a program to simulate the two games and calculate their expected value.

Pull request description:
Day178
Resolves #367.

Patch:
diff --git a/README.md b/README.md
index a28119e..782c346 100644
--- a/README.md
+++ b/README.md
@@ -186,3 +186,4 @@ problems from
 * [Day 172](https://github.com/vaskoz/dailycodingproblem-go/issues/358)
 * [Day 173](https://github.com/vaskoz/dailycodingproblem-go/issues/360)
 * [Day 177](https://github.com/vaskoz/dailycodingproblem-go/issues/365)
+* [Day 178](https://github.com/vaskoz/dailycodingproblem-go/issues/367)
diff --git a/day178/problem.go b/day178/problem.go
new file mode 100644
index 0000000..adc6bf4
--- /dev/null
+++ b/day178/problem.go
@@ -0,0 +1,53 @@
+package day178
+
+import (
+	"math/rand"
+	"time"
+)
+
+// Dice represents a 6-sided random die.
+type Dice struct {
+	r *rand.Rand
+}
+
+// Next returns the value of the next die throw.
+func (d *Dice) Next() int {
+	if d.r == nil {
+		d.r = rand.New(rand.NewSource(time.Now().UnixNano()))
+	}
+	return d.r.Intn(6) + 1
+}
+
+// FirstGame returns the number of rolls required to meet the condition.
+// Condition is a five followed by a six.
+func FirstGame(d *Dice) int {
+	var rolls int
+	var prevFive bool
+	for {
+		rolls++
+		if value := d.Next(); value == 5 {
+			prevFive = true
+		} else if value == 6 && prevFive {
+			return rolls
+		} else {
+			prevFive = false
+		}
+	}
+}
+
+// SecondGame returns the number of rolls required to meet the condition.
+// Condition is a five followed by another five.
+func SecondGame(d *Dice) int {
+	var rolls int
+	var prevFive bool
+	for {
+		rolls++
+		if value := d.Next(); value == 5 && prevFive {
+			return rolls
+		} else if value == 5 {
+			prevFive = true
+		} else {
+			prevFive = false
+		}
+	}
+}


Test patch:
diff --git a/day178/problem_test.go b/day178/problem_test.go
new file mode 100644
index 0000000..c5c29e0
--- /dev/null
+++ b/day178/problem_test.go
@@ -0,0 +1,33 @@
+package day178
+
+import "testing"
+
+func TestFirstGame(t *testing.T) {
+	t.Parallel()
+	var d Dice
+	if cost := FirstGame(&d); cost > 500 {
+		t.Errorf("Expected result to be around 36, got %v", cost)
+	}
+}
+
+func TestSecondGame(t *testing.T) {
+	t.Parallel()
+	var d Dice
+	if cost := SecondGame(&d); cost > 500 {
+		t.Errorf("Expected result to be around 36, got %v", cost)
+	}
+}
+
+func BenchmarkFirstGame(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var d Dice
+		FirstGame(&d)
+	}
+}
+
+func BenchmarkSecondGame(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var d Dice
+		SecondGame(&d)
+	}
+}