Last active
January 10, 2022 04:38
-
-
Save umran/56984d0adf8d751821ace36539228131 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"fmt" | |
"log" | |
"os" | |
) | |
var alphabet = []string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"} | |
func search(word []string, wordComplement [][]string, expectedChars []string, eliminatedChars []string) []string { | |
blanks := 0 | |
for _, c := range word { | |
if c == "" { | |
blanks++ | |
} | |
} | |
pool := filter(alphabet, func(c string) bool { | |
for _, ec := range eliminatedChars { | |
if c == ec { | |
return false | |
} | |
} | |
return true | |
}) | |
dictionary := genDictionary() | |
words := make([]string, 0) | |
forEachCombo(make([]string, 0, blanks), pool, func(combo []string) { | |
for _, c := range expectedChars { | |
if !contains(combo, c) { | |
return | |
} | |
} | |
candidate := "" | |
j := 0 | |
for i, c := range word { | |
if c != "" { | |
candidate += c | |
continue | |
} | |
if wordComplement[i] != nil && contains(wordComplement[i], combo[j]) { | |
return | |
} | |
candidate += combo[j] | |
j++ | |
} | |
if _, ok := dictionary[candidate]; ok { | |
words = append(words, candidate) | |
} | |
}) | |
return words | |
} | |
func forEachCombo(combo []string, pool []string, f func([]string)) { | |
if len(combo) == cap(combo) { | |
f(combo) | |
return | |
} | |
for _, c := range pool { | |
longerCombo := make([]string, len(combo), cap(combo)) | |
copy(longerCombo, combo) | |
longerCombo = append(longerCombo, c) | |
forEachCombo(longerCombo, pool, f) | |
} | |
} | |
func filter(list []string, f func(string) bool) []string { | |
filtered := make([]string, 0, cap(list)) | |
for _, item := range list { | |
if f(item) { | |
filtered = append(filtered, item) | |
} | |
} | |
return filtered | |
} | |
func contains(list []string, value string) bool { | |
for _, item := range list { | |
if item == value { | |
return true | |
} | |
} | |
return false | |
} | |
func genDictionary() map[string]struct{} { | |
file, err := os.Open("words.txt") | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer file.Close() | |
dictionary := make(map[string]struct{}) | |
scanner := bufio.NewScanner(file) | |
for scanner.Scan() { | |
dictionary[scanner.Text()] = struct{}{} | |
} | |
if err := scanner.Err(); err != nil { | |
log.Fatal(err) | |
} | |
return dictionary | |
} | |
func main() { | |
words := search( | |
[]string{"p", "i", "", "", ""}, | |
[][]string{nil, nil, {"t"}, nil, {"t"}}, | |
[]string{"t"}, | |
[]string{"o"}, | |
) | |
for _, m := range words { | |
fmt.Println(m) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment