|
@@ -0,0 +1,68 @@
|
|
|
|
+package kata
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ "fmt"
|
|
|
|
+ "sort"
|
|
|
|
+ "strings"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+func uniqueStrings(sl []string) []string {
|
|
|
|
+ sMap := make(map[string]struct{})
|
|
|
|
+ for _, s := range sl {
|
|
|
|
+ sMap[s] = struct{}{}
|
|
|
|
+ }
|
|
|
|
+ reduced := make([]string, len(sMap))
|
|
|
|
+ i := 0
|
|
|
|
+ for k := range sMap {
|
|
|
|
+ reduced[i] = k
|
|
|
|
+ i++
|
|
|
|
+ }
|
|
|
|
+ return reduced
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func MinQuine(s string) []string {
|
|
|
|
+ // Repetitions in the initial s string don't count.
|
|
|
|
+ words := uniqueStrings(strings.Split(s, " "))
|
|
|
|
+
|
|
|
|
+ // No repetition can happen with a single word.
|
|
|
|
+ if len(words) < 2 {
|
|
|
|
+ return []string{}
|
|
|
|
+ }
|
|
|
|
+ // No N-1 common substring can happen in strings shorter than 2.
|
|
|
|
+ if len(words[0]) < 2 {
|
|
|
|
+ return []string{}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // At least 2 words, each at least 2 letters long.
|
|
|
|
+ maxPos := len(words[0]) - 1 // Included and >= 1.
|
|
|
|
+ counts := make(map[string]int)
|
|
|
|
+ for _, word := range words {
|
|
|
|
+ for i := 0; i <= maxPos; i++ {
|
|
|
|
+ var smaller string
|
|
|
|
+ if i == 0 {
|
|
|
|
+ smaller = word[1:]
|
|
|
|
+ } else if i == maxPos {
|
|
|
|
+ smaller = word[:maxPos]
|
|
|
|
+ } else {
|
|
|
|
+ smaller = word[:i] + word[i+1:]
|
|
|
|
+ }
|
|
|
|
+ _, ok := counts[smaller]
|
|
|
|
+ if ok {
|
|
|
|
+ counts[smaller]++
|
|
|
|
+ } else {
|
|
|
|
+ counts[smaller] = 1
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ result := make([]string, 0, len(counts))
|
|
|
|
+ for word, count := range counts {
|
|
|
|
+ if count > 1 {
|
|
|
|
+ result = append(result, word)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ sort.Strings(result)
|
|
|
|
+ fmt.Println(s, result)
|
|
|
|
+ return result
|
|
|
|
+}
|