Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 159
Good morning! Here's your coding interview problem for today.

This problem was asked by Google.

Given a string, return the first recurring character in it, or null if there is no recurring character.

For example, given the string "acbbac", return "b". Given the string "abcdef", return null.

Pull request description:
Day159
Resolves #331.

Patch:
diff --git a/README.md b/README.md
index 4d48781..f78f0dc 100644
--- a/README.md
+++ b/README.md
@@ -169,3 +169,4 @@ problems from
 * [Day 156](https://github.com/vaskoz/dailycodingproblem-go/issues/325)
 * [Day 157](https://github.com/vaskoz/dailycodingproblem-go/issues/327)
 * [Day 158](https://github.com/vaskoz/dailycodingproblem-go/issues/329)
+* [Day 159](https://github.com/vaskoz/dailycodingproblem-go/issues/331)
diff --git a/day159/problem.go b/day159/problem.go
new file mode 100644
index 0000000..51f09ff
--- /dev/null
+++ b/day159/problem.go
@@ -0,0 +1,25 @@
+package day159
+
+import "errors"
+
+var errNoRecurringRune = errors.New("no recurring rune")
+
+// ErrNoRecurringRune is the error returned when the input has no
+// recurring runes. Every rune is unique.
+func ErrNoRecurringRune() error {
+	return errNoRecurringRune
+}
+
+// FirstRecurringRune returns the first rune that appears twice.
+// If no rune is repeated, then an error is returned.
+// Runs in O(N) time and potentially O(N) space.
+func FirstRecurringRune(s string) (rune, error) {
+	runes := make(map[rune]int)
+	for _, r := range s {
+		runes[r]++
+		if count := runes[r]; count == 2 {
+			return r, nil
+		}
+	}
+	return 0, ErrNoRecurringRune()
+}


Test patch:
diff --git a/day159/problem_test.go b/day159/problem_test.go
new file mode 100644
index 0000000..9664187
--- /dev/null
+++ b/day159/problem_test.go
@@ -0,0 +1,29 @@
+package day159
+
+import "testing"
+
+var testcases = []struct {
+	s           string
+	expected    rune
+	expectedErr error
+}{
+	{"acbbac", 'b', nil},
+	{"abcdef", 0, ErrNoRecurringRune()},
+}
+
+func TestFirstRecurringRune(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if r, e := FirstRecurringRune(tc.s); r != tc.expected || e != tc.expectedErr {
+			t.Errorf("Expected (%v,%v), got (%v,%v)", tc.expected, tc.expectedErr, r, e)
+		}
+	}
+}
+
+func BenchmarkFirstRecurringRune(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			FirstRecurringRune(tc.s)
+		}
+	}
+}