Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 181
Good morning! Here's your coding interview problem for today.

This problem was asked by Google.

Given a string, split it into as few strings as possible such that each string is a palindrome.

For example, given the input string `racecarannakayak`, return `["racecar", "anna", "kayak"]`.

Given the input string `abc`, return `["a", "b", "c"]`.

Pull request:
Day181
Resolves #375.

Patch:
diff --git a/README.md b/README.md
index 5120046..b4413fb 100644
--- a/README.md
+++ b/README.md
@@ -191,5 +191,6 @@ problems from
 * [Day 178](https://github.com/vaskoz/dailycodingproblem-go/issues/367)
 * [Day 179](https://github.com/vaskoz/dailycodingproblem-go/issues/371)
 * [Day 180](https://github.com/vaskoz/dailycodingproblem-go/issues/373)
+* [Day 181](https://github.com/vaskoz/dailycodingproblem-go/issues/375)
 * [Day 182](https://github.com/vaskoz/dailycodingproblem-go/issues/376)
 * [Day 184](https://github.com/vaskoz/dailycodingproblem-go/issues/378)
diff --git a/day181/problem.go b/day181/problem.go
new file mode 100644
index 0000000..94db4e1
--- /dev/null
+++ b/day181/problem.go
@@ -0,0 +1,57 @@
+package day181
+
+// MinimumPartitionPalindrome splits a string into as
+// few strings as possible such that each string is a palindrome.
+func MinimumPartitionPalindrome(str string) []string {
+	if len(str) == 0 {
+		return nil
+	}
+	palindrome := make([][]bool, len(str))
+	for i := range palindrome {
+		palindrome[i] = make([]bool, len(str))
+		palindrome[i][i] = true
+	}
+	for l := 2; l <= len(str); l++ {
+		for i := 0; i < len(str)-l+1; i++ {
+			j := i + l - 1
+			if l == 2 {
+				palindrome[i][j] = str[i] == str[j]
+			} else {
+				palindrome[i][j] = (str[i] == str[j]) && palindrome[i+1][j-1]
+			}
+		}
+	}
+	cuts := findCutsBFS(str, palindrome)
+	result := make([]string, 0, len(cuts))
+	prev := 0
+	for _, cut := range cuts {
+		result = append(result, str[prev:cut])
+		prev = cut
+	}
+	return result
+}
+
+func findCutsBFS(s string, pal [][]bool) []int {
+	var q [][]int
+	for i, isPal := range pal[0] {
+		if isPal {
+			q = append(q, []int{i + 1})
+		}
+	}
+	var cuts []int
+	for len(q) != 0 {
+		cuts, q = q[0], q[1:]
+		start := cuts[len(cuts)-1]
+		if len(s) == start {
+			break
+		}
+		for i := start; i < len(pal[start]); i++ {
+			if pal[start][i] {
+				newCuts := append([]int{}, cuts...)
+				newCuts = append(newCuts, i+1)
+				q = append(q, newCuts)
+			}
+		}
+	}
+	return cuts
+}


Test patch:
diff --git a/day181/problem_test.go b/day181/problem_test.go
new file mode 100644
index 0000000..3fba6c2
--- /dev/null
+++ b/day181/problem_test.go
@@ -0,0 +1,34 @@
+package day181
+
+import (
+	"reflect"
+	"testing"
+)
+
+var testcases = []struct {
+	input    string
+	expected []string
+}{
+	{"racecarannakayak", []string{"racecar", "anna", "kayak"}},
+	{"abc", []string{"a", "b", "c"}},
+	{"racecarracecar", []string{"racecarracecar"}},
+	{"a", []string{"a"}},
+	{"", nil},
+}
+
+func TestMinimumPartitionPalindrome(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if result := MinimumPartitionPalindrome(tc.input); !reflect.DeepEqual(result, tc.expected) {
+			t.Errorf("Expected %v, got %v", tc.expected, result)
+		}
+	}
+}
+
+func BenchmarkMinimumPartitionPalindrome(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			MinimumPartitionPalindrome(tc.input)
+		}
+	}
+}