package main import ( "bufio" "embed" "fmt" "log" "os" "slices" "sort" "strconv" "strings" "unicode" "golang.org/x/text/runes" "golang.org/x/text/transform" "golang.org/x/text/unicode/norm" ) //go:embed words/*.txt var embeddedWords embed.FS func getWords() ([]string, error) { var words []string counter := 0 file, err := embeddedWords.Open("words/francais.txt") if err != nil { return words, err } scnr := bufio.NewScanner(file) for scnr.Scan() { word := strings.TrimSpace(scnr.Text()) if filterWords(word) { words = append(words, strings.ToLower(word)) } counter++ } file.Close() return words, nil } func filterWords(word string) bool { if len(word) <= 0 { return false } if strings.Contains(word, " ") { return false } if strings.Contains(word, "-") { return false } if strings.Contains(word, "'") { return false } return true } func removeAccents(word string) (string, error) { transformer := transform.Chain( norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC, ) word2, _, err := transform.String( transformer, word, ) return word2, err } func main() { fmt.Println("Wordatro solver by sata") words, err := getWords() if err != nil { log.Fatal(err) } if len(os.Args) < 2 { log.Fatal("Word not supplied as first argument") } inputLetters := strings.ToLower(os.Args[1]) inputJokers := 0 if len(os.Args) > 2 { inputJokers, err = strconv.Atoi(os.Args[2]) if err != nil { panic("Second argument is joker count and should be an interger") } } inputLetters, err = removeAccents(inputLetters) if err != nil { panic(err) } var inputLetters2 []string for _, letter := range inputLetters { if unicode.IsLetter(letter) { inputLetters2 = append(inputLetters2, string(letter)) } } sort.Strings(inputLetters2) for k, word := range words { words[k], err = removeAccents(word) if err != nil { panic(err) } } sort.Slice(words, func(i, j int) bool { return len(words[i]) < len(words[j]) }) for _, word := range words { var letters []string for _, letter := range word { if unicode.IsLetter(letter) { letters = append(letters, string(letter)) } } sort.Strings(letters) if (len(inputLetters) + inputJokers) < len(letters) { continue } var matches int var used []int for _, letter := range letters { for k3, letter2 := range inputLetters2 { if slices.Contains(used, k3) { continue } if strings.EqualFold(letter, letter2) { used = append(used, k3) matches++ break } } } if (matches + inputJokers) == len(word) { fmt.Printf("[%d] %s\n", len(word), word) } } }