Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 108
Good morning! Here's your coding interview problem for today.

This problem was asked by Google.

Given two strings A and B, return whether or not A can be shifted some number of times to get B.

For example, if A is `abcde` and B is `cdeab`, return `true`. If A is `abc` and B is `acb`, return false.

Pull request:
Day108
Resolves #227.

Patch:
diff --git a/README.md b/README.md
index 83e53a8..5be6648 100644
--- a/README.md
+++ b/README.md
@@ -117,3 +117,4 @@ problems from
 * [Day 105](https://github.com/vaskoz/dailycodingproblem-go/issues/221)
 * [Day 106](https://github.com/vaskoz/dailycodingproblem-go/issues/223)
 * [Day 107](https://github.com/vaskoz/dailycodingproblem-go/issues/225)
+* [Day 108](https://github.com/vaskoz/dailycodingproblem-go/issues/227)
diff --git a/day108/problem.go b/day108/problem.go
new file mode 100644
index 0000000..e0a64e4
--- /dev/null
+++ b/day108/problem.go
@@ -0,0 +1,40 @@
+package day108
+
+import (
+	"strings"
+)
+
+// EqualWithShifting answers if A can be converted to B
+// by shifting.
+// Runs in O(N) time.
+func EqualWithShifting(A, B string) bool {
+	if len(A) != len(B) {
+		return false
+	}
+	if len(A) == 0 {
+		return true
+	}
+	startLetter := rune(A[0])
+	startPos := strings.IndexRune(B, startLetter)
+	for {
+		if startPos == -1 {
+			return false
+		}
+		matches := 0
+		for pos := startPos; pos < startPos+len(B); pos++ {
+			if A[pos-startPos] != B[pos%len(B)] {
+				newIndex := strings.IndexRune(B[startPos+1:], startLetter)
+				if newIndex == -1 {
+					startPos = -1
+				} else {
+					startPos += (newIndex + 1)
+				}
+				break
+			}
+			matches++
+		}
+		if matches == len(A) {
+			return true
+		}
+	}
+}


Test patch:
diff --git a/day108/problem_test.go b/day108/problem_test.go
new file mode 100644
index 0000000..db58886
--- /dev/null
+++ b/day108/problem_test.go
@@ -0,0 +1,32 @@
+package day108
+
+import "testing"
+
+var testcases = []struct {
+	A, B     string
+	expected bool
+}{
+	{"abcde", "cdeab", true},
+	{"abc", "acb", false},
+	{"abc", "ac", false},
+	{"", "", true},
+	{"abcab", "cabab", true},
+	{"abcab", "acbab", false},
+}
+
+func TestEqualWithShifting(t *testing.T) {
+	t.Parallel()
+	for tcid, tc := range testcases {
+		if result := EqualWithShifting(tc.A, tc.B); result != tc.expected {
+			t.Errorf("For TCID:%d expected %v got %v", tcid, tc.expected, result)
+		}
+	}
+}
+
+func BenchmarkEqualWithShifting(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			EqualWithShifting(tc.A, tc.B)
+		}
+	}
+}