The Art of Wordle

import requests
words = requests.get('http://www.mieliestronk.com/corncob_caps.txt')
words = words.text.splitlines()
words = [w for w in words if (len(w)==5)&(w[-1]!='S')]
def score_word(guess, actual):
outcome = []
for i, c in enumerate(guess):
if actual[i]==c:
outcome.append(2)
elif c in actual:
outcome.append(1)
else:
outcome.append(0)
return tuple(outcome)
score_word('LATER', 'ABACK')> (0,1,0,0,0)
def get_scores(guess, words):
results = {}
for word in words:
score = score_word(guess, word)
results[score] = results.get(score, 0) + 1
return results
get_scores('LATER', words)> {(0, 2, 0, 0, 1): 40,
(0, 1, 0, 0, 0): 107,
...
(1, 1, 0, 2, 2): 2,
(0, 1, 1, 0, 1): 30,
(1, 1, 2, 0, 1): 1,
(1, 2, 1, 2, 0): 1}
def get_score_counts_for_each_guess(words):
outer_results = {}
for guess in words:
results = list(get_scores(guess, words).values())
outer_results[guess] = sum(results)/len(results)
return outer_results
score_counts = get_score_counts_for_each_guess(words)import pandas as pd
pd.Series(score_counts).sort_values()[:10]
> TRACE 19.559211
SLATE 19.688742
CRATE 19.820000
TILER 19.820000
TRIED 19.953020
RATED 20.363014
PARSE 20.363014
CARED 20.363014
RILED 20.363014
TREAD 20.363014
pd.Series(score_counts).sort_values()[-10:]
> YUMMY 80.351351
WHIZZ 80.351351
QUAFF 80.351351
QUIFF 82.583333
KAYAK 82.583333
FUZZY 82.583333
CIVIC 82.583333
FLUFF 82.583333
JAZZY 90.090909
QUEUE 99.100000
def get_best_guess_for_score(score, new_words):
if len(new_words)==1:
return new_words[0], 1
new_score_counts = get_score_counts_for_each_guess(new_words)
best_guesses = pd.Series(new_score_counts).sort_values()
return best_guesses.index[0], best_guesses.values[0]
def get_outcomes_for_each_score(guess, words):
score_counts = get_scores(guess, words)
results = {}
for k, v in score_counts.items():
new_words = [word for word in words
if score_word(guess, word)==score]
best_guess = get_best_guess_for_score(k, new_words)
results[k] = [v, best_guess[0], best_guess[1]]
return results
guess = 'TRACE'
get_outcomes_for_each_score(guess, words)
>{(0, 0, 0, 2, 1): [10, 'LEECH', 1.1111111111111112],
(0, 0, 0, 0, 1): [238, 'LINED', 4.103448275862069],
...
(0, 1, 0, 0, 1): [160, 'RILED', 4.444444444444445]}
guess = 'TRACE'
score = (0,0,0,0,1)
new_words = [word for word in words
if score_word(guess, word)==score]
new_guess = 'LINED'
get_outcomes_for_each_score(new_guess, new_words)
>{(0, 0, 0, 1, 0): [10, 'BEEFY', 1.25],
(0, 1, 1, 1, 0): [7, 'BEGIN', 1.1666666666666667],
(0, 0, 1, 1, 0): [8, 'EBONY', 1.1428571428571428],
(1, 0, 0, 1, 0): [19, 'WHELP', 1.3571428571428572],
(1, 0, 0, 2, 0): [13, 'BLEEP', 1.4444444444444444],
(0, 2, 0, 2, 2): [14, 'BIDED', 2.8],
(1, 0, 0, 2, 2): [6, 'DOLED', 1.5],
(1, 0, 1, 1, 2): [1, 'BLEND', 1.0],
(0, 0, 0, 2, 2): [43, 'MOPED', 3.5833333333333335],
...}
guess = 'TRACE'
score = (0,0,0,0,1)
new_words = [word for word in words if score_word(guess, word)==score]
new_guess = 'LINED'
score = (0, 0, 0, 2, 2)
new_words = [word for word in new_words if score_word(new_guess, word)==score]
new_guess = 'MOPED'
score = (0,2,0,2,2)
new_words = [word for word in new_words if score_word(new_guess, word)==score]
new_guess = 'BOWED'
score = (0,2,0,2,2)
new_words = [word for word in new_words if score_word(new_guess, word)==score]
new_guess = 'DOSED'
score = (1,2,0,2,2)
new_words = [word for word in new_words if score_word(new_guess, word)==score]
new_guess = 'JOKED'
get_outcomes_for_each_score(new_guess, new_words)
>{(0, 2, 0, 2, 2): [2, 'FOXED', 1.0],
(2, 2, 2, 2, 2): [1, 'JOKED', 1.0],
(2, 2, 0, 2, 2): [1, 'JOYED', 1.0],
(0, 2, 2, 2, 2): [1, 'YOKED', 1.0]}
ANSWER = 'SLUMP'
guess = 'TRACE'
score_word(guess, ANSWER)
#> (0,0,0,0,0)
score = (0,0,0,0,0)
new_words = [word for word in words if score_word(guess, word)==score]
get_best_guess_for_score(score, new_words)
#> ('SLIMY', 3.824324324324324)
new_guess = 'SLIMY'
score_word(new_guess, ANSWER)
#> (2,2,0,2,0)
score = (2,2,0,2,0)
new_words = [word for word in new_words if score_word(new_guess, word)==score]
get_best_guess_for_score(score, new_words)
#> ('SLUMP', 1)
ANSWER = 'BANAL'
guess = 'TRACE'
score_word(guess, ANSWER)
#> (0,0,1,0,0)
score = (0,0,1,0,0)
new_words = [word for word in words if score_word(guess, word)==score]
get_best_guess_for_score(score, new_words)
#> ('SALON', 3.35)
new_guess = 'SALON'
score_word(new_guess, ANSWER)
#> (0, 2, 1, 0, 1)
score = (0, 2, 1, 0, 1)
new_words = [word for word in new_words if score_word(new_guess, word)==score]
get_best_guess_for_score(score, new_words)
#> ('MANLY', 1.0)
new_guess = 'MANLY'
score_word(new_guess, ANSWER)
#> (0, 2, 2, 1, 0)
score = (0, 2, 2, 1, 0)
new_words = [word for word in new_words if score_word(new_guess, word)==score]
get_best_guess_for_score(score, new_words)
# ('BANAL', 1)

--

--

--

Fascinated by what makes societies and markets work, especially in sustainable energy. http://guylipman.com. Views not necessarily reflect those of my employer.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Shared (dynamic) Libraries vs. Static Libraries.

Automated CI/CD pipeline — Docker + Git + Jenkins

Schema Validation with Apollo Engine

Automate Your Slack Interactions

Notifications in Android

Why the Heck Do We Need Recursion?

How to Effectively Inspect Network Activity in Chrome Dev Tools

Coding Training

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Guy Lipman

Guy Lipman

Fascinated by what makes societies and markets work, especially in sustainable energy. http://guylipman.com. Views not necessarily reflect those of my employer.

More from Medium

Wordle (an update)

The Best Wordle

Hunter Bigge Pitches Fast(er)