I modeled my Wordle solver[1] after Donald Knuth's Mastermind strategy[2].
An optimal guess is found by looking at the list of possible solutions and for each of those possible solutions checking how much each possible guess would narrow down the list of possible solutions.
Once you have a list of all possible guesses and how much each of those possible guesses would narrow down the total number of possible solutions for each possible solution, sort them by the maximum number of total remaining guesses.
The optimal first guesses from my solver are ARISE, RAISE, AESIR, REAIS, or SERAI because each will narrow down the possible word list to at minimum 168 remaining words.
Each guess after that uses the same algorithm with the list of possible guesses filtered with the information you learned in previous guesses.
Thanks for sharing your code. I had seen other people also mention that these 5 guesses (AESIR, ARISE, RAISE, REAIS, SERAI) all narrow down the list to 168 (in the worst case), but I was curious why the code I wrote to play with this was giving different answers.
After reading your code, I see an error in it. In fact, only RAISE is optimal; the others are worse, and leave bigger lists (according to my code):
is too simplistic, and not actually what the real game does. In the game, for each letter position, there are three possible responses:
• Correct (Green), what you call "position"
• Present (Yellow), what you call "included"
• Absent (Grey)
Here are three test cases, that you could try out on the real Wordle in recent days:
• When the solution is "FAVOR" and our guess is "ERROR", Wordle's response is [Grey, Grey, Grey, Green, Green] — note that for the first two Rs in "ERROR", the correct response is Grey (Absent), because the last R has already "used up" the "Green" response.
• When the solution is "FAVOR" and our guess is "ROARS", Wordle's response is [Yellow, Yellow, Yellow, Grey, Grey] — note that only the first R in "ROARS" gets a Yellow response and the second one gets Grey, because there's only one R in the solution.
• (As pointed out by @pedrosorio in a sibling comment) When the solution is "ABBEY" and our guess is "APNEA", Wordle's response is [Green, Grey, Grey, Green, Grey], but your solver thinks that the second "A" would get a "Yellow" response too.
> Rule 2 is somewhat difficult to state precisely and unambiguously, and the manufacturers have in fact not succeeded in doing so on the directions they furnish with the game […]
and gives an exact rule that you may want to study carefully.
In my code, the `response` function I use (it's not the most efficient, but we can just memoize it) is:
def response(h, g):
'''
- The hidden word is h.
- The guess is g.
For each position in the word g, some color:
- 'green' if in the same position
- 'yellow' if present (after subtracting 'green's)
- 'grey' if absent (after subtracting "green"s and "yellow"s)
'''
assert len(h) == len(g)
L = len(h)
green = [i for i in range(L) if h[i] == g[i]]
yellow = []
for i in range(L):
# We want to check whether g[i] is "present" in h
if i in green: continue
for j in range(L):
if j in green: continue
if j in yellow: continue
if h[j] == g[i]:
yellow.append(i)
break
return (green, yellow)
Note the three "continue" statements — they are crucial, to match the behaviour of the real Wordle (or Master Mind) on the three test cases I mentioned above.
The testcases notwithstanding, I found a bug in my code as well. Fixed my `response` function to:
def response(h, g):
assert len(h) == len(g)
L = len(h)
correct = [i for i in range(L) if h[i] == g[i]]
present_h = []
present_g = []
for i in range(L):
# We want to check whether g[i] is "present" in h
if i in correct: continue
for j in range(L):
if j in correct: continue
if j in present_h: continue
if h[j] == g[i]:
present_g.append(i)
present_h.append(j)
break
return (correct, present_g)
and now I too get (AESIR, ARISE, RAISE, REAIS, SERAI) all leaving 168 words. (But the testcases in the above comment still hold, though, make sure your code works for them.)
- solver says there are 10 possible words, one of them is "apnea"
- input "apnea" (match "a", match "e") EDIT: fixed
- solver says there are 0 possible words (it assumes last "a" should appear yellow, but the wordle page has the last "a" as grey because there is only one "a" in the word)
Yesterday was the first time I played, after reading about some monetization thing on HN related to wordle. For me, my first guess was ABIDE, and was able to get AB in the correct location, with e in there as well.
Thinking that e was the second last letter, I was convinced it was ABLED, since it was the only word I could think of with an e in that position, but I didn't realize that I already tried D in the first word.
Using guesses 3-4, I wasn't able to narrow it down further than AB_E_. But I was able to eliminate some characters, leaving only ~ Q, X, Z, Y, J, K, F. In my mind, I couldn't figure out what 5 letter word could be made using just these letters, so I systematically tried swapping all combinations (wordle doesn't accept fake words).
It was only after that that I realized I could repeat letters, so I tried until I figured out duplicating B would give abbey, which seemed probably enough to be a real word.
An optimal guess is found by looking at the list of possible solutions and for each of those possible solutions checking how much each possible guess would narrow down the list of possible solutions.
Once you have a list of all possible guesses and how much each of those possible guesses would narrow down the total number of possible solutions for each possible solution, sort them by the maximum number of total remaining guesses.
The optimal first guesses from my solver are ARISE, RAISE, AESIR, REAIS, or SERAI because each will narrow down the possible word list to at minimum 168 remaining words.
Each guess after that uses the same algorithm with the list of possible guesses filtered with the information you learned in previous guesses.
edit: formatting
1. https://wordlesolver.com source: https://github.com/christiangenco/wordlesolver
2. https://math.stackexchange.com/questions/1192961/knuths-mast...