Power Query: Wordle cheat!
Warrior in the garden
Have you heard this saying before?
"It is better to be a warrior in a garden than a gardener in a war".
One who knows how to war and chooses not to do it is peaceful; one who doesn't war because he doesn't know how to is helpless. I wonder if it applies just as well at games and cheating - is it better to know to how to cheat but choose not to, rather than not know how to cheat at all?
I've made a tool to cheat at Wordle and some days I like to pretend I'm the warrior in the garden.
Anyway, all pretense aside, I actually did find this fun. PowerShell and Power Query are my tools of choice at the moment and this is a good way of having fun with them.
Steps
- Get the word list
- Extract the word list into a data file
- Set up spreadsheet
- Write logic
Get the word list
TL;DR: The JavaScript source code is here.
I already knew from a friend that the full word list is in the source code itself. The first step is finding out where the source code lives.
If you just view the source for the main Wordle website.
You need to scan the file, ignore all of the ads and other junk, and find the file main.5d21d0d0.js
.
It turns out that NYT sometimes moves their files and links around. At this time of writing (October 2022), the JavaScript code is here
Extract the word list
Once you get the .js file, save it somewhere.
This PowerShell script will fetch just the words and save them in a file called words.txt (you'll need to change the filename if your target filename isn't wordle-main.js).
using System.Collections;
$root = "" # put your folder location here
(Get-Content "$root\wordle-main.js")[0] -match "(?<=ke=\[).*?(?=\])";
$raw = $matches[0]
$split = $raw -split ','
[ArrayList] $wordlist = @()
$split |
% {
$withoutQuotes = $_ -replace '"', ''
[void] $wordList.Add($withoutQuotes)
}
$wordList > "$root\words.txt"
Code
Here is all of the Power Query code.
include
, exclude
, and lock
are one-column tables. lock
should only have 5 rows, only (this column represents that positions of letters that you definitely know to be correct, i.e. are green).
words
is the output file. It will show you all of the possible words that matches the pattern of included, excluded, and locked letters.
thisFile
let
Source = Excel.CurrentWorkbook()
in
Source
raw
This takes in the file "words.txt" and uses it as a List.
let
Source = Table.FromColumns({Lines.FromBinary(File.Contents("C:\Users\dyota\OneDrive\Projects\Power Query\Wordle cheat\words.txt"), null, null, 1252)}),
Column1 = Source[Column1]
in
Column1
words
let
textContainsList = (reference as list, word as text, optional extent as nullable number) as logical =>
let
selection = (if extent = 0 then List.AllTrue else List.AnyTrue)
in
selection(
List.Transform(
reference,
each Text.Contains(word, _)
)
),
indeces = List.Buffer({0..(List.Count(lock)-1)}),
lock = List.Buffer(lock),
filters = List.Select(
raw,
each
let
word = _
in
textContainsList(include, word, 0)
and List.AllTrue(
List.Select(
List.Transform(
indeces,
(_) =>
let
thisLetter = lock{_}
in
if thisLetter = null or Text.Trim(thisLetter) = ""
then null
else thisLetter = Text.At(word, _)
),
each _ <> null
)
)
and not textContainsList(exclude, word)
)
in
filters
include
let
Source = thisFile,
include = Source{[Name="include"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(include,{{"Include", type text}}),
Include = List.Select(
#"Changed Type"[Include],
each not (_ = null)
)
in
Include
exclude
let
Source = thisFile,
exclude1 = Source{[Name="exclude"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(exclude1,{{"Exclude", type text}}),
Exclude = List.Select(
#"Changed Type"[Exclude],
each not (_ = null)
)
in
Exclude
lock
let
Source = thisFile,
lock1 = Source{[Name="lock"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(lock1,{{"Lock", type text}}),
Lock = #"Changed Type"[Lock]
in
Lock