Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 153
Good morning! Here's your coding interview problem for today.

Find an efficient algorithm to find the smallest distance (measured in number of words) between any two given words in a string.

For example, given words "hello", and "world" and a text content of "dog cat hello cat dog dog hello cat world", return 1 because there's only one word "cat" in between the two words.

Pull request description:
Day153
Resolves #316.

Patch:
diff --git a/README.md b/README.md
index be9bf1c..829912a 100644
--- a/README.md
+++ b/README.md
@@ -162,3 +162,4 @@ problems from
 * [Day 149](https://github.com/vaskoz/dailycodingproblem-go/issues/311)
 * [Day 150](https://github.com/vaskoz/dailycodingproblem-go/issues/312)
 * [Day 151](https://github.com/vaskoz/dailycodingproblem-go/issues/313)
+* [Day 153](https://github.com/vaskoz/dailycodingproblem-go/issues/316)
diff --git a/day153/problem.go b/day153/problem.go
new file mode 100644
index 0000000..52f1a9b
--- /dev/null
+++ b/day153/problem.go
@@ -0,0 +1,45 @@
+package day153
+
+import (
+	"strings"
+)
+
+// SmallestDistanceBetweenWords returns the smallest number of words
+// between the two given words in the text provided.
+// Returns -1 if one or both of the words don't exist in the text.
+func SmallestDistanceBetweenWords(text, one, two string) int {
+	words := strings.Split(text, " ")
+	oneI := getIndex(words, one, 0)
+	twoI := getIndex(words, two, 0)
+	if oneI == -1 || twoI == -1 {
+		return -1
+	}
+	smallest := len(words)
+	for oneI != -1 && twoI != -1 {
+		if dist := abs(oneI - twoI); dist < smallest {
+			smallest = dist
+		}
+		if oneI < twoI {
+			oneI = getIndex(words, one, oneI+1)
+		} else {
+			twoI = getIndex(words, two, twoI+1)
+		}
+	}
+	return smallest - 1
+}
+
+func getIndex(s []string, target string, start int) int {
+	for i := start; i < len(s); i++ {
+		if s[i] == target {
+			return i
+		}
+	}
+	return -1
+}
+
+func abs(a int) int {
+	if a < 0 {
+		return -a
+	}
+	return a
+}


Test patch:
diff --git a/day153/problem_test.go b/day153/problem_test.go
new file mode 100644
index 0000000..389347e
--- /dev/null
+++ b/day153/problem_test.go
@@ -0,0 +1,29 @@
+package day153
+
+import "testing"
+
+var testcases = []struct {
+	text, one, two string
+	expected       int
+}{
+	{"dog cat hello cat dog dog hello cat world", "hello", "world", 1},
+	{"dog cat hello cat dog dog hello cat world", "hello", "cat", 0},
+	{"dog cat hello cat dog dog hello cat world", "wat?", "cat", -1},
+}
+
+func TestSmallestDistanceBetweenWords(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if result := SmallestDistanceBetweenWords(tc.text, tc.one, tc.two); result != tc.expected {
+			t.Errorf("Expected %v got %v", tc.expected, result)
+		}
+	}
+}
+
+func BenchmarkSmallestDistanceBetweenWords(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			SmallestDistanceBetweenWords(tc.text, tc.one, tc.two)
+		}
+	}
+}