Skip to content

Instantly share code, notes, and snippets.

@huydx
Created January 28, 2022 14:23
Show Gist options
  • Save huydx/d6012765d0c99330104f1eddb5246fa7 to your computer and use it in GitHub Desktop.
Save huydx/d6012765d0c99330104f1eddb5246fa7 to your computer and use it in GitHub Desktop.
wordle_solver.go
package main
import (
"bufio"
"fmt"
"github.com/umpc/go-sortedmap/desc"
"log"
"math/rand"
"os"
"strconv"
"strings"
sortedmap "github.com/umpc/go-sortedmap"
)
var (
randomCandidates = []string{
"weird",
"adieu",
}
wordFreqs = sortedmap.New(300000, desc.Float64)
greenWord = []string{"", "", "", "", ""}
blacklist = map[string]bool{}
whitelist = map[string]int{}
reader *bufio.Reader
)
func init() {
data, err := os.ReadFile("./unigram_freq.csv")
if err != nil {
panic(err)
}
lines := strings.Split(string(data), "\n")
fmt.Printf("read %d lines\n", len(lines))
for _, line := range lines {
wf := strings.Split(line, ",")
if len(wf) != 2 {
continue
}
freq, err := strconv.ParseFloat(wf[1], 64)
if err != nil {
fmt.Println(wf)
log.Fatal(err)
}
wordFreqs.Insert(wf[0], freq)
}
reader = bufio.NewReader(os.Stdin)
}
func main() {
for {
var lastAnswer string
lastAnswer = readAnswer()
suggest(lastAnswer)
}
}
func suggest(output string) {
if output == "" || output == "\n" { //empty means we don't read anything from input
fmt.Printf("output is nil, suggest random candidate %v\n", randomCandidates[rand.Intn(len(randomCandidates))])
return
}
aa := strings.Split(output, " ")
if len(aa) != 2 {
panic("answer should be in form 'pasted_word feedback' ")
}
answer := strings.TrimSpace(aa[0])
feedback := strings.TrimSpace(aa[1])
ff := []byte(feedback)
if len(ff) != 5 {
log.Fatalf("feedback need be in a format bbygb where b=black y=yellow g=green, found %v len %d", feedback, len(ff))
}
for i, c := range ff {
switch c {
case 'b':
blacklist[string(answer[i])] = true
case 'y':
whitelist[string(answer[i])] = i
case 'g':
greenWord[i] = string(answer[i])
default:
panic("unknown feedback")
}
}
wordFreqIter, err := wordFreqs.IterCh()
if err != nil {
panic(err)
}
suggested := make([]string, 0)
wc := 0
bc := 0
gc := 0
Outer:
for wordFreq := range wordFreqIter.Records() {
word := wordFreq.Key.(string)
if len([]byte(word)) != 5 {
continue
}
for w, i := range whitelist {
idx := strings.Index(word, w)
if idx == -1 || idx == i {
wc += 1
continue Outer
}
}
for i, c := range []byte(word) {
if blacklist[string(c)] {
//fmt.Printf("cont because blacklist %s %v\n", word, blacklist)
bc += 1
continue Outer
}
if greenWord[i] != "" && greenWord[i] != string(c) {
//fmt.Printf("cont because greenword %s %v\n", word, blacklist)
gc += 1
continue Outer
}
}
suggested = append(suggested, word)
}
fmt.Printf("removed caused of whitelist %d, blacklist %d, greenlist %d\n", wc, bc, gc)
fmt.Printf("found %d suggestable words\n", len(suggested))
var suggestCount int
if len(suggested) < 500 {
suggestCount = len(suggested)
} else {
suggestCount = 500
}
for i := 0; i < suggestCount; i++ {
fmt.Println(suggested[i])
}
}
func readAnswer() string {
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
return text
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment