Wordle, by the New York Times, is an ultra-popular game that hundreds of thousands (or more) people play daily. I've personally been playing it for what feels like years now, and it has become a daily ritual.
This weekend, I had the itch to code and created a tool that automatically solves puzzles. I know this has been done many times, but that doesn't mean there isn't something to learn along the way.
Let's take a look at how it turned out!
The first thing I needed to source was a list of all the valid words. A simple Google search leads you to many Wordle dictionary sources. I tried a few different versions but ultimately ended up with one that contained just under 13,000 unique five-letter words. Note that this is not the official acceptable solution list but rather a long list of valid choices.
One of the strategies of the game is to pick common letters. The more common they are, the more potential you have for getting a hit. Let's say I chose the word Vixen; the letters V and X are uncommon, meaning you will have less chance of eliminating possibilities. Let's look at how the different letters stack up by counting the frequency of each letter.
To assist with solving the puzzles, I needed to create a system for storing the different guess options from the game. The rules of the game are simple. Select a five-letter word, and it tells you with three colors:
I came up with a few simple data structures.
Here is what they look like in action.
know_letters = {0: 's', 1: 'e'}
exclude_positions_for_letters = {'a': [2], 'r': [0, 4]}
exclude_letters = {'f', 'i', 'y', 'c', 'o'}
The algorithm to solve was the most fun to create. It took a lot of fussing to get it to where it is today. I wasn't sure if there was a way to create a machine-learning model out of this, but without any historical game outcome data, I went with the old-fashioned way, hard-coded rules. Here are the rules and weights that I came up with
Let's take a look at it in action. Two results from the game below are as follows:
The word WORTS had a larger base score than FORTY because it contains the most common letter in the set, S. However, WORTS ends with an S, which highly penalizes it, and FORTY was ranked 5,130 in the English language, where WORTS didn't appear in that list. The resulting set is a negative score for WORTS, pushing it to the bottom of this list. FORTY is the winner!
Streamlit, if you're unfamiliar with it, is a Python-based rapid UI development framework that is extremely popular with data professionals. They have native support for connecting to data warehouses, built-in Pandas Data Frame support, and the power to build visualizations with your favorite tools like Plotly and Vegas. It makes producing quick applications a snap! They even have a great hosting option for free, which is where I deployed this app.
I didn't spend too much time making this nice; I just wanted to make it functional for now. I chose a simple 5x5 grid of input boxes and radio buttons to enter your picks and select which color box Wordle returned. It worked well as a rapid prototype.
In fact, this entire project took only about 8-10 hours to complete, from idea to hosted application.
As a fan of the game, I don't want to use it on "Today's" puzzle, but there is no reason we can't test it out on the newly released Archives. We'll test this out on March 1st, 2024.
I used the same algorithm above to choose the best starter words based on the criteria above. Upon inspection, these are mostly strong starters. High vowel counts and common letters throughout. There are a few I wouldn't use: anything with repeating letters. However, going wrong with the rest of them would be hard. Here they are.
About, their, there, which, would, other, after, first, think, could, these, where, right, being, years, going, still, those, never, world, great, while, every, state, three.
Let's start with the very first option, ABOUT. This is as good as nearly any I have used.
Next, you can head to the solver and see what is suggested. The first step is to match the Wordle results in the application and submit to see the suggestions. We enter the five letters along the top and then match the colors of the squares to what the game shows you.
other, often, north, month, worth, hotel, costs, throw, noted, notes, voted, tower, topic, motor, posts, votes, forth, metro, voter, toxic, forty, towel, token, intro, opted
Like starter words, the algorithm suggests a set of most probable words. You'll notice the pattern that O and T are included in each word but not in the positions where the yellow squares are marked. We can again select the top choice if we like or any of these options if we feel they fit our mood better. Let's choose OTHER.
We got one yellow letter, R, and eliminated two additional positions on the board for O and T. Let's see what the solver says as we enter the next row.
This brought our possible choices down to 36, and here are the next top guesses:
forty, intro, nitro, vitro, sorts, rosti, torsi, torso, ports, torsk, triol, toric, trigo, torii, dorty, porty, rorty, forts, roton, trios, torts, toros, rotis, tiros, rotls
What stands out here is how the "top 100,000" English word weighting on the algorithm has paid off. You can see common words like FORTY and intro at the start of the list; however, at the end, you have ROTIS, TIROS, and ROTLS. Words that I've personally not heard or used. Let's keep with the flow and use FORTY as our choice.
Tada! 🎉 That's it. We got the solution in three guesses using the application. I tested this on 30 or so games from the archive, and I would say most end up solving in four guesses, some in three, and some in five. That follows the same distribution as my play over the years. I'm pretty happy with that!
You can see it for yourself here: https://wordlebrian.streamlit.app, and, of course, you can check out the entire repository on GitHub here: https://github.com/broepke/wordle.
Wordle is a fun and challenging game. It's also a great coding challenge. Figuring out how you approach this takes a little thought and iteration. We saw everything from finding an appropriate target word list to creating a data model to hold our guesses as we iterated through the puzzle effectively. We then built the scoring algorithm that helps us pick the best word and built a user interface to test this on some games. I'm very much looking forward to iterating on this app. As I mentioned above, it only took about 8-10 hours to get here, and now that I'm satisfied with the results, I think it's worth investing a little more time in it.
What would you change? How would you approach solving this problem? Happy Wordle-ing!