Wordle

Share on:

Wordle is a pleasant game, basically Mastermind with words. You choose an English word (although it can also be played in other languages), and then you're told if your letters are incorrect, correct but in the wrong place, or correct and in the right place. These are shown by the colours grey, yellow, and green.

The genius is that you can share your result: the grid of coloured squares which shows how quickly or slowly you've guessed the word. The shared grid shows only the colours, and not the letters, so is not helpful for anybody else. At the time of writing, Twitter seems awash with Wordle grids.

For example, today my attempt looked like this:

but the grid I could share looked like this:

Since all words are English, each turn considerably lessens the pool of words from which to choose. Since you have no idea what the hidden word might be, you just need to make a guess at each stage. I don't know what pool of words is used to create the daily wordle, whether its mostly simple English, or whether it includes some unusual words.

So the plan was to create a Wordle "helper" program which would provide the list of allowable words at each stage. I used Julia for speed.

to start, read in the word list (I used the all5.txt list from the previous post):

1Julia> wds = readlines(open("all5.txt"))

What we're going to do is to create a simple function which will take a word list, a chosen word, and its Wordle colours, and produce a new word list containing all possible usable words. It will look like:

wordle_guess(word_list, word, colours)

and so for the third word down above, we would use something like:

wordle_guess(current_words,"pylon","nnyyy")

where the characters n, y, g will be used for grey, yellow, and green. The use of n can be taken to stand for "no" or "nil" or "not" or "never". (For an entertaining riff on words beginning with "n" I can't recommend strongly enough the first story in Stanisław Lem's "The Cyberiad" which is quite possibly the most brilliantly inventive book ever - and certainly in the realm of science fiction.)

Then the logic of the program will be very simple; we walk through the current word one letter at a time, and reduce the word-list according to the colour:

  • for grey, find all words which do not use that particular letter
  • for yellow, find all words with that letter but in another position
  • for green, find all words with that letter in that position

No doubt there are cleverer ways of doing this, but here's what I whipped up:

 1function wordle_guess(ws,wd,cs)
 2    wlist = copy(ws)
 3    for i in 1:5
 4	if cs[i] == 'n'
 5	    wlist = [w for w in wlist if isnothing(findfirst(wd[i],w))]
 6	elseif cs[i] == 'y'
 7	    wlist = [w for w in wlist if !isnothing(findfirst(wd[i],w)) && w[i] != wd[i]]
 8	else
 9	    wlist = [w for w in wlist if w[i]==wd[i]]
10	end
11    end
12    return(wlist)
13end

And here's how it was used:

1Julia> wds2 = wordle_guess(wds,"cream","nnnnn")
2Julia> wds3 = wordle_guess(wds2,"shunt","nnnyn")
3Julia> wds4 = wordle_guess(wds3,"pylon","nnyyy")
4
52-element Vector{String}:
6 "knoll"
7 "lingo"

At this stage I simply had to flip a coin, and as you see from above, I chose the wrong one!

The remarkable thing is how much the word lists are reduced at each turn:

1Julia> [length(x) for x in [wds,wds2,wds3,wds4]]
2
34-element Vector{Int64}:
4 6196
5  937
6   37
7    2

An interesting question might be: if you choose a random word at each stage from the current list of usable words, what is the expected number of trials to find the word? And does that value differ between different hidden words?

And also: given a hidden word, and choosing a random word each time, what is the maximum number of trials that could be used?

These will need to wait for another day (or maybe they've been answered already.)