Skip to content

Instantly share code, notes, and snippets.

@DeeNewcum
Last active January 2, 2022 23:14
Show Gist options
  • Save DeeNewcum/c51c3023b2b6ab56c68ef9b4aa457b8a to your computer and use it in GitHub Desktop.
Save DeeNewcum/c51c3023b2b6ab56c68ef9b4aa457b8a to your computer and use it in GitHub Desktop.
Wordle strategy
#!/usr/bin/perl
# Find words that are good to start Wordle with, based on the most frequently-used letters in the
# English language.
#
# You can pass in a word list (for instance, for your second word, you may have narrowed down the
# list significantly, but still want to know what high-frequency options are left).
#
# By default, the program outputs a list like this:
# 45000 onset
# 45000 atone
# 45000 stein
# 45000 stone
# 44000 noise
# 43400 heist
# 43400 haste
# 43400 ethos
# 43400 those
# 43200 inert
# 43200 stern
# 43200 irate
# 43200 store
# 43200 tenor
# 43200 stare
# 43200 inter
# 42400 shone
# 42400 ashen
# 42400 shine
# 42200 arose
# 42200 resin
# 42200 raise
# 42200 saner
# 42200 risen
# 42200 snore
# 42200 siren
# 42200 arise
# 42200 rinse
# 42200 snare
# 41600 other
# 41600 their
# 41600 hater
# 41600 heart
# 41600 earth
# 41400 stead
use strict;
use warnings;
use Data::Dumper;
# copied from https://www3.nd.edu/~busiforc/handouts/cryptography/letterfrequencies.html
my %letter_frequency = qw[
e 12000
t 9000
a 8000
i 8000
n 8000
o 8000
s 8000
h 6400
r 6200
d 4400
l 4000
u 3400
c 3000
m 3000
f 2500
w 2000
y 2000
g 1700
p 1700
b 1600
v 1200
k 800
q 500
j 400
x 400
z 200
];
my $is_dups = ($ARGV[0] && $ARGV[0] eq '--dups');
shift @ARGV if $is_dups;
my %word_list;
if (@ARGV == 0 && -t STDIN) { # if the user started without specifying a dictionary file,
# then pick a sensible default
if (-e 'Wordle_word_list') {
push @ARGV, 'Wordle_word_list';
} else {
die "File 'Wordle_word_list' does not exist. You can extract it from the middle of Wordle's source code\n" .
'from the line that starts -- var Aa=["cigar","rebut","sissy","humph"...' . "\n";
}
}
while (<>) {
chomp;
next unless /^[a-z]{5}$/;
my $word = $_;
my @letters = split '', $word;
my %letters = map {$_ => 1} @letters;
my $num_letters = scalar(keys(%letters));
next if ($num_letters != 5 && !$is_dups);
my $score = 0;
foreach my $letter (@letters) {
if (exists $letter_frequency{$letter}) {
$score += $letter_frequency{$letter};
}
}
$word_list{$word} = $score;
}
my @sorted = sort {$word_list{$a} <=> $word_list{$b}} keys %word_list;
foreach my $word (@sorted) {
printf "%2d %s\n", $word_list{$word}, $word;
}
$is_dups
or print STDERR "\nNOTE that words with repeated letters are WEEDED OUT. This is bad for the final solution. Use --dups to override this.\n";
NOTE: This file contains
d8b 888
Y8P 888
888
.d8888b 88888b. .d88b. 888 888 .d88b. 888d888 .d8888b
88K 888 "88b d88""88b 888 888 d8P Y8b 888P" 88K
"Y8888b. 888 888 888 888 888 888 88888888 888 "Y8888b.
X88 888 d88P Y88..88P 888 888 Y8b. 888 X88
88888P' 88888P" "Y88P" 888 888 "Y8888 888 88888P'
888
888
888
...as in explicit answers to future puzzles. You have been warned.
Good starting letters are:
e, t, a, i, o, n, s, h, and r
Good starting words are (best at the top):
atone
irate
stein
stone
ovate
onset
haste
taken
stare
stain
satin
saint
meant
leant
inter
inert
heist
enact
agent
yeast
waste
untie
unite
twine
those
tenor
sweat
steam
steal
steak
==== legend ====
+ means it's the correct letter in the correct position
~ means it's the correct letter in the wrong position
- means the letter isn't found in any position
==== Jan 2, 2022 ====
-A~T+O-N-E
~S-H+O-R+T
~S-C+O-U+T
+B+O+O+S+T
(though I should have gotten it in 3, since I *knew* the S didn't belong in first place after "SHORT")
$ cat Wordle_word_list | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v '[ane]' | grep '^..o' | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v '[anehr]' | grep '^..o.t'
$ cat Wordle_word_list | grep -v '[eruahcn]' | grep '^..o.t$'
==== Apr 2, 2022 ====
~A-T-O-N-E
-S~H~A+R-D
+H+A-I+R+Y
+H+A+R+R+Y
$ cat Wordle_word_list | grep -v '[tone]' | grep -v '^a' | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v '[tonesd]' | grep -v '^a' | grep '^...r' | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v '[tonesd]' | grep -v '^a' | grep '^...r' | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v '[tonesd]' | grep -v '^a' | grep '^ha.ry' | ./good_Wordle_starting_words.pl --dups
==== Apr 3, 2022 ====
-A+T+O-N+E
-R-I~V-A-L (this required a very different tactic because the options were STORE, STOLE, STOKE, and STOVE... instead of guessing each in turn, I decided to try just one test case)
(so if it was STORE, STOLE, or STOVE, it would have told me directly, and if none matched then it would have been STOKE)
+S+T+O+V+E
$ cat Wordle_word_list | grep -v '[an]' | grep '^.to.e'
$ cat Wordle_word_list | grep r | grep v | grep l
==== Apr 4, 2022 ==== --HARD---
-A-T~O-N-E
-S+O~L-I-D
-M+O-G-U~L
-R+O-C-K+Y
-E~L-B~O~W
+L+O-O-P+Y
correct answer: LOWLY
$ cat Wordle_word_list | grep -v '[atne]' | grep -v '^..o' | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v '[atnesid]' | grep '^.o' | grep l | ./good_Wordle_starting_words.pl --dups
==== Apr 4, 2022 (second try) ==== --HARD---
-A-T~O-N-E
-S+O~L-I-D
+L+O+W+L+Y
$ cat Wordle_word_list | grep -v '[atne]' | grep -v '^..o' | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v '[atnesid]' | grep '^.o' | grep l | ./good_Wordle_starting_words.pl --dups
$ cat Wordle_word_list | grep -v '[atnesid]' | grep '^.o' | grep l | grep -v '^..l'
==== Apr 5, 2022 ====
-A~T+O~N-E
+S+N+O-R+T
+S+N+O+U+T
$ cat Wordle_word_list | grep -v '[ae]' | grep '^..o' | grep t | grep n | ./good_Wordle_starting_words.pl --dups
$ cat Wordle_word_list | grep -v '[aer]' | grep '^sno.t'
==== Apr 6, 2022 ====
-A~T+O-N+E
+T-H+O-S+E
+T+R+O-V+E
+T+R+O+P+E
$ cat Wordle_word_list | grep -v '[an]' | grep '^..o.e' | grep t | ./good_Wordle_starting_words.pl --dups
$ cat Wordle_word_list | grep -v '[anhs]' | grep '^t.o.e' | ./good_Wordle_starting_words.pl --dups
==== Apr 7, 2022 ====
-A-T-O-N~E
-S-H-I+E-D
+F-L-I+E+R
+F+E+W+E+R
$ cat Wordle_word_list | grep -v '[aton]' | grep e | grep -v '^....e' | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v '[atonshdli]' | grep '^f..er'
==== Apr 8, 2022 ====
~A-T-O-N-E
+S+H+A-R-D
+S+H+A+W+L
$ cat Wordle_word_list | grep -v '[tone]' | grep a | grep -v '^a'
$ cat Wordle_word_list | grep -v '[tonerd]' | grep '^sha'
==== Apr 9, 2022 ====
~A~T-O~N-E
+N+A-S~T-Y
+N+A+T+A+L
$ cat Wordle_word_list | grep -v [oe] | grep a | grep t | grep n | grep -v ^a | grep -v ^.t | grep -v ^...n
$ cat Wordle_word_list | grep -v [oe] | grep ^na | grep t | grep -v ^.t
==== Apr 10, 2022 ====
-A-T-O-N+E
-S-H~I+R+E
+F+I+B+R+E
$ cat Wordle_word_list | grep -v [aton] | grep 'e$' | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [atonsh] | grep 're$' | grep i | grep -v ^..i
==== Apr 11, 2022 ====
~A-T~O-N-E
-R~A-D-I~O
+C-H~A~O-S
+C+O+M+M+A
$ cat Wordle_word_list | grep -v [tnerdi] | grep a | grep o | grep -v ^a | grep -v ^..o | ./good_Wordle_starting_words.pl --dups
$ cat Wordle_word_list | grep -v [tnerdi] | grep a | grep o | grep -v ^a | grep -v ^.a | grep -v ^..o | grep -v 'o$' | ./good_Wordle_starting_words.pl --dups
$ cat Wordle_word_list | grep -v [tnerdihs] | grep ^c | grep a | grep o | grep -v ^a | grep -v ^.a | grep -v ^..o | grep -v 'o$'
==== Apr 12, 2022 ====
~A-T~O-N-E
~R~A-D-I~O
-B~R~A-V~O
-S+O-L+A~R
$ cat Wordle_word_list | grep -v [tne] | grep a | grep o | grep -v ^a | grep -v ^..o | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [tnedi] | grep a | grep o | grep -v ^a | grep -v ^..o | grep -v ^a | grep -v ^.a | grep o\$ | ./good_Wordle_starting_words.pl --dups
oops, there's an error right there ^^
it should be vv
$ cat Wordle_word_list | grep -v [tnedi] | grep a | grep o | grep -v ^a | grep -v ^..o | grep -v ^a | grep -v ^.a | grep -v o\$ | ./good_Wordle_starting_words.pl --dups
$ cat Wordle_word_list | grep -v [tnedibv] | grep a | grep o | grep r | grep -v ^[ar] | grep -v ^.[ar] | grep -v ^..[oa] | grep -v o\$
$ cat Wordle_word_list | grep -v [tnedibvsl] | grep ^.o.a | grep r | grep -v ^[ar] | grep -v ^.[ar] | grep -v ^..[oa] | grep -v o\$
==== Apr 13, 2022 ====
~A-T-O-N+E
~R~A-I~S+E
~C-H~E~A-P
+S+C+A+R+E
$ cat Wordle_word_list | grep -v [ton] | grep ^....e | grep a | grep -v ^a | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [toni] | grep ^....e | grep r | grep a | grep s | grep -v ^[ar] | grep -v ^.a | grep -v ^...s | ./good_Wordle_starting_words.pl --dups
# oh shit, it's between SPARE / SHARE / SCARE... better take a different tactic
$ grep p Wordle_word_list | grep c | grep h | ./good_Wordle_starting_words.pl
==== Apr 14, 2022 ====
~A+T-O-N-E
+S+T~R~A-P
+S+T+A~R-T
+S+T+A+I+R
$ cat Wordle_word_list | grep -v [one] | grep ^.t | grep a | grep -v ^a | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [onep] | grep ^st | grep a | grep r | grep -v ^a | grep -v ^..r | grep -v ^...a
# oh shit... START / STARK / STAIR now what?
==== Apr 15, 2022 ====
~A-T-O-N-E
-S-H+A-R-D
~C+L+A-I-M
+B+L+A+C+K
$ cat Wordle_word_list | grep -v [tone] | grep a | grep -v ^a | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [toneshrd] | grep ^..a | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [toneshrdim] | grep ^.la | grep c | grep -v ^c
==== Apr 16, 2022 ====
~A-T-O-N-E
+S-H~A-R+D
+S+Q+U+A+D
$ cat Wordle_word_list | grep -v [tone] | grep a | grep -v ^a | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [tonehr] | grep ^s...d | grep a | grep -v ^..a
==== Apr 17, 2022 ====
~A-T~O-N-E
+R~A-D-I~O
+R+O+Y+A+L
$ cat Wordle_word_list | grep -v [tne] | grep a | grep o | grep -v ^a | grep -v ^..o | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [tnedi] | grep ^r | grep a | grep o | grep -v ^a | grep -v ^.a | grep -v ^..o | grep -v o\$
==== Apr 18, 2022 ====
-A-T-O+N-E
-S-L-I+N-G
-D-R+U+N+K
+C+H+U+N+K
$ cat Wordle_word_list | grep -v [atoe] | grep ^...n | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [atoeslig] | grep ^...n | ./good_Wordle_starting_words.pl --dups
==== Apr 19, 2022 ====
-A-T-O~N+E
-R+I+N-S+E
-T-H-U~M-B
+M+I+N+C+E
$ cat Wordle_word_list | grep -v [ato] | grep ^....e | grep n | grep -v ^...n | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [ators] | grep ^.in.e
# Shoot, we have these words left -- WINCE/MINCE/HINGE/BINGE. How do we choose between the four?
$ cat Wordle_word_list | grep m | grep b | grep h
# Yay, THUMB will help us select between the four.
==== Apr 20, 2022 ====
~A-T-O-N+E
-R~A-I~S+E
+S-H+A-D+E
-P+L-U-C-K
+S+L+A+V+E
$ ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [ton] | grep ^....e | grep a | grep -v ^a | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [tonri] | grep ^....e | grep a | grep s | grep -v ^a | grep -v ^.a | grep -v ^...s | ./good_Wordle_starting_words.pl
$ cat Wordle_word_list | grep -v [tonrihd] | grep ^s.a.e
# there's only four options -- SLAVE/SPACE/SUAVE/SCALE
$ cat Wordle_word_list | grep l | grep p | grep c | grep u
# PLUCK should reveal what the correct word is, because the second letter is either L, P, U, or C, depending on which word is correct
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment