{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
Peter Norvig
Jotto: April 2020
Wordle: Jan 2022
\n", "\n", "# Jotto and Wordle: Word Guessing Games\n", "\n", "[Jotto](https://en.wikipedia.org/wiki/Jotto) is a word game in which a **guesser** tries to guess a secret **target** word, which is chosen from a **word list** of allowable words, in as few guesses as possible. Each guess must be one of the allowable words, and the **reply** to each guess is the number of letters in common between the guess word and the target word, regardless of the positions of the letters. \n", "\n", "Here is an example Jotto game, where I show the guesses, the replies, the number of remaining targets that are **consistent** with all the replies seen so far, and finally the letters that matched (the matches are an aid to you, the reader; they are not known to the guesser). In this game, the guesser gets to the target word, \"wonky\", in 7 guesses. \n", "\n", " Guess 1: \"stoma\" Reply: 1; Consistent targets: 1118 (Matched: \"o\")\n", " Guess 2: \"bairn\" Reply: 1; Consistent targets: 441 (Matched: \"n\")\n", " Guess 3: \"swipe\" Reply: 1; Consistent targets: 197 (Matched: \"w\")\n", " Guess 4: \"lurks\" Reply: 1; Consistent targets: 87 (Matched: \"k\")\n", " Guess 5: \"rowdy\" Reply: 3; Consistent targets: 14 (Matched: \"owy\")\n", " Guess 6: \"roved\" Reply: 1; Consistent targets: 2 (Matched: \"o\")\n", " Guess 7: \"wonky\" Reply: 5; Consistent targets: 1 (Matched: \"wonky\")\n", "\n", "\n", "There are several variants of the game; here are five key questions and my answers:\n", "\n", "- Q: How many letters can each word be?
A: **Only five-letter words are allowed**.\n", "- Q: Does a guess have to be a word in the word list?
A: **Yes.**\n", "- Q: What is the reply for a word that has the same letter twice, like the \"s\" in \"stars\"?
A: **Only words with no repeated letters are allowed in the word list**.\n", "- Q: What if the reply is \"5\", but the guess is not the target?
A: **No two words in the word list are allowed to have the same set of five letters**.
(For example, only one of the anagrams apers/pares/parse/pears/reaps/spare/spear is allowed.)\n", "- Q: Who chooses the target word?
A: **Random chance**. Jotto is sometimes a two-person game where the chooser is an adversary, but not here.\n", "\n", "# Jotto Preliminaries\n", "\n", "First off, some Python basics: Import some modules and define the basic types `Word`, `Score`, and `Reply`:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from typing import List, Tuple, Dict, Union, Counter, Callable, Iterable\n", "from dataclasses import dataclass\n", "from statistics import mean, median, stdev\n", "from collections import defaultdict\n", "from math import log2\n", "import random\n", "import matplotlib.pyplot as plt\n", "\n", "Word = str # A word is a lower-case string of five different letters\n", "Score = int # A score is the number of guesses it took to get the target word\n", "Reply = int # A reply is the number of letters in common between guess and target words" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can make a Jotto word list by:\n", "- Starting with a list of words.\n", "- Discarding the ones that don't have 5 distinct letters.\n", "- Putting the rest into a dict of anagrams keyed by the set of letters.\n", "- Keeping only one word for each anagram." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def allowable(words) -> List[Word]:\n", " \"\"\"Build a list of allowable Jotto words from an iterable of words.\"\"\"\n", " anagrams = {frozenset(w): w for w in words if len(w) == 5 == len(set(w))}\n", " return list(anagrams.values())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The [Stanford GraphBase project](https://www-cs-faculty.stanford.edu/~knuth/sgb.html) has a nice list of five-letter words, [sgb-words.txt](sgb-words.txt):" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(5756, 2845)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "! [ -e sgb-words.txt ] || curl -O https://norvig.com/ngrams/sgb-words.txt\n", " \n", "sgb_words = open('sgb-words.txt').read().split()\n", "wordlist = allowable(sgb_words)\n", "\n", "len(sgb_words), len(wordlist)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see there are 2,845 allowable Jotto words out of the 5,756 words in [sgb-words.txt](sgb-words.txt)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Playing Jotto\n", "\n", "The function `play` will play a game of Jotto and return the score (the number of guesses). The arguments are:\n", "- `guesser`: a `callable` (e.g., a function) that should return the guess to make. The guesser is passed two arguments: \n", " - The reply to the previous guess.\n", " - A list of the words that are consistent with all the guesses made so far. \n", "
(If the guesser wants to keep track of all the guesses made so far, or all the words in the word list, it is welcome to do so.)\n", "- `target`: The target word. If none is given, the target word is chosen at random from the wordlist.\n", "- `wordlist`: The list of allowable words.\n", "- `verbose`: Unless false, print a message for each guess.\n", "\n", "Two corner cases: \n", "1. If the guesser improperly guesses a non-word, the reply is `None`. \n", "2. To prevent a poor guesser from creating an infinite loop, the worst score you can get is the number of words in the wordlist." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "Guesser = Callable[[Reply, List[Word]], Word]\n", "\n", "def play(guesser: Guesser, target=None, wordlist=wordlist, verbose=True) -> Score:\n", " \"\"\"How many guesses does it take for `guesser` to guess the Jotto target word,\n", " which is selected by `chooser` from the words in `wordlist`?\"\"\"\n", " target = target or random.choice(wordlist) # Choose a random target if none was given\n", " targets = wordlist # The targets that are consistent with all replies\n", " reply = None # For the first guess, there is no previous reply\n", " N = len(wordlist) # After N guesses stop the game and record a score of N\n", " for i in range(1, N + 1):\n", " guess = guesser(reply, targets)\n", " reply = reply_for(guess, target) if guess in wordlist else None\n", " targets = [t for t in targets if reply_for(guess, t) == reply]\n", " if verbose: \n", " print(f'Guess {i}: \"{guess}\" Reply: {reply}; Consistent targets: {len(targets)}')\n", " if guess == target or i == N: \n", " return i\n", " \n", "def reply_for(guess, target) -> Reply: \n", " \"The number of letters in common between the target and guess\"\n", " return len(set(target).intersection(guess))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To play a game, we will need a guesser. Here are two simple ones:\n", "- `human_guesser` asks a human for `input`.\n", "- `random_guesser` guesses one of the remaining consistent targets, picked at random. \n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "def human_guesser(reply, targets) -> Word: return input(f'Reply was {reply}. Your guess? ')\n", "\n", "def random_guesser(reply, targets) -> Word: return random.choice(targets)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Sample Jotto Games\n", "\n", "Here is the `random_guesser` in action:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"tempo\" Reply: 0; Consistent targets: 451\n", "Guess 2: \"flick\" Reply: 0; Consistent targets: 67\n", "Guess 3: \"hydra\" Reply: 3; Consistent targets: 21\n", "Guess 4: \"hands\" Reply: 2; Consistent targets: 7\n", "Guess 5: \"bawdy\" Reply: 2; Consistent targets: 4\n", "Guess 6: \"guard\" Reply: 3; Consistent targets: 3\n", "Guess 7: \"grays\" Reply: 5; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "7" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(random_guesser)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"chard\" Reply: 2; Consistent targets: 833\n", "Guess 2: \"frank\" Reply: 1; Consistent targets: 377\n", "Guess 3: \"lased\" Reply: 3; Consistent targets: 91\n", "Guess 4: \"decks\" Reply: 2; Consistent targets: 58\n", "Guess 5: \"haves\" Reply: 2; Consistent targets: 44\n", "Guess 6: \"mated\" Reply: 4; Consistent targets: 8\n", "Guess 7: \"taxed\" Reply: 4; Consistent targets: 3\n", "Guess 8: \"adept\" Reply: 5; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "8" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(random_guesser)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"chefs\" Reply: 0; Consistent targets: 420\n", "Guess 2: \"junta\" Reply: 0; Consistent targets: 42\n", "Guess 3: \"wimpy\" Reply: 1; Consistent targets: 10\n", "Guess 4: \"dorky\" Reply: 3; Consistent targets: 3\n", "Guess 5: \"glory\" Reply: 3; Consistent targets: 1\n", "Guess 6: \"world\" Reply: 5; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "6" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(random_guesser, target='world')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Evaluating Guessers\n", "\n", "To properly evaluate a guesser, a sample of 3 games is not enough. We will have to play at least a few hundred games to get a statistically reliable result. The function `evaluate` takes a list of scores from playing multiple games and reports the following statistics:\n", "- The median, mean, standard deviation, and worst case number of guesses, and total number of scores.\n", "- The cumulative percentages guessed correctly (e.g., `\"≤5:11%\"` means 11% of the targets took 5 or fewer guesses).\n", "- A histogram of scores." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "def report(scores: Iterable[Score]) -> None:\n", " \"\"\"Report statistics and a histogram for these scores.\"\"\"\n", " scores = list(scores)\n", " ctr = Counter(scores)\n", " bins = range(min(ctr), max(ctr) + 2)\n", " scale = 100 / len(scores)\n", " weights = [scale * ctr[score] for score in ctr]\n", " plt.hist(list(ctr), weights=weights, align='left', rwidth=0.9, bins=bins)\n", " plt.xticks(bins[:-1])\n", " plt.xlabel('Number of guesses'); plt.ylabel('% of scores')\n", " print(f'median: {median(scores):.0f} guesses, mean: {mean(scores):.2f}',\n", " f'± {stdev(scores):.2f}, worst: {max(scores)}, scores: {len(scores):,d}')\n", " def pct(g): \n", " \"\"\"What percent of games requires no mare than g guesses?\"\"\"\n", " percent = scale * sum(ctr[i] for i in range(1, g + 1))\n", " return round(percent, (1 if 99 < percent < 100 else None))\n", " print('cumulative:', ', '.join(f'≤{g}:{pct(g)}%' for g in range(3, 11)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I'll evaluate `random_guesser` on every word in the word list:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 7 guesses, mean: 7.35 ± 1.68, worst: 16, scores: 2,845\n", "cumulative: ≤3:1%, ≤4:3%, ≤5:11%, ≤6:31%, ≤7:57%, ≤8:79%, ≤9:91%, ≤10:96%\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "report(play(random_guesser, target, verbose=False) for target in wordlist)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The random consistent guesser strategy might have seemed hopelessly naive, but it is actually a pretty decent strategy. The median is 7 guesses and about 80% of the time it will take 8 guesses or fewer. Can a better strategy improve on that?\n", "\n", "# Guessers that Partition Target Words\n", "\n", "A key idea in guessing is to reduce the number of consistent targets. When there is a single consistent target left, the game is over. We can think of a guess as **partitioning** the consistent targets into different **branches** of a tree, each branch corresponding to a different reply:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "def partition(guess, targets) -> Dict[Reply, List[str]]:\n", " \"\"\"A guess partition targets by the possible replies to guess: {reply: [word, ...]}.\"\"\"\n", " branches = defaultdict(list)\n", " for target in targets:\n", " branches[reply_for(guess, target)].append(target)\n", " return branches" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here are two different partitions of just the first 22 words in `wordlist`; one by the guess word `'girth'` and one by `'ethos'`:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "defaultdict(list,\n", " {4: ['their', 'might'],\n", " 1: ['about', 'sword', 'resay', 'nuder', 'house'],\n", " 0: ['would', 'cloud', 'place', 'sound', 'fondu'],\n", " 3: ['throe', 'write', 'rifts', 'think', 'grate'],\n", " 2: ['water', 'after', 'ethos', 'while'],\n", " 5: ['girth']})" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "words22 = wordlist[:22]\n", "\n", "partition('girth', words22)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "defaultdict(list,\n", " {3: ['their'],\n", " 2: ['about',\n", " 'sword',\n", " 'write',\n", " 'rifts',\n", " 'water',\n", " 'after',\n", " 'girth',\n", " 'think',\n", " 'resay',\n", " 'sound',\n", " 'grate',\n", " 'might',\n", " 'while'],\n", " 1: ['would', 'cloud', 'place', 'fondu', 'nuder'],\n", " 4: ['throe', 'house'],\n", " 5: ['ethos']})" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "partition('ethos', words22)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see that after guesssing `'girth'`, no matter what the reply is, we will be left with no more than 5 targets. However, if we guessed `'ethos'` then a majority of the time the reply would be 2, and there would be 13 possible targets remaining. That suggests that `'girth'` is a better guess and that a good strategy is: **guess a word that partitions the possible targets into branches with small numbers of words.**\n", "\n", "Since we only need to know the *size* of each branch, not the list of words therein, we can use `partition_counts`:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "def partition_counts(guess, targets) -> List[int]: \n", " \"The sizes of the branches of a partition of targets by guess.\"\n", " counter = Counter(reply_for(guess, target) for target in targets)\n", " return list(counter.values())" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 5, 5, 5, 4, 1]" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "partition_counts('girth', words22)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 13, 5, 2, 1]" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "partition_counts('ethos', words22)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Comparing Partitions\n", "\n", "What exactly is the best metric for deciding which partition is best? Ideally, we want the partition that minimizes the average number of additional guesses it will take to finish the game, but since we don't know that, we can instead minimize one of the following proxy metrics to rank partitions, based on the sizes of the branches:\n", "\n", "- **Maximum**: choose the partition that minimizes the size of the largest branch.\n", "\n", "\n", "- **Expectation**: In probability theory the expectation or **expected value** is the weighted average of a random variable. Here it means the sum, over all branches, of the size of the branch multiplied by the probability of ending up in the branch; that's what we want to minimize. We are assuming that every target is equally likely, so the probability of a branch is proportional to the number of targets in it.\n", "\n", "- **Negative Entropy**: Entropy is an information-theoretic measure that is similar to expectation, except that it weights each branch size by its base 2 logarithm (whereas expectation weights it by its actual size). We want to maximkize entropy, or minimize *negative* entropy.\n", "\n", "The maximum is just the builtin `max` function; here are the other two metrics:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "def expectation(counts: List[int]) -> float:\n", " \"The expected value of the counts.\"\n", " N = sum(counts)\n", " def P(x): return x / N\n", " return sum(P(x) * x for x in counts)\n", "\n", "def neg_entropy(counts: List[int]) -> float: \n", " \"\"\"The negation of the entropy of the counts.\"\"\"\n", " N = sum(counts)\n", " def P(x): return x / N\n", " return sum(P(x) * log2(P(x)) for x in counts)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Best and Worst First Guesses\n", "\n", "Here's a function to print a table of the best and worst words to partition the word list–that is, the best and worst first guesses in a game–according to each of the three metrics:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "def partition_scores(n, metrics=(max, expectation, neg_entropy), wordlist=wordlist): \n", " \"\"\"The top and bottom `n` words to guess, according to each partition metric.\"\"\"\n", " rankings = {metric: sorted((metric(partition_counts(g, wordlist)), g) for g in wordlist)\n", " for metric in metrics}\n", " def fmt(score): \n", " return f'{round(score):5d}' if score >= 100 or isinstance(score, int) else f'{score:5.2f}'\n", " bar = ' + '.join(['-' * 11] * len(metrics))\n", " print(' | '.join(f'{metric.__name__:11}' for metric in metrics))\n", " print(bar)\n", " for i in [*range(n), *range(-n, 0)]:\n", " fmts = [f'{word} {fmt(score)}' for metric in metrics \n", " for score, word in [rankings[metric][i]]]\n", " if i == -n: print(bar)\n", " print(' | '.join(fmts))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First I'll try it with the 22-word list:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "max | expectation | neg_entropy\n", "----------- + ----------- + -----------\n", "girth 5 | girth 4.36 | girth -2.42\n", "after 6 | grate 4.45 | grate -2.41\n", "grate 6 | after 4.55 | after -2.39\n", "write 6 | write 4.64 | write -2.38\n", "might 8 | their 4.91 | their -2.36\n", "place 8 | water 4.91 | water -2.36\n", "rifts 8 | would 5.27 | would -2.26\n", "their 8 | might 5.55 | might -2.21\n", "think 8 | think 5.64 | fondu -2.20\n", "throe 8 | rifts 5.73 | sound -2.18\n", "water 8 | fondu 5.73 | cloud -2.11\n", "----------- + ----------- + -----------\n", "would 8 | sound 5.82 | think -2.10\n", "fondu 9 | throe 5.91 | rifts -2.08\n", "house 9 | resay 6.00 | resay -2.06\n", "resay 9 | cloud 6.36 | throe -2.04\n", "sound 9 | while 6.55 | while -1.96\n", "while 9 | sword 6.82 | sword -1.94\n", "about 10 | place 6.82 | house -1.77\n", "cloud 10 | house 7.64 | place -1.77\n", "sword 10 | nuder 8.00 | nuder -1.75\n", "nuder 11 | ethos 9.09 | ethos -1.65\n", "ethos 13 | about 9.18 | about -1.44\n" ] } ], "source": [ "partition_scores(11, wordlist=words22)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The three metrics are similar; \"girth\" is good and \"ethos\" is bad on all three metrics.\n", "\n", "Now with the full wordlist (this will take about 12 seconds to run):" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "max | expectation | neg_entropy\n", "----------- + ----------- + -----------\n", "wader 1012 | raved 813 | debar -1.95\n", "cadre 1026 | debar 818 | alder -1.95\n", "armed 1028 | roved 827 | raved -1.94\n", "diner 1029 | orbed 827 | dater -1.94\n", "coder 1030 | wader 827 | cadre -1.94\n", "padre 1035 | armed 827 | armed -1.94\n", "raved 1038 | fader 828 | garde -1.94\n", "rayed 1038 | dater 829 | wader -1.94\n", "delta 1039 | alder 830 | lased -1.93\n", "drone 1041 | cadre 830 | padre -1.93\n", "eland 1043 | garde 830 | fader -1.93\n", "garde 1043 | padre 832 | dears -1.93\n", "heard 1044 | deign 832 | drone -1.93\n", "tired 1044 | gored 834 | diner -1.93\n", "debar 1046 | laved 834 | rayed -1.93\n", "fader 1048 | rayed 837 | tired -1.93\n", "----------- + ----------- + -----------\n", "vacuo 1465 | jumpy 1067 | gauzy -1.61\n", "miaow 1474 | gauze 1067 | quake -1.61\n", "pique 1480 | juicy 1070 | humpf -1.61\n", "okapi 1485 | quail 1073 | coqui -1.61\n", "imago 1491 | imago 1081 | whump -1.60\n", "haiku 1493 | miaow 1084 | diazo -1.60\n", "audio 1494 | quake 1086 | zombi -1.59\n", "gauze 1497 | coqui 1091 | okapi -1.59\n", "quake 1500 | quota 1098 | azoic -1.59\n", "quail 1507 | haiku 1099 | haiku -1.58\n", "diazo 1513 | diazo 1100 | mujik -1.58\n", "coqui 1535 | okapi 1105 | jumpy -1.57\n", "quota 1548 | azoic 1120 | juicy -1.57\n", "azoic 1555 | axiom 1157 | axiom -1.56\n", "axiom 1615 | audio 1184 | audio -1.49\n", "ouija 1848 | ouija 1413 | ouija -1.29\n" ] } ], "source": [ "partition_scores(16)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The top guesses favor the letters \"a\", \"d\", \"e\", and \"r\". \n", "\n", "The word \"ouija\" is a uniquely terrible guess; mostly what it does is confirm that a majority of the words have exactly one of the vowels \"aiou\"." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Guess Trees: Caching Best Guesses\n", "\n", "Going through every word in the wordlist to decide which one makes the best partition takes some time. I would prefer to do that computation just once and cache it, rather than have to repeat the computation in every new game. I will cache the best guesses in a structure called a **guess tree**: a tree that has branches for every possible path the game might take, with the best guess for each situation already computed. A guess tree is either:\n", "- An **interior node**, which has a guess and a dict of branches, `Node(guess, {reply: subtree, ...})`, where each subtree covers all the target words that are consistent with the corresponding reply.\n", "- A **leaf word**, indicating the sole remaining consistent target word. Every word in the word list should appear as a leaf in exactly one place in a guess tree." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "@dataclass \n", "class Node:\n", " \"\"\"A node in a guess tree. It stores the best guess, and a branch for every possible reply.\"\"\"\n", " guess: Word\n", " branches: Dict[Reply, 'Tree']\n", "\n", "Tree = Union[Node, Word] # A Tree is either an interior Node or a leaf Word" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The function `minimizing_tree(metric, targets)` builds a guess tree that covers all the targets and that, at every node, guesses a word that minimizes the `metric` applied to the `partition_counts` of the guess." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "def minimizing_tree(metric, targets) -> Tree:\n", " \"\"\"Make a tree that picks guesses that minimize metric(partition_counts(guess, targets)).\"\"\"\n", " if len(targets) == 1:\n", " return targets[0]\n", " else:\n", " guess = min(targets, key=lambda guess: metric(partition_counts(guess, targets))) \n", " branches = partition(guess, targets)\n", " return Node(guess, {reply: minimizing_tree(metric, branches[reply]) \n", " for reply in branches})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is a tree that covers a small list of five words:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "words5 = ['purge', 'bites', 'sulky', 'patsy', 'hayed']\n", "tree5 = minimizing_tree(max, words5)\n", "\n", "assert tree5 == Node(guess='bites', \n", " branches={1: Node(guess='purge', \n", " branches={1: Node(guess='sulky', \n", " branches={1: 'hayed', \n", " 5: 'sulky'}), \n", " 5: 'purge'}), \n", " 2: 'patsy', \n", " 5: 'bites'})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The tree says that the first guess is `'bites'`, and if the reply is `1` there is a complex subtree to consider (starting with the guess `'purge'`), but if the reply is `2` the target can only be `'patsy'` and of course if the reply is `5` then `'bites'` was the target and the game is over." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Turning a Tree into a Guesser\n", "\n", "A tree is not a guesser, but we can easily make a guesser from a tree. A `TreeGuesser` works as follows:\n", "- When *initialized*, it takes a tree as input, and stores the tree under the `.root` attribute.\n", "- When *called* for the first turn in a game (when the reply is `None`), it resets `.tree` to `.root`.\n", "- When *called* on subsequent turns within a game, it updates `.tree` to be the branch corresponding to the reply.\n", "- It then returns the guess for that branch: either the `.guess` attribute or the leaf word. " ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "class TreeGuesser:\n", " \"\"\"Given a guess tree, use it to create a callable Guesser that can play Jotto.\"\"\"\n", " def __init__(self, tree): self.root = tree\n", " \n", " def __call__(self, reply, targets) -> str:\n", " \"\"\"If reply is None, start a new game; otherwise follow the branch for the reply.\n", " Then return the current leaf or interior node guess.\"\"\"\n", " self.tree = self.root if reply is None else self.tree.branches[reply]\n", " return self.tree.guess if isinstance(self.tree, Node) else self.tree" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we build a tree that minimizes the maximum branch size (over the full wordlist) and make a guesser out of it:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "tree = minimizing_tree(max, wordlist)\n", "guesser = TreeGuesser(tree)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Sample Jotto Games with the Minimizing Guesser\n" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"wader\" Reply: 2; Consistent targets: 1004\n", "Guess 2: \"lawns\" Reply: 2; Consistent targets: 354\n", "Guess 3: \"sutra\" Reply: 2; Consistent targets: 125\n", "Guess 4: \"heaps\" Reply: 1; Consistent targets: 40\n", "Guess 5: \"carny\" Reply: 3; Consistent targets: 12\n", "Guess 6: \"bairn\" Reply: 5; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "6" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(guesser)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"wader\" Reply: 0; Consistent targets: 466\n", "Guess 2: \"tings\" Reply: 2; Consistent targets: 160\n", "Guess 3: \"gunky\" Reply: 2; Consistent targets: 44\n", "Guess 4: \"plink\" Reply: 2; Consistent targets: 13\n", "Guess 5: \"bonks\" Reply: 5; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "5" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(guesser)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"wader\" Reply: 2; Consistent targets: 1004\n", "Guess 2: \"lawns\" Reply: 2; Consistent targets: 354\n", "Guess 3: \"sutra\" Reply: 2; Consistent targets: 125\n", "Guess 4: \"heaps\" Reply: 2; Consistent targets: 43\n", "Guess 5: \"eclat\" Reply: 2; Consistent targets: 13\n", "Guess 6: \"hilar\" Reply: 0; Consistent targets: 3\n", "Guess 7: \"wefts\" Reply: 4; Consistent targets: 1\n", "Guess 8: \"owest\" Reply: 5; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "8" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(guesser)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Evaluating Guess Trees\n", "\n", "We could evaluate a Guess Tree with repeated calls to `play`, but there is a faster way: walk the tree and keep track of how many guesses it takes to get to each leaf word. The function `tree_scores` does this. For each subtree branch in the tree there are three cases:\n", "- If the subtree is a leaf word that is the same as the node's guess, we're done; it took one guess.\n", "- If the subtree is a leaf word that is not the guess, it took two guesses: one for the incorrect guess and one for the leaf word.\n", "- If the subtree is a Node, add one to each of the scores from the subtree and yield those scores." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "def tree_scores(node: Node) -> Iterable[Score]:\n", " \"\"\"All the scores for playing all the target words in the tree under `node`.\"\"\"\n", " for subtree in node.branches.values():\n", " if isinstance(subtree, Word):\n", " yield 1 if subtree == node.guess else 2\n", " else:\n", " yield from (score + 1 for score in tree_scores(subtree))\n", " \n", "assert sorted(tree_scores(tree5)) == [1, 2, 2, 3, 4]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Making Inconsistent Guesses\n", "\n", "So far, we have always guessed one of the consistent targets. That seems reasonable; why waste a guess on a word that could not possibly be the target? But it turns out that in some cases it ***is*** a good strategy to guess such a word.\n", "\n", "I will redefine `minimizing_tree` so that it is passed both the list of remaining consistent target words and the complete word list. It also takes a flag, `inconsistent`. When this flag is true, any word in the wordlist can be considered as a guess; when false, only consistent targets are considered, as before. (Note: when there are 3 or fewer target words left there is no use considering inconsistent guesses, since they cannot improve the average score over a consistent guess.)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "def minimizing_tree(metric, targets, wordlist=wordlist, inconsistent=False) -> Tree:\n", " \"\"\"Make a tree that picks guesses that minimize metric(partition_counts(guess, targets)).\"\"\"\n", " if len(targets) == 1:\n", " return targets[0]\n", " else:\n", " guesses = wordlist if (inconsistent and len(targets) > 3) else targets\n", " guess = min(guesses, key=lambda guess: metric(partition_counts(guess, targets))) \n", " branches = partition(guess, targets)\n", " return Node(guess, {reply: minimizing_tree(metric, branches[reply], wordlist, inconsistent) \n", " for reply in sorted(branches)})" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we see that by default, the redefined `minimizing_tree` behaves just as it did before:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "assert minimizing_tree(max, words5) == tree5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But with `inconsistent=True`, we get a better tree:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Node(guess='dashy', branches={0: 'purge', 1: 'bites', 2: 'sulky', 3: 'patsy', 4: 'hayed'})" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tree5i = minimizing_tree(max, words5, inconsistent=True)\n", "tree5i" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first guess by `tree5i` is an inconsistent word, `'dashy'`. There is no chance that this is the target, but it sets us up so that after we get the reply we will always be able to guess correctly on the second guess. So the minimum, mean, median, and maximum number of guesses is 2. \n", "\n", "In contrast, `tree5` makes only consistent guesses and has a mean of 2.4 guesses and a maximum of 4:" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 2 guesses, mean: 2.40 ± 1.14, worst: 4, scores: 5\n", "cumulative: ≤3:80%, ≤4:100%, ≤5:100%, ≤6:100%, ≤7:100%, ≤8:100%, ≤9:100%, ≤10:100%\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "report(play(TreeGuesser(tree5), w, words5, False) for w in words5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As a more extreme example, consider the following list of 11 words, which differ only in the first letter. A consistent guesser could do no better than to just go through the list one at a time (in any order), and would be equally likely to guess right on any of guesses 1 through 11, for an average of 6:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 6 guesses, mean: 6.00 ± 3.32, worst: 11, scores: 11\n", "cumulative: ≤3:27%, ≤4:36%, ≤5:45%, ≤6:55%, ≤7:64%, ≤8:73%, ≤9:82%, ≤10:91%\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "ails = 'bails fails hails jails mails nails pails rails tails vails wails'.split()\n", "\n", "report(tree_scores(minimizing_tree(max, ails)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But an inconsistent guesser can make a first guess that partitions the remaining words, eventually leading to an average of only 4 guesses: " ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 4 guesses, mean: 4.00 ± 0.77, worst: 5, scores: 11\n", "cumulative: ≤3:27%, ≤4:73%, ≤5:100%, ≤6:100%, ≤7:100%, ≤8:100%, ≤9:100%, ≤10:100%\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "report(tree_scores(minimizing_tree(max, ails, inconsistent=True)))" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "assert (minimizing_tree(max, ails, inconsistent=True) == \n", " Node(guess='front', \n", " branches={0: Node(guess='thumb', \n", " branches={0: Node(guess='power', \n", " branches={0: Node(guess='jails', \n", " branches={4: 'vails', \n", " 5: 'jails'}), \n", " 1: Node(guess='pails', \n", " branches={4: 'wails', \n", " 5: 'pails'})}), \n", " 1: Node(guess='bails', \n", " branches={4: Node(guess='hails', \n", " branches={4: 'mails', \n", " 5: 'hails'}), \n", " 5: 'bails'})}), \n", " 1: Node(guess='their', \n", " branches={1: Node(guess='fails', \n", " branches={4: 'nails', \n", " 5: 'fails'}), \n", " 2: Node(guess='rails', \n", " branches={4: 'tails', \n", " 5: 'rails'})})}))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Evaluating Consistent Guessers\n", "\n", "Here are the evaluations of trees made from minimizing the three metrics, with only consistent guesses allowed:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 7 guesses, mean: 7.15 ± 1.81, worst: 18, scores: 2,845\n", "cumulative: ≤3:1%, ≤4:4%, ≤5:13%, ≤6:35%, ≤7:67%, ≤8:86%, ≤9:92%, ≤10:95%\n", "CPU times: user 6.71 s, sys: 17.1 ms, total: 6.73 s\n", "Wall time: 6.76 s\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%time report(tree_scores(minimizing_tree(max, wordlist, inconsistent=False)))" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 7 guesses, mean: 7.14 ± 1.82, worst: 17, scores: 2,845\n", "cumulative: ≤3:1%, ≤4:4%, ≤5:13%, ≤6:36%, ≤7:68%, ≤8:85%, ≤9:91%, ≤10:95%\n", "CPU times: user 6.75 s, sys: 25.6 ms, total: 6.78 s\n", "Wall time: 6.89 s\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%time report(tree_scores(minimizing_tree(expectation, wordlist, inconsistent=False)))" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 7 guesses, mean: 7.09 ± 1.78, worst: 19, scores: 2,845\n", "cumulative: ≤3:1%, ≤4:4%, ≤5:13%, ≤6:36%, ≤7:69%, ≤8:86%, ≤9:92%, ≤10:96%\n", "CPU times: user 6.68 s, sys: 18.8 ms, total: 6.7 s\n", "Wall time: 6.73 s\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%time report(tree_scores(minimizing_tree(neg_entropy, wordlist, inconsistent=False)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We might as well also get an evaluation of the random guesser on every target in the wordlist:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 7 guesses, mean: 7.34 ± 1.73, worst: 18, scores: 2,845\n", "cumulative: ≤3:1%, ≤4:4%, ≤5:12%, ≤6:29%, ≤7:57%, ≤8:80%, ≤9:91%, ≤10:96%\n", "CPU times: user 6.9 s, sys: 26.7 ms, total: 6.92 s\n", "Wall time: 6.95 s\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%time report(play(random_guesser, target, verbose=False) for target in wordlist)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Evaluating Inconsistent Guessers\n", "\n", "Now we'll build and evaluate trees with inconsistent guesses allowed. This will take longer; about 30 seconds per tree." ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 7 guesses, mean: 7.05 ± 0.98, worst: 10, scores: 2,845\n", "cumulative: ≤3:0%, ≤4:1%, ≤5:6%, ≤6:24%, ≤7:69%, ≤8:95%, ≤9:99.9%, ≤10:100%\n", "CPU times: user 30.5 s, sys: 116 ms, total: 30.7 s\n", "Wall time: 30.8 s\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%time report(tree_scores(minimizing_tree(max, wordlist, inconsistent=True)))" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 7 guesses, mean: 6.84 ± 0.95, worst: 10, scores: 2,845\n", "cumulative: ≤3:0%, ≤4:1%, ≤5:7%, ≤6:32%, ≤7:78%, ≤8:97%, ≤9:100.0%, ≤10:100%\n", "CPU times: user 29.7 s, sys: 39.8 ms, total: 29.7 s\n", "Wall time: 29.7 s\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%time report(tree_scores(minimizing_tree(expectation, wordlist, inconsistent=True)))" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 7 guesses, mean: 6.82 ± 1.00, worst: 10, scores: 2,845\n", "cumulative: ≤3:0%, ≤4:1%, ≤5:8%, ≤6:35%, ≤7:78%, ≤8:97%, ≤9:99.6%, ≤10:100%\n", "CPU times: user 30 s, sys: 15.8 ms, total: 30 s\n", "Wall time: 30 s\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%time report(tree_scores(minimizing_tree(neg_entropy, wordlist, inconsistent=True)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Jotto Evaluation Summary\n", "\n", "Here's a table of evaluation results for the mean and maximum number of guesses for the various approaches:\n", "\n", "|

Algorithm|Consistent
Only
Mean (Max)|Inconsistent
Allowed
Mean (Max)|\n", "|--|--|--|\n", "|random guesser|7.34 (18)| |\n", "|minimize max|7.15 (18)|7.05 (10)|\n", "|minimize expectation|7.14 (17)|6.84 (10)|\n", "|minimize neg_entropy|7.09 (19)|6.82 (10)|\n", "\n", "(There can be slight variation from run to run.)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Wordle\n", "\n", "[Wordle](https://www.powerlanguage.co.uk/wordle/) is a [suddenly-popular](https://www.nytimes.com/2022/01/03/technology/wordle-word-game-creator.html) variant of Jotto (with some Mastermind thrown in) with these differences:\n", "- Words with repeated letters are allowed, as are anagrams.\n", "- The reply to a guess consists of 5 pieces ([trits](https://en.wiktionary.org/wiki/trit#English)) of information, one for each position in the guess:\n", " - *Green* if the guess letter is in the correct spot.\n", " - *Yellow* if the guess letter is in the word but in the wrong spot.\n", " - *Miss* if the letter is not in the word in any spot.\n", " \n", "Since repeated letters and anagrams are allowed, I can use all of `sgb_words` as my list of allowable Wordle words.\n", "\n", "There seems to be an ambiguity in the rules. Assume the guess is *etude* and the target is *poems*. I think the correct reply should be that one letter *e* is *yellow* and the other is a *miss*, although a strict reading of the rules would say they both should be *yellow*, because both instances of *e* are \"in the word but in the wrong spot.\" I decided that in cases like this I would report the first one as yellow and the second as a miss." ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": [ "Green, Yellow, Miss = 'GY.' # A reply is 5 characters, each one of 'GY.'\n", "\n", "def wordle_reply_for(guess, target) -> str: \n", " \"The five-character reply for this guess on this target in Wordle.\"\n", " # We'll start by having each reply be either Green or Miss ...\n", " reply = [Green if guess[i] == target[i] else Miss for i in range(5)]\n", " # ... then we'll put in the replies that should be yellow\n", " counts = Counter(target[i] for i in range(5) if guess[i] != target[i])\n", " for i in range(5):\n", " if reply[i] == Miss and counts[guess[i]] > 0:\n", " counts[guess[i]] -= 1\n", " reply[i] = Yellow\n", " return ''.join(reply)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The right thing to do now would be to refactor the code to allow for the injection of a different `reply_for` function. However, I'm not going to do that; instead I'm going to \"cheat\" and just redefine `reply_for` to be `wordle_reply_for`. So if you want to go back in this notebook and re-run some Jotto cells, you'll have to re-run the \"`def reply_for`\" cell first." ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [], "source": [ "reply_for = wordle_reply_for" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that in Jotto, `reply_for` was symmetric; `reply_for(g, t) == reply_for(t, g)`. But that is not true for Wordle. (I had a bug somewhere in my code that showed up when playing Wordle but not Jotto, and I thought it might be because I had inadvertently reversed arguments to `reply_for` somewhere (but it turned out to be that I had left out a `wordlist=sgb_words`).) Anyway, here are some tests for `wordle_reply_for`:" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [], "source": [ "assert reply_for('treat', 'truss') == 'GG...' and reply_for('truss', 'treat') == 'GG...'\n", "assert reply_for('stars', 'traps') == '.YGYG' and reply_for('traps', 'stars') == 'YYG.G'\n", "assert reply_for('palls', 'splat') == 'YYG.Y' and reply_for('splat', 'palls') == 'YYGY.'\n", "assert reply_for('banal', 'apple') == '.Y..Y' and reply_for('apple', 'banal') == 'Y..Y.'\n", "assert reply_for('banal', 'mania') == '.GGY.' and reply_for('mania', 'banal') == '.GG.Y'\n", "assert reply_for('epees', 'geese') == 'Y.GYY' and reply_for('geese', 'epees') == '.YGYY'\n", "assert reply_for('wheee', 'peeve') == '..GYG' and reply_for('peeve', 'wheee') == '.YG.G'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can test the new `reply_for` on a partition of `words22`:" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "defaultdict(list,\n", " {'.YYYY': ['their'],\n", " '...Y.': ['about'],\n", " 'G....': ['would'],\n", " '.Y.YG': ['throe'],\n", " 'YY...': ['sword'],\n", " '.....': ['cloud', 'sound', 'fondu'],\n", " 'GGGGG': ['write'],\n", " '.YYG.': ['rifts', 'girth'],\n", " 'GY.YY': ['water'],\n", " '.Y.YY': ['after'],\n", " '..GY.': ['think'],\n", " '.Y..Y': ['resay', 'nuder'],\n", " '....G': ['place', 'house'],\n", " '.G.GG': ['grate'],\n", " '...YY': ['ethos'],\n", " '..YY.': ['might'],\n", " 'G.G.G': ['while']})" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "partition('write', words22)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That looks good. Notice that there are many more possible replies in Wordle than the 6 possible replies in Jotto, so the target words are partitioned into smaller branches. It should take fewer guesses to solve a Wordle than a Jotto. How many possible replies are there? There are 3 responses at each of five positions, and 35 = 243, but five of those replies are impossible: you can't have four Greens and one Yellow, because if four letters of the guess are in the right place then the fifth must be either in the right place or a miss. \n", "\n", "# Sample Wordle Games\n", "\n", "Let's see what some Wordle games with a random guesser looks like:" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"guess\" Reply: .....; Consistent targets: 954\n", "Guess 2: \"batch\" Reply: .Y...; Consistent targets: 114\n", "Guess 3: \"villa\" Reply: ....Y; Consistent targets: 26\n", "Guess 4: \"drank\" Reply: .YYY.; Consistent targets: 3\n", "Guess 5: \"apron\" Reply: GGGGG; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "5" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(random_guesser, wordlist=sgb_words)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"nurse\" Reply: .G.G.; Consistent targets: 8\n", "Guess 2: \"gutsy\" Reply: .G.GG; Consistent targets: 5\n", "Guess 3: \"pussy\" Reply: .GGGG; Consistent targets: 3\n", "Guess 4: \"hussy\" Reply: GGGGG; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "4" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(random_guesser, wordlist=sgb_words)" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"dicey\" Reply: .Y.Y.; Consistent targets: 147\n", "Guess 2: \"sepia\" Reply: .G.G.; Consistent targets: 14\n", "Guess 3: \"kefir\" Reply: .G.GY; Consistent targets: 4\n", "Guess 4: \"remit\" Reply: GGGG.; Consistent targets: 1\n", "Guess 5: \"remix\" Reply: GGGGG; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "5" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(random_guesser, wordlist=sgb_words)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Wordle Strategies\n", "\n", "With the bigger `sgb_words` word list, computations take longer, so I'm only going to compare the random guesser with the two negative entropy minimizing guessers. This will take 15 minutes or so:" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "median: 4 guesses, mean: 4.63 ± 1.34, worst: 12, scores: 5,756\n", "cumulative: ≤3:18%, ≤4:51%, ≤5:79%, ≤6:92%, ≤7:97%, ≤8:99%, ≤9:99.6%, ≤10:99.8%\n", "CPU times: user 3min 6s, sys: 218 ms, total: 3min 7s\n", "Wall time: 3min 7s\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%time report(play(random_guesser, target, sgb_words, verbose=False) for target in sgb_words)" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 3min 3s, sys: 119 ms, total: 3min 3s\n", "Wall time: 3min 6s\n", "median: 4 guesses, mean: 4.09 ± 1.20, worst: 12, scores: 5,756\n", "cumulative: ≤3:32%, ≤4:73%, ≤5:89%, ≤6:95%, ≤7:98%, ≤8:99.4%, ≤9:99.8%, ≤10:99.9%\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%time wtree = minimizing_tree(neg_entropy, sgb_words, sgb_words, inconsistent=False)\n", "report(tree_scores(wtree))" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 8min 17s, sys: 420 ms, total: 8min 18s\n", "Wall time: 8min 21s\n", "median: 4 guesses, mean: 3.82 ± 0.71, worst: 7, scores: 5,756\n", "cumulative: ≤3:32%, ≤4:87%, ≤5:98%, ≤6:99.9%, ≤7:100%, ≤8:100%, ≤9:100%, ≤10:100%\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%time wtree = minimizing_tree(neg_entropy, sgb_words, sgb_words, inconsistent=True)\n", "report(tree_scores(wtree))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pretty good! The Wordle web site challenges you to solve each puzzle in six guesses; we can now do that 99.9% of the time when inconsistent guesses are allowed, a big jump from the 95% without inconsistent guesses and the 92% with random consistent guesses. \n", "\n", "This is all on the `sgb-words.txt` file. I poked around in the Wordle javascript, trying to find the official Wordle word list. If I correctly interpreted what I found, my algorithm gets these results:\n", "\n", " median: 3 guesses, mean: 3.49 ± 0.60, worst: 6, scores: 2,315\n", " cumulative: ≤3:53%, ≤4:96%, ≤5:99.8%, ≤6:100%, ≤7:100%, ≤8:100%, ≤9:100%, ≤10:100%\n", " \n", "I won't post the word list here, because I don't have the author's permission.\n", "\n", "# Jotto and Wordle Evaluation Summary\n", "\n", "Here is a summary (the first four columns on `sgb-words.txt`, the last on the Wordle word list):\n", "\n", "|


Algorithm|JOTTO
Consistent
Only
Mean (Max)|JOTTO
Inconsistent
Allowed
Mean (Max)|WORDLE
Consistent
Only
Mean (Max)|WORDLE
Inconsistent
Allowed
Mean (Max)|WORDLE
Official
Wordlist
Mean (Max)|\n", "|--|--|--|--|--|--|\n", "|random guesser|7.34 (18)| ––––––– |4.63 (12) | ––––––– | 4.08 (8) |\n", "|minimize max|7.15 (18)|7.05 (10)| ––––––– | ––––––– | ––––––– | ––––––– |\n", "|minimize expectation|7.14 (17)|6.84 (10)| ––––––– | ––––––– | ––––––– | ––––––– |\n", "|minimize neg_entropy|7.09 (19)|6.82 (10)| 4.09 (12) | 3.82 (7) | 3.49 (6) |\n", "\n", "\n", "\n", "\n", "# Sample Wordle Games with Minimizing Guesser\n", "\n", "Here are some sample games with the negative-entropy minimizing, inconsistent-guessing guesser:" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"tares\" Reply: YY..G; Consistent targets: 31\n", "Guess 2: \"sloth\" Reply: G..G.; Consistent targets: 4\n", "Guess 3: \"which\" Reply: .....; Consistent targets: 2\n", "Guess 4: \"spats\" Reply: G.GGG; Consistent targets: 1\n", "Guess 5: \"stats\" Reply: GGGGG; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "5" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(TreeGuesser(wtree), wordlist=sgb_words)" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"tares\" Reply: ..GY.; Consistent targets: 39\n", "Guess 2: \"peony\" Reply: .YY..; Consistent targets: 5\n", "Guess 3: \"fight\" Reply: G.Y..; Consistent targets: 1\n", "Guess 4: \"forge\" Reply: GGGGG; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "4" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(TreeGuesser(wtree), wordlist=sgb_words)" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Guess 1: \"tares\" Reply: YY.YY; Consistent targets: 20\n", "Guess 2: \"stalk\" Reply: YYG..; Consistent targets: 3\n", "Guess 3: \"feast\" Reply: .GGGG; Consistent targets: 2\n", "Guess 4: \"beast\" Reply: .GGGG; Consistent targets: 1\n", "Guess 5: \"yeast\" Reply: GGGGG; Consistent targets: 1\n" ] }, { "data": { "text/plain": [ "5" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "play(TreeGuesser(wtree), wordlist=sgb_words)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Best and Worst First Guesses for Wordle\n", "\n", "This will take about 10 minutes:" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "max | expectation | neg_entropy\n", "----------- + ----------- + -----------\n", "aloes 298 | tares 133 | tares -6.21\n", "arose 361 | rates 136 | rates -6.12\n", "aides 383 | aloes 137 | tales -6.10\n", "stoae 383 | tales 140 | tears -6.06\n", "earls 393 | nares 140 | nares -6.02\n", "reals 393 | saner 142 | tires -6.02\n", "earns 395 | lores 144 | reals -6.00\n", "nares 395 | reals 144 | dares -5.99\n", "nears 395 | roles 145 | lores -5.99\n", "saner 395 | lanes 148 | tries -5.99\n", "snare 395 | tears 152 | teals -5.98\n", "ideas 398 | riles 153 | saner -5.98\n", "lanes 403 | earls 154 | pares -5.97\n", "antes 409 | cares 155 | cares -5.97\n", "nates 409 | nates 156 | roles -5.97\n", "sepia 409 | laser 156 | aloes -5.96\n", "aisle 410 | dares 157 | lanes -5.96\n", "rates 415 | raise 157 | taels -5.95\n", "stare 415 | races 159 | slate -5.92\n", "tares 415 | teals 159 | riles -5.91\n", "----------- + ----------- + -----------\n", "jiffy 3158 | jiffy 1923 | oxbow -2.52\n", "oxbow 3173 | whooo 1941 | quiff -2.52\n", "duddy 3179 | oxbow 1954 | fizzy -2.50\n", "whizz 3202 | boffo 1959 | jiffy -2.49\n", "pffft 3208 | whizz 1978 | mummy -2.47\n", "fluff 3216 | vivid 1986 | civic -2.47\n", "whooo 3230 | fluff 1997 | mamma -2.46\n", "boffo 3233 | pffft 1999 | yummy -2.45\n", "vivid 3262 | kudzu 2016 | whizz -2.44\n", "kudzu 3264 | puppy 2074 | fluff -2.43\n", "civic 3348 | civic 2080 | kudzu -2.42\n", "puppy 3361 | ahhhh 2114 | buzzy -2.40\n", "mummy 3428 | mummy 2152 | jazzy -2.35\n", "yummy 3428 | yummy 2154 | pffft -2.35\n", "buzzy 3448 | buzzy 2181 | fuzzy -2.28\n", "ohhhh 3507 | fuzzy 2296 | yukky -2.25\n", "fuzzy 3542 | yukky 2328 | gyppy -2.25\n", "immix 3543 | immix 2398 | immix -2.08\n", "yukky 3569 | gyppy 2401 | ahhhh -2.05\n", "gyppy 3636 | ohhhh 2476 | ohhhh -1.85\n", "CPU times: user 8min 36s, sys: 396 ms, total: 8min 36s\n", "Wall time: 8min 36s\n" ] } ], "source": [ "%time partition_scores(20, wordlist=sgb_words)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The best words use popular letters, especially \"e\", \"s\", \"a\", \"r\", \"l\", \"t\".\n", "\n", "The worst words have repeated unpopular letters, like \"zz\" and \"yukky\".\n", "\n", "# Next Steps\n", "\n", "There are many directions you could take this if you are interested:\n", "- **Other games:**\n", " - Consider a Jotto game variant where each reply consists of two numbers: the number of letters in common with the target, and the number of letters that are in the exact correct position (as in Mastermind).\n", " - Implement [Mastermind](https://en.wikipedia.org/wiki/Mastermind_%28board_game%29). The default version has 6 colors and 4 pegs. Can you go beyond that?\n", " - Research what other computer scientists have done with [Jotto](https://arxiv.org/abs/1107.3342) or [Mastermind](http://serkangur.freeservers.com/).\n", " - Refactor the code so it can smoothly handle multiple different games.\n", "- **Better strategy**:\n", " - Our `minimizing_tree` function is **greedy** in that it guesses the word that minimizes some metric of the current situation without looking ahead to future branches in the tree. Can you get better performance by doing some **look-ahead**? Perhaps with a beam search?\n", " - As an alternative to look-ahead, can you improve a tree by editing it? Given a tree, look for interior nodes that end up with a worse-than-expected average score, and see if the node can be replaced with something better (covering the same target words). Correcting a few bad nodes might be faster than carefully searching for good nodes in the first place.\n", " - The three metrics (max, expectation, and negative entropy) are all designed as proxies to what we really want to minimize: the average number of guesses. Can we estimate that directly? For example, we know a branch of size 1 will always take 1 guess; of size 2 an average of 3/2 guesses; and of size 3 an average of 5/3 guesses if one of the words partitions the other two, otherwise an average of 2. Can we learn a function that takes a set of words as input and estimates the average number of guesses for the set?\n", " - Is it feasible to do a complete search and find the guaranteed optimal strategy? What optimizations to the code would be necessary? How long would the search take?\n", "- **Chooser strategy**:\n", " - Analyze the game where the chooser is not random, but rather is an adversary to the guesser–the chooser tries to choose a word that will maximize the guesser's score. What's a good strategy for the chooser? Is there a strategy equilibrium? (One thing I thought of is to choose a word like one of the `ails` words that has many other words that are off by one letter.) \n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 4 }