"source": [
"# Laser display boards\n",
"\n",
- "You need to navigate your way through Heathwick Airport to find the correct gate. The bad news is that all the display boards have gone down. The good news is that the terminal staff are handing out the machine-code instructions to generate the messages on the board. \n",
+ "You're off on your first sightseening trip of your holiday and you need to catch the right llama-rickshaw to get there. You arrive all keen at the llama-rickshaw station, only to find a scene of chaos. The bad news is that there are lots of llama-rickshaws heading to different places. The good news is that above each bay is a display board that shows where that llama-rickshaw is heading. The bad news is that all the display boards have gone down. The good news is that the station staff are handing out the machine-code instructions to generate the messages on the board. \n",
"\n",
"Given your l33t haxor skilz, it will be no problem to recreate the messages on the display boards.\n",
"\n",
"The board is grid, 80 pixels wide and 8 pixels tall, with row 1 being the top row and column 1 being the left column. The pixels are changed with these commands:\n",
"\n",
"* `top A B` switches the state of the pixels in the topmost row from columns A to B inclusive. If a pixel was lit, it becomes dark; if it was dark, it becomes lit.\n",
- "* `left A B` is similar, but works on the left edge, toggling the state of pixles in the leftmost column in rows A to B inclusive. \n",
+ "* `left A B` is similar, but works on the left edge, toggling the state of pixels in the leftmost column in rows A to B inclusive. \n",
"* `rotate column A B` rotates column A by B spaces down. Pixels that are moved beyond the bottom edge \"wrap around\" to the top edge.\n",
"* `rotate row A B` rotates row A by B spaces to the right. Pixels that are moved beyond the right edge \"wrap around\" to the left edge.\n",
"\n",
".*........\n",
"```\n",
"\n",
- "* `rotate column 8 1` moves the one lit pixel in column 8 down one row.\n",
+ "* `rotate column 8 5` moves the one lit pixel in column 8 down five rows, wrapping it all the way around the display and leaving the board with one lit pixel in that column one row lower.\n",
"```\n",
"*.....*.**\n",
".......*..\n",
"metadata": {},
"source": [
"## Part 1\n",
- "You're standing in front of gate 9¾. You have [the instructions](05-pixels.txt). How many pixels would be lit on the board, if it was working?"
+ "You're standing in front of gate 9¾. You have [the instructions](05-pixels.txt). How many pixels would be lit on the board, if it were working?"
]
},
{
--- /dev/null
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Given a sequence of {F|L|R}, each of which is \"move forward one step\", \"turn left, then move forward one step\", \"turn right, then move forward one step\":\n",
+ "1. which tours are closed?\n",
+ "2. what is the area enclosed by the tour?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 69,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "import collections\n",
+ "import enum\n",
+ "import random"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "class Direction(enum.Enum):\n",
+ " UP = 1\n",
+ " RIGHT = 2\n",
+ " DOWN = 3\n",
+ " LEFT = 4\n",
+ " \n",
+ "turn_lefts = {Direction.UP: Direction.LEFT, Direction.LEFT: Direction.DOWN,\n",
+ " Direction.DOWN: Direction.RIGHT, Direction.RIGHT: Direction.UP}\n",
+ "\n",
+ "turn_rights = {Direction.UP: Direction.RIGHT, Direction.RIGHT: Direction.DOWN,\n",
+ " Direction.DOWN: Direction.LEFT, Direction.LEFT: Direction.UP}\n",
+ "\n",
+ "def turn_left(d):\n",
+ " return turn_lefts[d]\n",
+ "\n",
+ "def turn_right(d):\n",
+ " return turn_rights[d]\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "Step = collections.namedtuple('Step', ['x', 'y', 'dir'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def advance(step, d):\n",
+ " if d == Direction.UP:\n",
+ " return Step(step.x, step.y+1, d)\n",
+ " elif d == Direction.DOWN:\n",
+ " return Step(step.x, step.y-1, d)\n",
+ " elif d == Direction.LEFT:\n",
+ " return Step(step.x-1, step.y, d)\n",
+ " elif d == Direction.RIGHT:\n",
+ " return Step(step.x+1, step.y, d)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def trace_tour(tour):\n",
+ " current = Step(0, 0, Direction.RIGHT)\n",
+ " trace = [current]\n",
+ " for s in tour:\n",
+ " if s == 'F':\n",
+ " current = advance(current, current.dir)\n",
+ " elif s == 'L':\n",
+ " current = advance(current, turn_left(current.dir))\n",
+ " elif s == 'R':\n",
+ " current = advance(current, turn_right(current.dir))\n",
+ " trace += [current]\n",
+ " return trace "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "k = Step(1, 2, 3)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Step(x=1, y=2, dir=3)"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "k"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "__main__.Step"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "Step"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<Direction.UP: 1>"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "d = Direction.UP\n",
+ "d"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "<Direction.RIGHT: 2>"
+ ]
+ },
+ "execution_count": 23,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "turn_right(d)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{<Direction.LEFT: 4>: <Direction.UP: 1>,\n",
+ " <Direction.UP: 1>: <Direction.RIGHT: 2>,\n",
+ " <Direction.DOWN: 3>: <Direction.LEFT: 4>,\n",
+ " <Direction.RIGHT: 2>: <Direction.DOWN: 3>}"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "turn_rights"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[Step(x=0, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=1, dir=<Direction.UP: 1>),\n",
+ " Step(x=2, y=1, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=2, y=2, dir=<Direction.UP: 1>)]"
+ ]
+ },
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trace_tour('FLRL')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[Step(x=0, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=2, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=2, y=1, dir=<Direction.UP: 1>),\n",
+ " Step(x=3, y=1, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=3, y=2, dir=<Direction.UP: 1>),\n",
+ " Step(x=2, y=2, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=1, y=2, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=1, y=1, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=0, y=1, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=0, y=0, dir=<Direction.DOWN: 3>)]"
+ ]
+ },
+ "execution_count": 33,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trace_tour('FFLRLLFLRL')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[Step(x=0, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=1, dir=<Direction.UP: 1>),\n",
+ " Step(x=0, y=1, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=-1, y=1, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=-2, y=1, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=-2, y=0, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=-2, y=-1, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=-2, y=-2, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=-2, y=-3, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=-1, y=-3, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=0, y=-3, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=-3, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=-2, dir=<Direction.UP: 1>),\n",
+ " Step(x=1, y=-1, dir=<Direction.UP: 1>),\n",
+ " Step(x=0, y=-1, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=0, y=-2, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=-1, y=-2, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=-1, y=-1, dir=<Direction.UP: 1>),\n",
+ " Step(x=-1, y=0, dir=<Direction.UP: 1>),\n",
+ " Step(x=0, y=0, dir=<Direction.RIGHT: 2>)]"
+ ]
+ },
+ "execution_count": 34,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trace_tour('FLLFFLFFFLFFLFLLRRFR')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[Step(x=0, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=2, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=2, y=-1, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=3, y=-1, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=3, y=0, dir=<Direction.UP: 1>),\n",
+ " Step(x=3, y=1, dir=<Direction.UP: 1>),\n",
+ " Step(x=4, y=1, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=4, y=2, dir=<Direction.UP: 1>),\n",
+ " Step(x=3, y=2, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=2, y=2, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=1, y=2, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=0, y=2, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=0, y=3, dir=<Direction.UP: 1>),\n",
+ " Step(x=0, y=4, dir=<Direction.UP: 1>),\n",
+ " Step(x=-1, y=4, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=-1, y=3, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=-2, y=3, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=-2, y=2, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=-1, y=2, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=-1, y=1, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=-2, y=1, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=-2, y=0, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=-1, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=-1, y=-1, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=0, y=-1, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=0, y=0, dir=<Direction.UP: 1>)]"
+ ]
+ },
+ "execution_count": 35,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trace_tour('FFRLLFRLLFFFRFLLRLLRRLLRLL')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 112,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def positions(trace):\n",
+ " return [(s.x, s.y) for s in trace]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 113,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[(0, 0),\n",
+ " (1, 0),\n",
+ " (2, 0),\n",
+ " (2, -1),\n",
+ " (3, -1),\n",
+ " (3, 0),\n",
+ " (3, 1),\n",
+ " (4, 1),\n",
+ " (4, 2),\n",
+ " (3, 2),\n",
+ " (2, 2),\n",
+ " (1, 2),\n",
+ " (0, 2),\n",
+ " (0, 3),\n",
+ " (0, 4),\n",
+ " (-1, 4),\n",
+ " (-1, 3),\n",
+ " (-2, 3),\n",
+ " (-2, 2),\n",
+ " (-1, 2),\n",
+ " (-1, 1),\n",
+ " (-2, 1),\n",
+ " (-2, 0),\n",
+ " (-1, 0),\n",
+ " (-1, -1),\n",
+ " (0, -1),\n",
+ " (0, 0)]"
+ ]
+ },
+ "execution_count": 113,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "positions(trace_tour('FFRLLFRLLFFFRFLLRLLRRLLRLL'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 114,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def valid(trace):\n",
+ " return (trace[-1].x == 0 \n",
+ " and trace[-1].y == 0 \n",
+ " and len(set(positions(trace))) + 1 == len(trace))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 115,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 115,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "valid(trace_tour('FFRLLFRLLFFFRFLLRLLRRLLRLL'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 116,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "False"
+ ]
+ },
+ "execution_count": 116,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "valid(trace_tour('FFRLLFRLLFFFRFLLRLLRRLLRLLFF'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 117,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "False"
+ ]
+ },
+ "execution_count": 117,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "valid(trace_tour('FFLLLFRR'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 118,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "False"
+ ]
+ },
+ "execution_count": 118,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "valid(trace_tour('F'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 119,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 119,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "valid(trace_tour('LLLL'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 120,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def chunks(items, n=2):\n",
+ " return [items[i:i+n] for i in range(len(items) - n + 1)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 121,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['abcdefg',\n",
+ " 'bcdefgh',\n",
+ " 'cdefghi',\n",
+ " 'defghij',\n",
+ " 'efghijk',\n",
+ " 'fghijkl',\n",
+ " 'ghijklm',\n",
+ " 'hijklmn',\n",
+ " 'ijklmno',\n",
+ " 'jklmnop',\n",
+ " 'klmnopq',\n",
+ " 'lmnopqr',\n",
+ " 'mnopqrs',\n",
+ " 'nopqrst',\n",
+ " 'opqrstu',\n",
+ " 'pqrstuv',\n",
+ " 'qrstuvw',\n",
+ " 'rstuvwx',\n",
+ " 'stuvwxy',\n",
+ " 'tuvwxyz']"
+ ]
+ },
+ "execution_count": 121,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import string\n",
+ "chunks(string.ascii_lowercase, 7)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Using the [Shoelace formula](https://en.wikipedia.org/wiki/Shoelace_formula)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 122,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def shoelace(trace):\n",
+ " return abs(sum(s.x * t.y - t.x * s.y for s, t in chunks(trace, 2))) // 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 123,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "4"
+ ]
+ },
+ "execution_count": 123,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "shoelace(trace_tour('FFLRLLFLRL'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 124,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "9"
+ ]
+ },
+ "execution_count": 124,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "shoelace(trace_tour('FLLFFLFFFLFFLFLLRRFR'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 125,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "15"
+ ]
+ },
+ "execution_count": 125,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "shoelace(trace_tour('FFRLLFRLLFFFRFLLRLLRRLLRLL'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 329,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def step(s, current):\n",
+ " if s == 'F':\n",
+ " return advance(current, current.dir)\n",
+ " elif s == 'L':\n",
+ " return advance(current, turn_left(current.dir))\n",
+ " elif s == 'R':\n",
+ " return advance(current, turn_right(current.dir))\n",
+ " else:\n",
+ " raise ValueError"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 507,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def valid_prefix(tour):\n",
+ " current = Step(0, 0, Direction.RIGHT)\n",
+ " prefix = []\n",
+ " posns = []\n",
+ " for s in tour:\n",
+ " current = step(s, current)\n",
+ " prefix += [s]\n",
+ " if (current.x, current.y) in posns:\n",
+ " return ''\n",
+ " elif current.x == 0 and current.y == 0: \n",
+ " return ''.join(prefix)\n",
+ " posns += [(current.x, current.y)]\n",
+ " if current.x == 0 and current.y == 0:\n",
+ " return ''.join(prefix)\n",
+ " else:\n",
+ " return ''"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 552,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def mistake_positions(tour, debug=False):\n",
+ " mistakes = []\n",
+ " current = Step(0, 0, Direction.RIGHT)\n",
+ " posns = [(0, 0)]\n",
+ " for i, s in enumerate(tour):\n",
+ " current = step(s, current)\n",
+ " if (current.x, current.y) in posns:\n",
+ " if debug: print(i, current)\n",
+ " mistakes += [(i+1, current)]\n",
+ " posns += [(current.x, current.y)]\n",
+ " if (current.x, current.y) == (0, 0):\n",
+ " return mistakes[:-1]\n",
+ " else:\n",
+ " return mistakes + [(len(tour)+1, current)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 550,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def returns_to_origin(mistake_positions):\n",
+ " return [i for i, m in mistake_positions\n",
+ " if (m.x, m.y) == (0, 0)]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 492,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "sample_tours = ['FFLRLLFLRL', 'FLLFFLFFFLFFLFLLRRFR', 'FFRLLFRLLFFFRFLLRLLRRLLRLL']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 493,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'FFLRLLFLRL'"
+ ]
+ },
+ "execution_count": 493,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "valid_prefix(sample_tours[0])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 494,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 494,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "all(valid_prefix(t) == t for t in sample_tours)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 495,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "False"
+ ]
+ },
+ "execution_count": 495,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "valid_prefix(sample_tours[0] + 'FLLLL') == sample_tours[0]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 526,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "9 Step(x=0, y=0, dir=<Direction.DOWN: 3>)\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "[(10, Step(x=0, y=0, dir=<Direction.DOWN: 3>)),\n",
+ " (12, Step(x=0, y=-1, dir=<Direction.DOWN: 3>))]"
+ ]
+ },
+ "execution_count": 526,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "mistake_positions(sample_tours[0] + 'F')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 527,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "9 Step(x=0, y=0, dir=<Direction.DOWN: 3>)\n",
+ "12 Step(x=1, y=0, dir=<Direction.UP: 1>)\n",
+ "13 Step(x=0, y=0, dir=<Direction.LEFT: 4>)\n",
+ "14 Step(x=0, y=-1, dir=<Direction.DOWN: 3>)\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "[(10, Step(x=0, y=0, dir=<Direction.DOWN: 3>)),\n",
+ " (13, Step(x=1, y=0, dir=<Direction.UP: 1>)),\n",
+ " (14, Step(x=0, y=0, dir=<Direction.LEFT: 4>)),\n",
+ " (15, Step(x=0, y=-1, dir=<Direction.DOWN: 3>)),\n",
+ " (16, Step(x=0, y=-1, dir=<Direction.DOWN: 3>))]"
+ ]
+ },
+ "execution_count": 527,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "mistake_positions(sample_tours[0] + 'FLLLL')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 528,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'FFLRLLFLRL'"
+ ]
+ },
+ "execution_count": 528,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "(sample_tours[0] + 'FLLLL')[:10]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 375,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def random_walk(steps=1000):\n",
+ " return ''.join(random.choice('FLR') for _ in range(steps))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 548,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "''"
+ ]
+ },
+ "execution_count": 548,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "valid_prefix(random_walk(1000))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 342,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'FLFFLRFRLFRRRR'"
+ ]
+ },
+ "execution_count": 342,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "valid_prefix(random_walk(1000), allowed_mistakes=1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 440,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [],
+ "source": [
+ "walks = []\n",
+ "while len(walks) < 10:\n",
+ " w = valid_prefix(random_walk())\n",
+ " if len(w) > 30: walks += [w]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 441,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['LFRRFLLRFLRLLRFLRLFLRFLFFFRLLRLL',\n",
+ " 'LRFFLFFFRLLRFRFFLRRFRLFLRFRLFRLRFFFF',\n",
+ " 'FFFLRFRLRLFLRLFLFFFFFRFFRLLFFFLRLFFLRF',\n",
+ " 'LFRLFFFFRLLRFFLLFFFRFFLLRFRLFLRFLF',\n",
+ " 'LFLRRFLLRRFRFLFFRFFFFRRLLRFLRFRRLF',\n",
+ " 'FLRLRLRFRLRFRLLFRFFRRLFRFLFLRRLR',\n",
+ " 'RFRRFFFFRLRFLFRRLRFFFFRRFFLLFFRF',\n",
+ " 'FFLFLRLFRLFFRFFLLFFRLLFRRLLRLFFF',\n",
+ " 'RFFLFRRLRRLRLLFRFRLLRRLRFRLLRRFFRLFFLR',\n",
+ " 'RFLFFLFRLFLRLFLRRLFFLRFLFLFRLLRF']"
+ ]
+ },
+ "execution_count": 441,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "walks"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 350,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[Step(x=0, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=1, dir=<Direction.UP: 1>),\n",
+ " Step(x=0, y=1, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=0, y=0, dir=<Direction.DOWN: 3>)]"
+ ]
+ },
+ "execution_count": 350,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trace_tour('FLLL')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 147,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(-1, 3)"
+ ]
+ },
+ "execution_count": 147,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85ef4c240>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import matplotlib.pyplot as plt\n",
+ "%matplotlib inline\n",
+ "plt.axis('on')\n",
+ "plt.arrow(0, 0, 0.8, 0, head_width=0.1, head_length=0.1, fc='k', ec='k', length_includes_head=True)\n",
+ "plt.arrow(0.2, 0, 0, 1, head_width=0.1, head_length=0.1, fc='k', ec='k', length_includes_head=True)\n",
+ "plt.xlim([-1, 2])\n",
+ "plt.ylim([-1, 3])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 135,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def bounds(trace):\n",
+ " return (max(s.x for s in trace),\n",
+ " max(s.y for s in trace),\n",
+ " min(s.x for s in trace),\n",
+ " min(s.y for s in trace))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 136,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(0, 2, -13, -13)"
+ ]
+ },
+ "execution_count": 136,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bounds(trace_tour('RFRFFLRFLFFRRFFRRRRLLLRRRRRRFRLFRFFRFFRRFRLRRFLLFRLLFRFLFLFRFRLLFRLFRFLRRLLFRRRFRRRRLLFLFRFRRFFRRLLLRLRRFRLRRFFRRFLFRRLLRRFFRFRRRRRFLLLLLRRFFFLLFFFRRLFLFFLRRRFRFLLFFRRLLRFLLRRF'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 148,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "plot_wh = {Direction.UP: (0, 1), Direction.LEFT: (-1, 0),\n",
+ " Direction.DOWN: (0, -1), Direction.RIGHT: (1, 0)}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 214,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def plot_trace(trace):\n",
+ " plt.axis('on')\n",
+ " plt.axes().set_aspect('equal')\n",
+ " for s, t in chunks(trace, 2):\n",
+ " w, h = plot_wh[t.dir]\n",
+ " plt.arrow(s.x, s.y, w, h, head_width=0.1, head_length=0.1, fc='k', ec='k', length_includes_head=True)\n",
+ " xh, yh, xl, yl = bounds(trace)\n",
+ " plt.xlim([xl-1, xh+1])\n",
+ " plt.ylim([yl-1, yh+1])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 514,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nf/99T6fT/tnPftY3b95clDOOVuG5N+xzOcmXFr/Ln19aPOXXZymdJkD/0mrdunXceuutABw8eJBx\n48YVzfsNjhw5grtTVVXFxRdfzO9//3sAampq2LBhA3PmzIk84akOHDjAJz7xCcyGXbFKggr20iKA\nu//C3f/a3S8eLASjwYQJE4omBADV1dWMGTOGjRs38uabbw48wbq7u3nggQciTze4c889VyEoYsXz\n0y1n5Oqrr6alpYWGhgYAHnroIVauXBl5KilFejtyiaurq2PZsmV0dnbS2trKsmXLYo8kJUorAxEB\nFAMRCRQDEQEUAxEJFAMRARQDEQkUAxEBFAMRCRQDEQEUAxEJFAMRARQDEQkUAxEBFAMRCRQDEQEU\nAxEJFAMRARQDEQkUAxEBFAMRCRQDEQEUAxEJFAMRARQDEQkUAxEBFAMRCRQDEQEUAxEJFAMRARQD\nEQkUAxEBFAMRCRQDEQEUg484evQo48ePp7y8HIAFCxZQWVnJ7t27I08mcvblFQMzu9XMfmtmJ8zs\nc0kNFUtFRQWHDx/m+PHjALg7vb29nHPOOZEnEzn78l0Z7ARuBrYmMEt0ZWVlLFmy5CMfy2QyNDQ0\nRJro9J5//nk2b96Mu8ceRUaJvGLg7h3uvhewhOaJrqWlZeA0AWDNmjURpzm9RYsWceONN3LFFVco\nCpIIS+KHyMx+Cdzr7r8ZYhsvlR/Y5cuX861vfYu6ujquvfba2OMM6ic/+cnA/ZqaGsaMGcOf/vQn\nRUFOYWa4+7C/sNM57GgTcP7JHwIceNDdfzqSoVasWDFwP5PJkMlkRvLlBdPS0sL69evZs2fPR550\nxaq3t5cjR47w9a9/PfYoUgSy2SzZbHbEX6eVQYn6/Oc/z/bt2ykvL2fhwoW0tLTwqU99KvZYUoQS\nWxmM5JgJ7kuGMXfuXKZOnaoISGLyWhmY2VeAR4E64BCw3d1vPM22WhmIRJDryiCR04RcKAYiceQa\nA70DUUQAxUBEAsVARADFQEQCxUBEAMVARALFQEQAxUBEAsVARADFQEQCxUBEAMVARALFQEQAxUBE\nAsVARADFQEQCxUBEAMVARALFQEQAxUBEAsVARADFQEQCxUBEAMVARALFQEQAxUBEAsVARADFQEQC\nxUBEAMVARALFQEQAxUBEAsVARADFQEQCxUBEgDxjYGaPmNluM9tuZhvMrDapwUSksPJdGfw3MMXd\nLwf2Ag/kP1LxyGazsUcYkVKbFzRzMckrBu6+2d37wsMXgIb8RyoepfafXmrzgmYuJkleM/gnYGOC\n+xORAkoPt4GZbQLOP/lDgAMPuvtPwzYPAsfcfe1ZmVJEzjpz9/x2YPaPwNeAme7eM8R2+R1IRM6Y\nu9tw2wy7MhiKmd0A3AfMGCoEuQ4jIvHktTIws71ABXAgfOgFd789icFEpLDyPk0QkdGhoO9ANLNb\nzey3ZnbCzD5XyGOPhJndYGZ7zOx/zGxJ7HmGY2ZPmtk+M9sRe5ZcmFmDmW0xs11mttPM7oo903DM\nrNLMXjSzV8PMzbFnyoWZlZnZb8zsP4fbttBvR94J3AxsLfBxc2ZmZcBjwBxgCrDQzCbHnWpYT9E/\nb6k4Dtzj7pcCXwDuKPbvcbgmdp27XwFcDtxoZtMij5WLRcCuXDYsaAzcvcPd99L/8mSxmgbsdfc/\nuPsx4MfA/MgzDcndtwEHY8+RK3d/z923h/tdwG6gPu5Uw3P3w+FuJf0X34v6HNvMGoAvAz/MZXv9\nodKp6oG3T3r8DiXwg1qqzGwi/b9pX4w7yfDCkvtV4D1gk7v/OvZMw/gXoIkco5V4DMxsk5ntOOm2\nM/z7N0kf6ywZbNVS1L8BSpWZjQXWA4vCCqGouXtfOE1oAK42s0tjz3Q6ZnYTsC+swIwcVuN5vc9g\nMO4+K+l9Ftg7wKdPetwAvBtpllHLzNL0h2CNuz8be56RcPdOM8sCN5Dj+XgEjcA8M/syUA2cY2b/\n7u7/cLoviHmaUKzXDX4NTDKzz5hZBfC3wLBXYotATvUvIj8Cdrn7d2MPkgszqzOzceF+NXA9sCfu\nVKfn7kvd/dPufhH9P8NbhgoBFP6lxa+Y2dvAdKDNzIruD5vc/QTwz/T/efbrwI/dfXfcqYZmZmuB\nduCvzOwtM7st9kxDMbNG4O+AmeGlut+Ed7MWs08CvzSz7fRf3/gvd/955JkSpTcdiQigVxNEJFAM\nRARQDEQkUAxEBFAMRCRQDEQEUAxEJFAMRASA/wNQM89DiBxhRAAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85ef71c50>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(sample_tours[0] + 'FLLLL'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 215,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nRU5ErkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85ef505f8>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour('FFFLLFFL'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 216,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[Step(x=0, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=0, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=1, y=-1, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=1, y=-2, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=0, y=-2, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=-1, y=-2, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=-1, y=-3, dir=<Direction.DOWN: 3>),\n",
+ " Step(x=-2, y=-3, dir=<Direction.LEFT: 4>),\n",
+ " Step(x=-2, y=-2, dir=<Direction.UP: 1>),\n",
+ " Step(x=-2, y=-1, dir=<Direction.UP: 1>),\n",
+ " Step(x=-1, y=-1, dir=<Direction.RIGHT: 2>),\n",
+ " Step(x=-1, y=0, dir=<Direction.UP: 1>),\n",
+ " Step(x=0, y=0, dir=<Direction.RIGHT: 2>)]"
+ ]
+ },
+ "execution_count": 216,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "trace_tour(walks[3])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 405,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWMAAAEACAYAAABmohcVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAF81JREFUeJzt3X2QVPWd7/H3t3uYBwYWhoRCeZCH3DiGEEMMRVioxA7r\nrjibhaVIVRZJXSNJrBCJ1EY0shKGwXCDa8hWCBIjaoiXWNlcoheQxeAqbUmu8rDEBwYQ4wQQFkgg\nM6AODEP3d/+YgcvlAjOmT875QX9eVV10T5/+fb5nnP5w5nQ3mrsjIiLJSiU9gIiIqIxFRIKgMhYR\nCYDKWEQkACpjEZEAqIxFRAJQEsUiZrYbOArkgVZ3HxnFuiIixSKSMqathDPu3hjReiIiRSWq0xQW\n4VoiIkUnqgJ14FdmttnMvhrRmiIiRSOq0xSj3f2gmfUGnjWzHe6+IaK1RUQue5GUsbsfbP/zD2b2\nFDAS+H/K2Mz0j2CISFFyd+tom4JPU5hZVzPr1n69EvgbYNsFBiraS21tbeIzaN+1/9r/+C+dFcWR\ncR/gqfYj3xLgZ+6+LoJ1RUSKRsFl7O6/A4ZHMIuISNHS29Fikslkkh4hMcW876D9L/b97yx7P+c0\nCgoy87iyRERCYWZ4HC/giYhI4VTGIiIBUBmLiARAZSwiEgCVsYhIAFTGIiIBUBmLiARAZSwiEgCV\nsYhIAFTGIiIBUBmLiARAZSwiEgCVsYhIAFTGIiIBUBmLiARAZSwiEgCVsYhIAFTGIiIBUBmLiARA\nZSwiEgCVsYhIACIrYzNLmdlWM1sV1ZoiIsUiyiPjGcD2CNcTESkakZSxmfUHaoBHoljvz6WlpYWl\nS5eya9euRPLfffddFi9ezIEDBxLJP3LkCIsWLaKpqSmR/H379vHDH/6QEydOJJK/a9cuHnroIXK5\nXCL5xczdWbVqFevXr096lGCVRLTOvwB3AT0iWi9SJ06c4LHHHmPOnDk0NTUxY8YM5s+fH1t+c3Mz\nP/rRj7j//vs5fvw4+Xye2267Lbb8pqYmFi5cyJIlSzh58iT9+/enpqYmtvwDBw4wf/58nnjiCVpb\nWxk1ahQf+9jHYstvaGhgzpw5rFmzhpaWFiZMmEBVVVVs+V26dCGdTseWF5LTJXzXXXexe/duPv7x\nj/Piiy/GOkN5eXmseX8qc/fCFjD7W+Amd59uZhngTnf/u/Ns57W1tWduZzIZMplMQdmdNWzYMOrr\n62PJ6oiZUej3/FKUSqXI5/OJZJeWlnLq1KnE8gcMGMDu3btJpYrv9fJp06bx0EMPJTrDzJkzeeCB\nB2LLy2azZLPZM7fr6upwd+vwge5e0AX4H8BeoAE4ALwLPH6e7TwpgH/yk5/0Pn36eDqd9rvvvjvW\n/ObmZl+4cKH37NnT0+m0L1myJNb8xsZGnz17tldWVnpJSYmvXr061vyDBw/69OnTvaKiwtPptL/6\n6qux5jc0NPiUKVO8vLzczcz/+Mc/xpKbz+f9wx/+sJeUlPgvfvGLWDJDU1VV5YAPGzbMu3Tp4iNH\njowte/v27V5WVuaVlZXe1NQUW+652ruv4y7tzEadvQDXA6sucN+fe58vCPBJkyb5yZMn/fHHH/e3\n3norkTmam5v9kUce8UOHDiWS39jY6D/+8Y/92LFjieQfPHjQly5d6idOnEgkv6GhwZctW+a5XC6W\nvJUrV3q3bt0c8EGDBsWWG5LTZZzP5/2ZZ57xDRs2xJY9YcIET6VSXlFR4XPmzIkt91ydLeOCT1Oc\nzcyup+00xfjz3OdRZr0fZsakSZNYsWJFIvlSnCZNmsSTTz555nZ9fT1Dhw5NcKL49erVi8bGxthP\nzbW0tNCjRw9aWloAGDJkCG+99VasM5zWfmqyw9MUkZ7EcvcXzlfEIsVo6dKlfPWrXwWKs4iTVFZW\nxo4dOwDo3r177C8a/imK7xUFkZj06tWLIUOGAKiIEzB48GAA+vbtS9++fROepmMqYxGRAKiMRUQC\noDIWEQmAylhEJAAqYxGRAKiMRUQCoDIWEQmAylhEJAAqYxGRAKiMRUQCoDIWEQmAylhEJAAqYxGR\nAKiMRUQCoDIWEQmAylhEJAAqYxGRAKiMRUQCoDIWEQmAylhEJAAqYxGRAKiMRUQCUHAZm1mZmW00\ns9+Y2etmVhvFYFFZt24dAJs3b6a+vj7haUSKx6ZNm2hsbATg17/+dcLThK/gMnb3FuCz7v4JYDhw\nk5mNLHiyCBw+fJhx48YBsG/fPqZOnZrwRCLFwd0ZP348ZgbAjTfeSC6XS3iqsEVymsLdm9uvlgEl\ngEexbqE++MEPUlNTQyqVomvXrsycOTO27NraWlavXo17EN8KSZi7s3LlSurq6hLJP3XqFD/96U9Z\ntGhRLHlmxowZMygvL6esrIzbbruNdDodS/alqiSKRcwsBfwH8CHgQXffHMW6UViwYAFr166lsrKS\nqqoqnn/++Vhy582bR2VlJf369WPBggVMnDgxllwJU3V1Nfv376e5uZlPf/rTseXm83kaGhqYO3cu\njY2NmBnDhg2LJfvaa6/FzDAzZs2aFUvmpcyiPHIzs78A/jcw3d23n3Of19b+39PJmUyGTCYTWfbF\n1NTUsHbt2liyzpVOp8nlcqxZs4aamppEZpDkvPrqq4wYMYJ8Pk8+n09khtOFmFT+tGnTWLJkSSLZ\nQ4cOpbq6mqeeeiq2zGw2SzabPXO7rq4Od7cOH+jukV6AOcA3z/N1LyYlJSVeXl7u3/jGNxzwhQsX\nJj2SJOTAgQN+++23e3l5uZeVlcWe39DQ4FOmTPGSkhLv379/7PlJ2bRpk1dUVHhFRYUfOnQosTna\nu6/D7ozi3RQfNLMe7dcrgBuAnYWue6l74YUX2LNnT2zn6CRcV1xxBYsXL2b37t2sX78+9vzBgwez\nfPlydu3axdNPPx17flLuuusujh8/Tj6f5zvf+U7S43QoinPGVwI/bT9vnAL+1d3/LYJ1L2mjR49O\negQJTJ8+fejTp09i+YMHD04sO24tLS1s2bLlzPXTb3ENWcFl7O6vA9dFMIuISCTKyso4dOgQ3bp1\n46qrruKVV15JeqQO6RN4InJZqqysBKCiooLy8vKEp+mYylhEJAAqYxGRAKiMRUQCoDIWEQmAylhE\nJAAqYxGRAKiMRUQCoDIWEQmAylhEJAAqYxGRAKiMRUQCoDIWEQmAylhEJAAqYxGRAKiMRUQCoDIW\nEQmAylhEJAAqYxGRAKiMRUQCoDIWEQmAylhEJAAqYxGRABRcxmbW38yeN7PtZva6md0RxWCXg9bW\nVh588EEAVqxYwdatWxOeSERCFcWR8Sngm+4+FPhL4HYzuyaCdS95b7zxBtOnTyeVSrFx40a+973v\nJT2SiASq4DJ294Pu/kr79XeBHUC/Qte9HAwbNowxY8aQz+cpKyvj3nvvjSX3xIkTfP7zn2f58uXk\ncrlYMkWkMObu0S1mNgjIAsPai/ns+zzKrEvFSy+9xOjRo6muruaLX/xiLJlNTU0sXLiQyspKevbs\nSV1dHV/+8pdjyRYJiZnxkY98hO3btyc6g7tbh9tFVZBm1o22Ir7P3Vee536vra09czuTyZDJZCLJ\nDt1NN93EM888k0h2ly5daG1tpb6+nqFDhyYyg0gS3J0hQ4ZQXV0d6/Mvm82SzWbP3K6rq4uvjM2s\nBHgaWOvuP7jANkV5ZJyEI0eO0Lt3b6644gq++93v8qUvfYmXX36ZT33qU0mPJhKb5557jvHjx5PP\n59mxYweDBg1KZI7OHhlH9da2x4DtFypiidcHPvABdu7cyd69e7nllluSHkckdu7OzJkzaW5uprW1\nlW9/+9tJj9ShKN7aNgaYAow1s9+Y2VYzG1f4aFKIq6++mpKSkqTHEEnEyZMn+f3vfw9ALpdj165d\nCU/UsYKfre7+ayAdwSwiIpEoKytj//79mBnV1dVs3Lgx6ZE6pE/giYgEQGUsIhIAlbGISABUxiIi\nAVAZi4gEQGUsIhIAlbGISABUxiIiAVAZi4gEQGUsIhIAlbGISABUxiIiAVAZi4gEQGUsIhIAlbGI\nSABUxiIiAVAZi4gEQGUsIhIAlbGISABUxiIiAVAZi4gEQGUsIhIAlbGISAAiKWMze9TMDpnZa1Gs\nJ9E4dOgQd9xxBwB1dXVs3Lgx4YlE5EKiOjL+CXBjRGtJROrr63nwwQcBWLduHevWrUt4IhG5kEjK\n2N03AI1RrHW5cndWrlzJddddx4svvhhL5mc/+1mGDh0KQHl5+Zmj5Mvdtm3bGD58OMuXLyeXyyU9\njkinlCQ9QDFYsWIFs2bN4sCBAxw/fpwbbriBsWPHxpJdXl4OwJ133kmPHj1iyTzXokWLWLt2bWx5\nW7du5fDhw3zta1/jnnvuYd68eUydOjW2fAlLaWlp0iN0irl7NAuZDQRWu/u1F7jfa2trz9zOZDJk\nMplIskNnZqRSKdLpNLlcjnw+H2v+4MGD2bJlC7169Yo1F2D9+vWx/cVzrnQ6DUAulyOqn3O5dOTz\nefr168fVV1/NCy+8EFtuNpslm82euV1XV4e7W4cPdPdILsBA4LWL3O/FCvDZs2f7Lbfc4ul02pcv\nX570SLEZMWKEAz5q1KjYMp977jlPpVI+ceJEf/zxx72Yf/aK2YoVK7yystIrKip827Ztic3R/vPX\nYYdG+dY2a7/IeVRVVbFs2TIOHz7MlClTkh4nFtlsltdea3uDzdatW9mwYUMsuWPHjuXIkSM8+eST\nDBw4MJZMCUs+n+fuu+/mvffe48SJE9xzzz1Jj9ShqN7a9gTwf4CrzWyvmd0axbqXo549eyY9QmyO\nHTtG7969AejduzfHjh2LLbuYvs/y/zt16hRVVVVA22//qVT4H6mI5AU8d785inXk8jJ+/HjGjRtH\nWVkZe/fuvSSeEHJ5KC0tZcuWLZgZ1dXVrFy5MumROqRnh4hIAFTGIiIBUBmLiARAZSwiEgCVsYhI\nAFTGIiIBUBmLiARAZSwiEgCVsYhIAFTGIiIBUBmLiARAZSwiEgCVsYhIAFTGIiIBUBmLiARAZSwi\nEgCVsYhIAFTGIiIBUBmLiARAZSwiEgCVsYhIAFTGIiIBUBmLiAQgkjI2s3FmttPMdpnZt6JY83LQ\n2NjI+PHjAZg7dy7Lli1LdqAis2rVKqZNmwZATU0Ne/bsSXgikQsruIzNLAUsBm4EPgpMNrNrCl33\ncnD06FHWrFkDQHNzM1u3bo0t291jywoxH+CNN95g165dAPzqV7/iD3/4Q2zZSe9/0vny/kVxZDwS\neNPd97h7K/BzYEIE617yBg0axOTJk0mn05SWljJ79uxYct955x0GDBjA1KlTefvtt2PJPNvu3bu5\n8sorufPOOzl8+HDs+ad9/etfp2vXrgB85jOfYcSIEbHkrl69miuvvJLFixfT0tISS+bZlixZwsCB\nA1m+fDm5XC72fPnTWKF/g5rZJOBGd7+t/fYXgZHufsc523kx/m39u9/9jg996EOUlpZSWloaS+Z7\n771HPp+nS5cupNNpxowZw6ZNm2LJhra/DADKysowM06cOEEulyOViv8ligULFjBr1iwqKytjy3/n\nnXdIpVJUVFRQWlrKNddcw7Zt22LJPp0P0K1bN7p3787ChQuZPHlybPkhMTNGjBjB5s2bE53B3a2j\n7UqiyDrP187bunPnzj1zPZPJkMlkIogP2+DBg7nvvvuYPXt27EdJ+XyedDrN0aNHzzxB485PpVJ8\n4QtfwKzDn8U/i9tvv51169axfv362LPdnZMnT9LU1JTI99/dOXLkCDfffHNRlvGpU6fo1atX7D97\n2WyWbDb7/h/o7gVdgFHAM2fdvgf41nm2c4nH0aNHvaqqyidOnOg7duyIPf+3v/2td+/e3W+99Vbf\nu3dv7PlJ++Uvf+ndu3f3++67z48dOxZ7/ve//33v1auXL1682G+66SYv1ufeo48+6pWVld61a1d/\n6aWXEpuj/fvfYZdGcZoiDbwB/BVwANgETHb3Heds54VmSeflcjnS6XTR5ict6f0/nf+5z32ONWvW\nFN0LeqdOnWLAgAEcPHgQgDFjxrBhw4ZEZunsaYqCT6K5ew6YDqwD6oGfn1vEEr+kizDp/KQlvf9J\n5yfNzBg1atSZ28OHD09wms4p+Mi400E6MhaJXbEeGZ9mZlRXV7Nz585EZ4jlyFhERAqnMhYRCYDK\nWEQkACpjEZEAqIxFRAKgMhYRCYDKWEQkACpjEZEAqIxFRAKgMhYRCYDKWEQkACpjEZEAqIxFRAKg\nMhYRCYDKWEQkACpjEZEAqIxFRAKgMhYRCYDKWEQkACpjEZEAqIxFRAKgMhYRCYDKWEQkAAWVsZl9\n3sy2mVnOzK6LaigRKdz06dNZs2YNAKNHj6a5uTnhieRiCj0yfh2YCLwQwSwiEqHDhw+TSrU9xXfu\n3Ek6nY4lN5/P09LSEkvW+bS2tpLL5RLL/1MVVMbu/oa7vwlYRPOISETmz59PaWkpFRUVzJs3j7Ky\nslhyv/KVr9C3b18WL16cSCmPGzeOgQMHsnz58tizC2HuXvgiZuuBO91960W28SiyRKTzJkyYwOrV\nq0niude1a1e6dOnC0aNHY88GqKyspLm5meuvv57169cnMgOAmeHuHR6wlnRioWeBPmd/CXDgXndf\n/X6Gmjt37pnrmUyGTCbzfh4uIu/Tww8/zNSpU9mzZ09smfX19UBbCQ0ePJjKykqamppizTcz8vk8\nY8aMYdmyZbFlA2SzWbLZ7Pt+nI6MRSRStbW1rF27lgceeIDrr78+9vxbb72V/fv3c//99/OJT3wi\n9vxzdfbIOMoynunu/3GRbVTGIlJ0OlvGhb617e/N7G1gFPC0ma0tZD0RkWIVyZFxp4J0ZCwiRSiW\nI2MREYmGylhEJAAqYxGRAKiMRUQCoDIWEQmAylhEJAAqYxGRAKiMRUQCoDIWEQmAylhEJAAqYxGR\nAKiMRUQCoDIWEQmAylhEJAAqYxGRAKiMRUQCoDIWEQmAylhEJAAqYxGRAKiMRUQCoDIWEQmAylhE\nJAAFlbGZ/bOZ7TCzV8zsl2b2F1ENJiJSTAo9Ml4HfNTdhwNvArMKH+nylM1mkx4hMcW876D9L/b9\n76yCytjd/93d8+03Xwb6Fz7S5amYfyCLed9B+1/s+99ZUZ4zngqsjXA9EZGiUdLRBmb2LNDn7C8B\nDtzr7qvbt7kXaHX3J/4sU4qIXObM3QtbwOwW4DZgrLu3XGS7woJERC5R7m4dbdPhkfHFmNk44G7g\nMxcr4s4OIyJSrAo6MjazN4FS4Ej7l152969HMZiISDEp+DSFiIgULtZP4BXjh0TMbJyZ7TSzXWb2\nraTniZOZ9Tez581su5m9bmZ3JD1TEswsZWZbzWxV0rPEzcx6mNn/an/e15vZp5KeKS5m9o9mts3M\nXjOzn5lZ6cW2j/vj0EX1IREzSwGLgRuBjwKTzeyaZKeK1Sngm+4+FPhL4PYi2//TZgDbkx4iIT8A\n/s3dPwJ8HNiR8DyxMLO+wDeA69z9Wtpen/uHiz0m1jIuwg+JjATedPc97t4K/ByYkPBMsXH3g+7+\nSvv1d2l7IvZLdqp4mVl/oAZ4JOlZ4mZm3YFPu/tPANz9lLsfS3isOKWBSjMrAboC/3mxjZP8h4KK\n4UMi/YC3z7q9jyIro9PMbBAwHNiY7CSx+xfgLtrem19shgCHzewn7adpHjaziqSHioO7/yewENgL\n7Aea3P3fL/aYyMvYzJ5tP0dy+vJ6+59/d9Y2xfIhkfO9na/onpRm1g1YAcxoP0IuCmb2t8Ch9t8O\njPP/PFzOSoDrgAfd/TqgGbgn2ZHiYWY9afsteCDQF+hmZjdf7DEFvc/4fNz9ry92f/uHRGqAsVFn\nB2gfcNVZt/vTwa8ql5v2X9FWAP/T3VcmPU/MxgDjzawGqAC6m9nj7v7fE54rLvuAt919S/vtFUCx\nvIh9A9Dg7n8EMLMngdHABQ9A4343xekPiYzv6EMil4nNwH8zs4Htr6T+A1Bsr6g/Bmx39x8kPUjc\n3P2f3P0qdx9C23/754uoiHH3Q8DbZnZ1+5f+iuJ5IXMvMMrMys3MaNv3i754GfmRcQd+SNuHRJ5t\nm+/y/pCIu+fMbDpt7yJJAY+6e1G8mgxgZmOAKcDrZvYb2k7R/JO7P5PsZBKjO4CfmVkXoAG4NeF5\nYuHum8xsBfAboLX9z4cv9hh96ENEJAD63y6JiARAZSwiEgCVsYhIAFTGIiIBUBmLiARAZSwiEgCV\nsYhIAFTGIiIB+C+pi+rYc+DkNgAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85eaef0f0>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(walks[3]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 442,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "10"
+ ]
+ },
+ "execution_count": 442,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "long_walks = [w for w in walks if len(w) >= 30]\n",
+ "len(long_walks)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 443,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85ebd9f28>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(long_walks[0]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 444,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAANgAAAEACAYAAADROrgbAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFDRJREFUeJzt3XuQVOWZx/Hv0zMDyFXIrDsEBLRYAq5IFiPZApFm1YkK\n6lbEEGPWyx9W/tjdRFMxoKYKrKSQqpRBU7FScpF1RV1LwOAYUwhF2gquKyYMd5RZjYLgIDdBkMtc\nnv2je6aQZaTp877TPcPvU3VqTg9nnvP0TP/mnD7D+x5zd0QkjlSxGxDpzBQwkYgUMJGIFDCRiBQw\nkYgUMJGIzhgwM1tgZrvNbMNJn+trZq+Z2btmttzM+sRtU6RjyucIthD41imfmw6sdPevAauAB0I3\nJtIZWD5/aDazwUCNu1+We/wOMMHdd5tZFZBx9+FxWxXpeAp9D3aBu+8GcPd64G/CtSTSeegih0hE\n5QV+3W4z+9uTThE/aWtDM9N/dpROyd3tTNvkewSz3NLiZeCu3PqdwLIzNBJsmTFjRknX6wg96jkn\nX/KVz2X654D/BoaZ2XYzuxuYDVxrZu8C1+Qei8gpzniK6O7fa+Ofrgnci0in0+EucqTT6ZKuF6Nm\nqdeLUbPU6+Urr7+DJdqBmcfeh0h7MzM84EUOESmAAiYSkQImEpECJhKRAiYSkQImEpECJhKRAiYS\nkQImEpECJhKRAiYSkQImEpECJp1WfX09c+bM4dNPPy1aDwqYlJxHH30UM0u89O/fnx//+MdUVVUx\ne3ZxxgRruIqUlAMHDlBVVUW3bt0YMWJEolpvvfUWAL179+bQoUNnNdT/TPIdrlLopDciUTz55JOc\nOHGCEydOMG/ePEaOHFlwrcbGRtauXcsvfvELampqAnaZP50iSkm57bbbAKioqEh8BCsvL2fMmDEh\n2iqYAiYlZfDgwQBMnDiR8vKOf4KlgIlEpICJRKSAiUSkgIlEpICJRKSAiUSkgIlEpICJRKSAiUSk\ngIlEpICJRKSAiUSUKGBmdp+ZbTKzDWb2rJl1CdWYSGdQcMDM7KvAvwOj3f0ysmPLvhuqMZEQmpub\nWbNmDQAff/xxu+8/6SliGdDDzMqB7sCu5C1JLHV1dUFH9W7fvp3jx48Hq/fZZ59RX18frB7Ali1b\n2L17NwDz588PWjsfBQ+4cfddZvYosB34HHjN3VcG60wA2LNnDw899BBHjx5NVGfbtm2sWbOGkSNH\nMmHChCATwSxatIh+/fpx5513smfPniD1Uqns73yzM47Gz8ull17K6NGj2bBhA/fcc0+Qmmej4ICZ\n2fnAzcBg4CCw2My+5+7PnbrtzJkzW9fT6XTR7pfbEU2cOJHNmzcHq7dp0ybq6uo4duxYkHqfffYZ\nL774Ih999FGQes3NzfTo0YOf//znQeoBXHLJJdTW1lJVVVVwjUwmQyaTOfsvdPeCFmAKMO+kx/8C\n/OY027kUZvXq1Q444GvWrElUa9++fT59+nTftm1boO7cZ8+e7cuXL/fm5uYg9V555RV/7LHH/OjR\no0Hqtbjxxhs99OswV++MOUkyJns78I9m1g04DlwNvJ2gnpyiZ8+eres9evRIVKtfv3488sgjSVv6\ngmnTpgWtN2nSpKD1SkHBFzncfQ2wGKgF1gMGzA3UlwCjRo0CshPAXHLJJUXuRgqRaFYRd38YeDhQ\nLyKdjv4nh0hECphIRAqYSEQKmEhECphIRAqYSEQKmEhECphIRAqYSEQKmEhECphIRAqYSEQKmHR6\nLYNLm5qa2n3fCph0au+88w4rVqwA4Je//GW777/j3wRXOp1jx47x1FNPMWvWLH77298yYcKEgmtV\nVlbyla98hYMHD3LttdcG7DI/5gFnGTrtDsw89j46syuvvJIuXbqwatWqYrfSbkaPHk1tbW3QmmPH\njuWNN94IVs/McPczzsyjgJWwHTt2MGzYMMyM9957j/79+xe7pXZhZowcOZKGhgbmzp3L+PHji93S\n/5NvwHSKWMLWr1/f+gZ948aN50zAAPr378/y5cuL3UZiushRwiZPngxk5+Sorq4ucjdSCAVMJCIF\nTCQiBUwkIgVMJCIFTCQiBUwkIgVMJCIFTCQiBUwkIgVMJCIFTCQiBUwkokQBM7M+ZvaimW01s81m\n9s1QjYl0BkmHqzwOvOrut5pZOdA9QE8inUbBRzAz6wWMd/eFAO7e6O6HgnUm56SlS5cC8Nprr7Fr\n164id5NcklPEi4G9ZrbQzNaa2VwzOy9UY/JF9957L2+++Wax24iusbERM6OiooJUqhNcInD3ghbg\ncqAB+Ebu8WPAw6fZzqVwo0ePdjNzINhy4403FvtptampqckrKyv9O9/5TrFb+VK51/UZc5LkPdhH\nwA53/3Pu8WJg2uk2nDlzZut6Op0mnU4n2O25ZdmyZfzsZz/j6aef5qKLLmLq1KmJ6i1evJiamhrW\n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\n9pgvWLDAGxoagtRbvXq1T58+3ffu3RukXkyAL1q0yO+77z4/duxYsdtpF/kGLMi0bV8m1KQ3O3fu\nZODAgQC8+uqrXH/99YlrShhmRl1dHUOHDi12K+2mvSa9aTcDBgxonfFV4ZKOosMETKQjUsBEIlLA\nRCJSwEQiUsBEIlLARCJSwEQiUsBEIlLARCJSwEQiUsBEIlLARCJKFDAzu87M3jGzbWY2LVRTIp1F\nkjtcpoDfAN8C/h64zcyGh2pMOoampqYvfJQvSnIEGwPUufuH7t4A/Bdwc5i2pKNouY/0+PHjO8Uk\nNaElCdgAYMdJjz/KfS66K664gocffjhIrQ8//JA77rgj2E3Gjxw5wuzZsxk6dCjvv/9+4nruzrJl\nyxgxYgTPPvtsgA5h06ZNTJ48malTpyauNXHiRFKpFFdddRVmZxx/eO7JZ9jz6RZgCjD3pMffBx4/\nzXbBhmnPnj076LwPgHfp0sXNLHjdUl7KysqC19y6dWuwn3NHQJ5TBiSZVeojYNBJjwcCu0634cyZ\nM1vX0+k06XS6oB3+9Kc/5fLLL+f+++9n0qRJzJgxo6A6J/vrX//KjBkzeO+993jjjTcS1zt8+DBP\nPPEE8+fPZ/ny5Vx88cWJ6jU3N/Pyyy/z4IMP8tBDD3H77bcn7nHjxo088MAD9OjRgxdeeCFxvVQq\nRVlZWeI6pSyTyZDJZM766wqek8PMyoB3gauBj4E1wG3uvvWU7bzQfYiUqnzn5Cj4CObuTWb2b8Br\nZN/LLTg1XCLnug4zq5RIKel0s0qJdEQKmEhECphIRAqYSEQKmEhECphIRAqYSEQKmEhECphIRAqY\nSEQKmEhECphIRB0uYIWMyWnPejFqlnq9GDVLvV6+FDC92EqyZqnXy1eHC5hIR6KAiUTULgMuo+5A\npEjyGXAZPWAi5zKdIopEpICJRNQuATOzKWa2ycyazGx0gjrBbjZhZgvMbLeZbUhS56R6A81slZlt\nMbONZvbDADW7mtlbZlabq5l8Ishs3ZSZrTWzlwPU+sDM1ud6XBOgXh8ze9HMtprZZjP7ZsJ6w3K9\nrc19PJj0Z2Nm9+VezxvM7Fkz69LmxvnMTpp0Ab4G/B2wChhdYI0U8L/AYKACWAcMT9DTlcDXgQ2B\nnmMV8PXcek+yc0YW3N9JdbvnPpYB/wOMCVDzPmAR8HKAWu8DfQO+Vv4DuDu3Xg70Dlg7RXZy3AsT\n1Phq7jl3yT1+Abijre3b5Qjm7u+6ex2QZPLyoDebcPfVwIEE/Zxar97d1+XWDwNbCTBXv7t/nlvt\nSvYFl+iqlJkNBG4A5idsrbUkgc6EzKwXMN7dFwK4e6O7HwpRO+ca4D1333HGLb9cGdDDzMqB7rQx\nozV0rPdgRbvZxNkysyFkj45vBaiVMrNaoB5Y4e5vJyw5B7ifhEE9iQPLzextM7snYa2Lgb1mtjB3\nSjfXzM4L0GOLqcDzSQq4+y7gUWA7sBP41N1XtrV9sICZ2YrcOWnLsjH38cZQuzjN50rubwxm1hNY\nDPwodyRLxN2b3f0fyM79/00zuyRBb5OA3bkjrZHsjKLFWHf/Btmj4r+a2ZUJapUDo4En3H008Dkw\nPUCPmFkFcBPwYsI655M9cxpM9nSxp5l9r63tk9z84Qvc/dpQtdqQ980miiV3yrAYeMbdl4Ws7e6H\nzCwDXAdsKbDMOOAmM7sBOA/oZWb/6e53JOirPvdxj5m9RPZUfnWB5T4Cdrj7n3OPFwOh7px6PfAX\nd9+TsM41wPvuvh/AzJYCY4HnTrdxMU4RC/2t+TYw1MwG567afBdIehUs1G/xFk8BW9z98RDFzKzS\nzPrk1s8j+8N9p9B67v6guw9y94vJfv9WJQmXmXXPHbExsx5ANbApQX+7gR1mNiz3qasp/JfJqW4j\n4elhznbgH82sm2VviHY12ffbpxfqCs0Zrrz8M9n3T0fJ3onlDwXWuY7s1bk6YHrCnp4jewQ8nvum\n3Z2w3jigiezVzVpgLXBdwpojc3XWARuAhwL+TCaQ8CoicNFJz3dj0p9JruYosr9M1wFLgT4Bap4H\n7AF6BfrezciFagPwNFDR1rb6r1IiEXWkq4giHY4CJhKRAiYSkQImEpECJhKRAiYSkQImEpECJhLR\n/wGantOCZJhsswAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc8640290b8>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(long_walks[1]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 445,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAVEAAAEACAYAAAAKpEUQAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAF8RJREFUeJzt3X9w1fW95/HnOxA4mERQWmuEiQxdBLG911u9YJdeJqtF\n2drV24E72969wGrLnVpdxe66/NQQcejtnVlY6bWdlss6wCAtdelccCpWSw8CLaCiFQFTBqxREMQt\nhSUgJyfnvX8ksGkuP5J8Pt+cH3k9ZjKck5y8P+8vJ3nlc875Jm9zd0REpHvK8t2AiEgxU4iKiARQ\niIqIBFCIiogEUIiKiARQiIqIBAgOUTO7zsxeN7Odbf8eN7MHYzQnIlLoLOZ5omZWBrwPjHX396IV\nFhEpULEfzn8R2K8AFZHeInaI/kdgdeSaIiIFK9rDeTMrBw4Bo939aJSiIiIFrm/EWv8eeO1CAWpm\n+iV9ESl47m5duX3Mh/Nf4xIP5d296N/q6ury3oOOoXSOoxSOoZSOozuihKiZDaD1RaW1MeqJiBSL\nKA/n3f008MkYtUREiol+Y6mLamtr891CsFI4BiiN4yiFY4DSOY7uiHqy/UUXMvOeWktEpDvMDM/j\nC0siIr2OQlREJIBCVEQkgEJURCSAQlREJIBCVEQkgEJURCSAQlREJIBCVEQkgEJURCSAQlREJIBC\nVEQkgEJURCSAQlREJECsv2w/0Mx+amZ7zWy3mY2NUVdEpNDFGlT3JPBzd/8bM+sLXBaprohIQQve\niZpZFfBX7v40gLtn3f1EcGcF7J133iGTySS6RkNDQ7cHZ3VGLpdj3759idUHOH36NI2NjYmuIZJv\nMXaiw4GPzOxp4M+BV4GH2uYulZQ9e/bw6KOP8rOf/YzJkyczc+bM6GscPnyYxx9/nB07drBw4UJu\nv/32qPVzuRxvv/028+bNo7GxkXXr1nHNNddEXSOTybB161aeeOIJmpqa2LZtW9T6AJWVlYwcOTJ6\nXZGuCh4PYmY3AduAz7v7q2b2P4Hj7l7X4XZeV/f/31VbW1t0c1nM7Oz4gMTWSKVSZDIZcrlcYmsA\niR9HT1i2bBn33ntvvtuQIpZOp0mn0+eu19fXd3k8SIw5zZ8CDrS7/gVg/Xlu58UO8Mcee8wHDhzo\nixYtSmSNDz/80GfMmOGXXXaZp9PpRNZoaGjwSZMmeVVVlR8+fDiRNV5++WUfO3asDx8+PHrtFStW\neHl5uQ8ZMsSz2Wz0+tJ7teVUlzIwyqA6M9sETHf335lZHXCZu8/scBuPsVY+mRkHDx7kqquuom/f\nWK/JnV82m9UaFzBq1CgaGhoAeO6557jzzjuj1pfeK5+D6h4EVpnZG7Q+L7owUt2ClHTwaI2LW7Zs\nGQBjx44tuqeEpPRE+Qp3998CfxmjlsiljBs3DoCJEydSUVGR526kt9NvLImIBFCIiogEUIiKiARQ\niIqIBFCIiogEUIiKiARQiIqIBFCIiogEUIiKiARQiIqIBFCIiogEUIiKiARQiIqIBFCIiogEUIiK\niARQiIqIBIjyR5nN7PfAcSAHNLv7mBh1RUQKXaydaA6odfe/KMUAzWQyjB8/HoAJEyZw/PjxPHck\nIoUiVohaxFpBNm/ezGuvvRa1ZllZGQcOHACgsbGxR2YTyb925swZVq1axYkTJ/Ldisg5sdLAgRfM\nzIEfufvSSHU7bePGjcyePZudO3eSzWaZPn161PojRozg4MGDzJkzR3N9LuHo0aPU19eTyWSi1t27\ndy9btmzR/78UlFgjk69298Nm9kngReABd9/S4TZeV1d37nptbW3USY1mhlnrpNOkRjPX1NSwe/du\nKisrE6lfCtydESNGsH///sTWSKVSpFIpdu3axdChQxNbR0pfOp0mnU6fu15fX9/lkclRQvRPCrbO\nnf+/7r6ow/sTnTtvZjzwwAN88MEHfPrTn+a73/1uYmvJhf3yl7/k7rvvJpfL8corr3DDDTdEq/3u\nu+8yadIkvvnNbzJt2jTKy8uj1RaB7s2dD344b2aXAWXuftLMKoDbgfrQut0xePBgvve97+VjaWmz\nfPlympqaAFi9ejVPPPFEtNrXXnstr776arR6IjHEeDHoU8AWM3sd2Aasd/dfRKgrRWjJkiXnLs+a\nNSuPnYj0jOCdqLu/A9wYoRcpAYMGDQKgurpazx1Lr1AQpyWJiBQrhaiISACFqIhIAIWoiEgAhaiI\nSACFqIhIAIWoiEgAhaiISACFqIhIAIWoiEgAhaiISACFqIhIAIWoiEgAhaiISACFqIhIAIWoiEiA\naCFqZmVmttPM1sWqKSJS6GLuRB8C9kSs12ljxowBWif1/epXv8pHCyLSS0UJUTMbCnwJ+OcY9brq\n5ptvpry8nFQqxfXXX5+PFkSkl4q1E10MPAIkNxP5Ih599FFyuRxTp07l6quvzkcL0k4qlWLw4MH5\nbkOkR8QYmXwncMTd3zCzWuCCM5vnz59/7nJtbS21tbWhywOtQ9FaWloUoAUgm81y+eWX4+64O2Zd\nGuEt0qPS6TTpdDqohrmHbR7NbCHwd0AWGABUAWvdfWqH23noWpfog7q6uj8Jaul5K1eu5L777sPd\nWb9+Pbfeemu+WxLpNDPD3bv0kz/44by7z3H3GncfDnwV2NgxQKX3+M1vfkNTUxOnTp1i+/bt+W5H\nJHE6T1Si+v73vw+0PsUye/bsPHcjkrzg50Tbc/dNwKaYNUVECpl2oiIiARSiIiIBFKIiIgEUoiIi\nARSiIiIBFKIiIgEUoiIiARSiIiIBFKIiIgEUoiIiARSiIiIBFKIiIgEUoiIiARSiIiIBFKIiIgFi\nzFjqD7wM9Gur96y714fWFREpBsEh6u5nzOzfufspM+sDbDWz5919R4T+OuXQoUMAHDhwgJaWFvr0\n6dNTS4tILxfl4by7n2q72J/WYO7R0cm33XYb0DokbcOGDT25tIj0clFC1MzKzOx14DDworu/EqNu\nZ02ZMoV+/fpx+eWXRxvDLCLSGbF2ojl3/wtgKDDWzEbHqNtZDz74IGbGfffdR0VFRU8uLedRU1PD\n8OHD892GSI+IPajuhJmlgYnAno4fbz8Tvra2NtqusbKykjNnztC/f/8o9aT7Tp48yR/+8Aey2SzZ\nbJa+faN+iYlElU6nSafTQTVivDr/CaDZ3Y+b2QDgi8A/nO+27UM0CWaWaH25tCVLlnDmzBk++ugj\nVq9ezZQpU/LdksgFddzM1dd3/cSiGNuEamC5mZXR+vTAT9z95xHqShHq168fzc3NgH6oSe9g7j3z\nQrqZeZJrmRl1dXWJ73bl0syM6urqc6eeiRQLM8Pdu/TTX7+xJCISQCEqIhJAISoiEkAhKiISQCEq\nIhJAISoiEkAhKiISQCEqIhJAISoiEkAhKiISQCEqIhJAISoiEkAhKiISQCEqIhJAISoiEkAhKiIS\nIDhEzWyomW00sz1mtsvMHozRmIhIMYixE80C33b30cDngfvNbFSEup22detWADZs2EBTU1NPLi0i\nvVxwiLr7YXd/o+3ySWAvMCS0bld8/etfB2D79u3Bk/vOJ5vNRq/ZWyT9f5fL5cjlcomu0RP3v9Yo\nXlGfEzWzYcCNwPaYdS9l7ty5lJeXM2TIECZOnBi19po1a7jiiiuYP38+J06ciFq7lGUyGW655RZG\njhyZSP1cLsdPfvIThg8fzuTJkxNZ4/Tp0yxatIhPfOITLFq0KJE1jh49yowZMxg4cCCbNm1KZI2G\nhgYmTZrElVdeyZEjRxJZY/PmzYne34Us2qA6M6sE0sACd/+X83w8sUF12WyWmpoaPvjgg0TqA5SV\nlZFKpfjwww+pqKhIbJ1SMH78eDZv3pzvNqJoG1yWWP1UKkUmk0l8N530cfSEDRs2cMcddyS6RncG\n1UUJUTPrCzwHPO/uT17gNl5XV3fuesd5z6FOnDjBvn37otU7a+XKlTz55JNMmDCBF198kYMHD3LN\nNddEX6eUnDx5kh/+8IcsWLCApqYmtm3bFn2N5uZm1qxZw1NPPcWwYcN45plnoq/R1NTEkiVLWLt2\nLZMnT2bmzJnR1zh8+DALFixg+/btLFy4kNtvvz1q/VwuR0NDA/PmzePdd99l3bp10b9+M5kMv/71\nrxO7v3fs2MH999/PjTfeyGuvvRZ1FHc6nf6TpwDr6+vzFqIrgI/c/dsXuU2iI5OT0tLSwoEDBxgx\nYgRmphDtgtOnT3P06FFqamoSW+Po0aP06dOHK6+8MrE13nnnHYYMGUK/fv0SW6OhoYHrrrsuakC0\nl8vl2L9/PyNGjEikPiR3f990003s3LkTM2Pjxo1RN18d5WUnambjgJeBXYC3vc1x9w0dbleUIdqe\nQlSk5/3gBz/gW9/6FldccQW7d++muro6sbXy9nC+UwspREWkm8yMuro65s+fn/g6XQ1R/caSiEgA\nhaiISACFqIhIAIWoiEgAhaiISACFqIhIAIWoiEgAhaiISACFqIhIAIWoiEgAhaiISACFqIhIAIWo\niEgAhaiISACFqIhIAIWoiEiAKCFqZsvM7IiZvRmjnohIsYi1E30aSHYMXx65O7NmzQJg1qxZNDc3\n57kjESkUUULU3bcAx2LUKkQff/wxTz31FACrV6/m2LGSPdSC19DQkOjo35aWlkSmxkrp6pvvBorB\ngAEDmD17NnPnzmX69OlcddVV+W6poGWzWX77299Gr/vGG2/wjW98g9GjR/P4448zbNiw6Gu0H5G9\ncOFCbr755uhrSGmJNqjOzK4F1rv7n13g44nOnU/ayZMnqaqqYu/evYwaNSrf7RS02tpaNm3alFj9\nsrIyzIyWlpZE18jlchw7doxBgwYlto5cWjabpbq6mocffpg5c+ZErR1j7jzuHuUNuBZ48yIf92IH\n+MGDB/PdRkHbtWuXp1IpT6VSfujQoai1d+/e7RUVFX7PPfd4Y2Nj1NpnrVmzxisrK33+/Pm6vwvE\nihUrvLy83IcMGeLZbDbRtdpyqmvZ19VPuGAhGAbsusjHEz34nqBvqkubMmWKAw74vHnzotdvbm6O\nXvNCa+j+LgwjR4489zX13HPPJbpWd0I01ilOzwC/Bq4zs0YzuydGXSk+7R9uTZ8+PXr9vn2Tfxq/\nJ9aQzlu2bBkAY8eOLcinAKN8tbj738aoI8Xv7PPF1dXV1NTU5LkbKQXjxo0DYOLEiVRUVOS5m39N\nv7EkIhJAISoiEkAhKiISQCEqIhJAISoiEkAhKiISQCEqIhJAISoiEkAhKiISQCEqIhJAISoiEkAh\nKiISQCEqIhJAISoiEkAhKiISQCEqIhIg1l+2n2hmb5vZ78xsZoyaIiLFIDhEzawM+CfgDuAG4Gtm\nVlLjMDOZDOPHjwdgwoQJHD9+PM8dSZJ0f0tXxNiJjgH2ufu77t4M/Bi4O0LdglFWVsaBAwcAaGxs\njD6D5+2332bDhg1nB/olYtOmTbz++uuJ1Xd31q5dy3vvvZfYGj2lFO7vUnDmzBlWrVrFiRMn8t3K\nRcX46hgCtP/OeZ/WYC0Zffv25Tvf+Q5Tp07l+uuv5+GHH45af+nSpZSVlTFq1Ci+/OUvc+zYsaj1\nz65RXl7O+PHjGT16NB9//HHU+plMhuXLl5NKpQDo169f1Po9qSfv74ULF3L33cW95zh69Cj19fVk\nMpmodffu3cuWLVsKcq5Sexb609DMJgO3u/vft13/O+Av3f2hDrfzurq6c9dra2sLcnLfhWSzWcaM\nGZPobs7MqKio4OTJk4nU79OnD+5OLpdLpD5A//79AVi9ejVf+cpXElsnadlslrFjx7Jz587E1jCz\n9iPFi5K7M2LECPbv35/YGqlUilQqxa5duxg6dGjU2ul0mnQ6fe56fX097m5dKtLVGcsd34BbgA3t\nrs8CZp7ndtFnRJeKxYsX+4QJE3znzp2JrTFt2jS/5557vLGxMZH6zc3N/oUvfMHr6ur8j3/8YyJr\nlIqz9/fixYu92L8vXnrpJa+oqPABAwb4W2+9FbX273//e7/pppt86dKlnslkota+ELoxdz7GTrQP\n0ADcBnwA7AC+5u57O9zOQ9cSKSXr16/nrrvuKuqd6NSpU1m5ciUAc+fO5YknnshzR2HaHh10aSca\n/MKSu7cADwC/AHYDP+4YoCJSmpYsWXLu8qxZs/LYSf5EednR3TcAI2PUEpHiMWjQIACqq6uprKzM\nczf5od9YEhEJoBAVEQmgEBURCaAQFREJoBAVEQmgEBURCaAQFREJoBAVEQmgEBURCaAQFREJoBAV\nEQmgEBURCaAQFREJoBAVEQmgEBURCaAQFREJEBSiZjbZzN4ysxYz+1yspkREikXoTnQX8BVgU4Re\nRHqNPXv2cNdddwEwbNiwop6z1NsFhai7N7j7PqBrI0ZFermamhqqqqowMz772c9iFvdbaPHixSxd\nupTm5uaodc/K5XI88sgjPP/884nULybB0z4BzOxXwH919wsO6da0T5E/tWDBAh577LHE6vfv35+q\nqioGDx5MQ0NDImtUVFRw6tQpPvOZz/Dmm28mskZP6s60z0sOqjOzF4FPtX8X4MBcd1/flcXmz59/\n7nJtbS21tbVd+XSRkjJjxgy2bt3KCy+8kO9WggwfPpwVK1bku41uSafTpNPpoBraiYqUoMWLF1NV\nVcW0adMoLy+PXj+XyzFz5kxuu+027rjjjuhPR+RLd3aiMUP0v7n7axe5jUJURApad0I09BSnvzaz\n94BbgOfMTM8yi0ivEmUn2qmFtBMVkQLX4ztREZHeTiEqIhJAISoiEkAhKiISQCEqIhJAISoiEkAh\nKiISQCEqIhJAISoiEkAhKiISQCEqIhJAISoiEkAhKiISQCEqIhJAISoiEiD0jzL/o5ntNbM3zOx/\nm9nlsRoTESkGoTvRXwA3uPuNwD5gdnhLhS10qFUhKIVjgNI4jlI4Biid4+iO0LnzL7l7ru3qNmBo\neEuFrRS+WErhGKA0jqMUjgFK5zi6I+ZzovcCmrEkIr1KlLnzZjYXaHb3ZxLpUkSkQAUPqjOzacDf\nA7e6+5mL3E5T6kSk4HV1UN0ld6IXY2YTgf8OjL9YgHanMRGRYhC0EzWzfUA/4P+0vWubu38rRmMi\nIsWgx+bOi4iUoh79jaViPjnfzCaa2dtm9jszm5nvfrrDzIaa2UYz22Nmu8zswXz31F1mVmZmO81s\nXb576S4zG2hmP237nthtZmPz3VNXmdnDZvaWmb1pZqvMrF++e+oMM1tmZkfM7M1277vCzH5hZg1m\n9oKZDexMrZ7+tc+iPDnfzMqAfwLuAG4AvmZmo/LbVbdkgW+7+2jg88D9RXocAA8Be/LdRKAngZ+7\n+/XAnwN789xPl5jZNcB/AT7n7n9G62ssX81vV532NK3fz+3NAl5y95HARjqZTz0aokV8cv4YYJ+7\nv+vuzcCPgbvz3FOXufthd3+j7fJJWr9ph+S3q64zs6HAl4B/zncv3WVmVcBfufvTAO6edfcTeW6r\nO/oAFWbWF7gMOJTnfjrF3bcAxzq8+25gedvl5cBfd6ZWPv8ASTGdnD8EeK/d9fcpwvBpz8yGATcC\n2/PbSbcsBh6h9XzlYjUc+MjMnm57WuJHZjYg3011hbsfAv4H0AgcBP7o7i/lt6sgV7n7EWjdcACf\n7MwnRQ9RM3ux7fmRs2+72v79D+1uU2wn55/v9Kyi/QY2s0rgWeChth1p0TCzO4EjbTtq4/z3TTHo\nC3wOeMrdPwecovXhZNEws0G07t6uBa4BKs3sb/PbVc8LOk/0fNx9wsU+3nZy/peAW2OvnaD3gZp2\n14dSJA9bOmp72PUssNLd/yXf/XTDOOAuM/sSMACoMrMV7j41z3111fvAe+7+atv1Z4Fie8Hyi8AB\nd/8DgJmtBf4tUCybo46OmNmn3P2ImV0NfNiZT+rpV+fPnpx/16VOzi8wrwD/xsyubXv18atAsb4q\n/L+APe7+ZL4b6Q53n+PuNe4+nNb7YWMRBihtDxvfM7Pr2t51G8X3QlkjcIuZpczMaD2GYnpxrOMj\nmXXAf267PA3o1CYj+k70Er5H68n5L7b+nxfHyfnu3mJmD9B6dkEZsMzdi+mLBQAzGwf8J2CXmb1O\n61MSc9x9Q34767UeBFaZWTlwALgnz/10ibvvMLNngdeB5rZ/f5TfrjrHzJ4BaoHBZtYI1AH/APzU\nzO6l9QfE33Sqlk62FxHpPo0HEREJoBAVEQmgEBURCaAQFREJoBAVEQmgEBURCaAQFREJoBAVEQnw\n/wDymFXfd/I9VwAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85eddf7b8>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(long_walks[2]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 446,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85ef41048>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(long_walks[3]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 447,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nB7ykpMQTiYTPmDEjWOZXvvIVf/XVV72xsTFI5ukAv+qqq3zatGn+s5/9LGj28ePHfcGCBf7tb387\naG5Mu3fv9rvuussXL16c7aW0GW2Y0tTqHqslZjYGmAvc7O5/bmVbz+S6TldXV3dq0unEiRN5+umn\ng2XHZGYMGjSItWvXZnspcpbMrNU9VqZHBR8DSoClZrbazH6UYV6bXXrppfzwhz8EyJlSyUdHRgcv\n3P2ToRYi0pXonRciEahYIhGoWCIRqFgiEahYIhGoWCIRqFgiEahYIhGoWCIRqFgiEahYIhGoWCIR\nqFgiEahYIhGoWB3oz39OfRZ006ZNHDlyJMurkZi6TLGOHz/e6XNPfjDzyJEj/OIXvwiWK51PyClN\nWTNixAjWrl3L1q1bMWt5xkdb7du3j4ceeoh58+axaNEibrrppowzJ0yYwCOPPEJhYSHjxo0LsErp\nrHK6WEOHDsXMSCaTuDslJSVRrmf06NFB8+699166d+8eNFM6l5x+KDh06FBqa2sZN24cvXr1orGx\nMeOpUydP+/fvZ+bMmfTs2ZM33ngjWK67U1lZme2bTiLLaEpTu64o8JSm07l7sIeBHZEruasjpjR1\nGrHu/CqVnI0uUyyRzkTFEolAxRKJQMUSiUDFEolAxRKJQMUSiUDFEolAxRKJQMUSiUDFEolAxRKJ\nQMUSiUDFEokgSLHMbKqZNZrZBSHyRHJdxsUys97AKGBr5stpv2QymXPZuZYbMzvXctsqxB7rP4B7\nAuScFd2Z4ufGzM613LbKqFhm9lmgzt3fDrQekS6h1SlNZrYU+FjTLwEOzATuA0af9nciH3lnPUzG\nzP4OeBWoJ1Wo3sD7wBB3393M9h0ztUakA7Q2TCbYlCYz+z+gzN33BwkUyWEhX8dy9FBQBOjAuYIi\nHyUd+s4LM3vQzNabWY2ZPW9m5wXKHW9mtWZ2wszKAuSNMbMNZrbJzKaHWGM697/MbJeZrQ2Vmc7t\nbWZVZvaOmb1tZpMD5XYzsxVmVp3OvT9EbpP8PDNbbWa/DJy7xczWpNf9+4C5Pczs5+n78Dozu/6M\nG4ccndzaidQLyXnp83OAfw+U2x/4JFBF6nleJll5wLtAHyAfqAEGBFrnMOAaYG3g2/Vi4Jr0+RJg\nY8A1F6f/PAf4HamDU6HWfRewAPhl4NvjT8D5ITPTufOBSenzCeC8M23boXssd3/V3RvTF39H6khi\niNyN7r6ZMM/xhgCb3X2rux8DngU+HyAXd18OBD+44+473b0mff4gsB7oFSi7Pn22G6k7U5DnDul3\n7IwFngqRd3o8gR+Nmdm5wHB3fxrA3Y+7+4dn2j6bb8K9E1iSxes/k15AXZPL7xHoTtoRzOwTpPaK\nKwLl5ZlZNbATWOruK0Pk8pd37MR4ku/AK2a20sz+OVDm5cBeM3s6/fD1STMrOtPGwYtlZkvNbG2T\n09vpPz/bZJsZwDF3XxgyN9Q/oZmv5cQRHjMrAZ4DvpXec2XM3Rvd/VpSjy6uN7OrMs00s9uAXem9\nrBH+aPJN7j6Y1B7xX8xsWIDMBFAGPO7uZaRev/1OSxsH5e4t/mdSZvZlUv/gESFzA3oPuKzJ5d7A\n9g667rNmZglSpfqxuy8Kne/uH5pZEhgDvJNh3FDgc2Y2FigCzjWzZ9z9jgxzgdRD4/Sfe8zsf0k9\nvF+eYex7pN6+94f05eeAMx7Y6uijgmOAacDn3D3Wf8Kb6W+/lcCVZtbHzAqALwIhj1rF+A0N8N/A\nO+7+SKhAM7vQzHqkzxeROvi0IdNcd7/P3S9z98tJ3b5VoUplZsXpPTdm1h24FajNNNfddwF1ZtYv\n/aWRtPQLJvSRk1aOqmwm9fGS1enTjwLl/gOp50WHgR3AkgzzxpA6srYZ+E7Af/9CUnu/I8A20keY\nAuQOBU6QOoJZnb5txwTIHZTOqgHWAjMi3CduIeBRQaBvk9vh7cA/v6tJ/eKtAV4AepxpW71ALBKB\nPpovEoGKJRKBiiUSgYolEoGKJRKBiiUSgYolEoGKJRLB/wNUGFdJtvbjXgAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85ef240f0>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(long_walks[4]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 448,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nP9UhVhMVdx/Z2DFNlVQTFUg1yJwxYwazZs2id+/ePPfcc9FqAzz11FM8/vjjPPjggzz++ONRa9dZ\nv349hw4d4sILL2TFihU89NBDXH755VHHqK2tpaKigvvuu4+tW7cyd+7cqO3D9uzZw5gxY5g5cyaT\nJ0+mXbt20WrXKSgoYNOmTWzevDl67Tlz5vDYY48xfPhwpkyZQpcuXaKPUVZWxmuvvcbQoUNZvHhx\n9Pqn2kQl7fZq/peVwaBGjkk4/1I+/PBD37t3b9Sa+/fv9/bt2zvgBQUFibVYmzt3bl2K+6ZNm7y2\ntjaRcdzda2pq/O23345ed+LEiW5mnpeX5w8//HD0+kk7cuRIIvdLffv27fPt27f/n8c7STRxZZDu\nR4tfMbPtwJeA+WaW9e6k3bp1o2vXrlFrFhYWMnHiRADGjx+fyG+LY5133nmYJfe+bF5eHueee270\nuldeeSXuTm1tLZdeemn0+knLz89P5H6pr3379vTq1SvRMU5F2u3VmjxQgu3VMsXMqKysTKwr77x5\n8xgzZgwt4X7q0aMHO3cet+WmBJl6vJvaXq1FfZogIqdOYSAigMJARAKFgYgACgMRCRQGIgIoDEQk\nUBiICKAwEJFAYSAigMJARAKFgYgACgMRCRQGIgIoDEQkUBiICJB+E5UZZvaWma0xs/8ys46xJiYi\nmZXuyuDXQH93vwDYDPxz+lM6Pe3bt48HHngAgOnTp2d5NpK0XHy8022issjd6zqW/AHIvY3dErBl\nyxYOHz4ctWZlZSVvvPEGALNmzWr2W5/JieXi493oVukn4R+A5yPWy0m33XYbCxcuZNy4cdx9991R\na19yySUsX76c6dOnJ7oZqmRf3759GT16NK+88krOPN6NbohqZq8Cf1X/j0g1gLjX3eeFY+4l1URl\n7AnqeHl5+dHLsfsmZEKXLl349NNPE03xkpIS3n33XQoKYuZ0ZpWWltKzZ09efvnlbE8lp7344ouM\nHTuW6urqqI/3sX0Tpk2b1qQNUWP0TLgFWA60aeS42NvBZ9z+/fv9kUce8U6dOvnMmTOzPZ2ctH79\nei8sLPTCwkLfuXNntqeT01pa34RRwBRgjLsfSqdWc1BUVMRdd93Fnj17KCsry/Z0ctKMGTM4ePAg\nBw8eTKzzlCQj3U8T/hVoD7xqZqvM7LR49JvzEj5p99xzz9Hzt99+exZnIicrrX/V7p5s6xlpdvr2\n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\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc87c3185c0>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(long_walks[5]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 449,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85ec78198>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(long_walks[6]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 450,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nydeYPn06L774IqNHj2bJkiXJ6+eid955hzvvvJMHHniAgQMHMnfu3ORrfPzxx9x///08/fTTTJw4\nMfn44/LycpYtW8Zjjz3Gd77znaS1o7Uc7taWFBMkTwTq3H23mRUBzwE/dfeFLbYLHe4WpaGhgY0b\nN/KlL30pbI19+/axa9cuVqxYwfjx40N/c+aaHTt2kJ+fT9++fcPW2LRpEyUlJXTt2jVZzbVr11JW\nVoa7U1JSwpYtW0Ink0Zr60gmxXsyJwN/MLOVwMvAcy0DpjPLz88PDRhoOvQfMGBA6Bq5qri4ODRg\nAE455ZSkAQNQUlLCiBEjALj++us7dcAcTtL3ZNpcqJMeybSn+fPn60jmOJJLj3f0kYyIyCEpZEQk\nlEJGREIpZEQklEJGREIpZEQklEJGREIpZEQklEJGREIpZEQklEJGREIpZEQklEJGREIpZEQklEJG\nREIpZEQkVMYhY2YDzOz3ZlZtZqvN7IYUjYlIbkhxJFMP/MDdy4CvAdeb2ZAEdY8re/fu5Y477gBg\n9uzZWe5GJJ0UEyS3u/vK5uv7gDVASaZ1O7JNmzaxf//+pDVramp49dVXAXjggQdy4pSMcuTWrVuX\ns4950pEoZjaQplG1L6es21FUV1dz2223MW/evJARGeeffz7Lli1j9uzZOX1iaflr55xzDq+88gqz\nZs3i4osvTl6/rKyMoqKi5HWPVLITiZtZT2ApcIe7P9PK/V5RUXHgdsq5S+3FzDTsS5J59913GTJk\nCHV1daGjdk877TTeeuutpL+4Ws5dmjlz5iFPJI67Z3yh6YhoMTCtjW28swP89ttv9969e3tVVVW2\n25Ec8MEHH3h5ebl3797dly5dmrT23r17vVevXl5YWOhLlixJWrul5ud3q8/9JEcyZvafwE53/0Eb\n23iKtbLJzKipqaFfv3460pCk6uvrk/+b+sUvfsF1110HwEUXXRQ6nbStkSgpJkieD/wJWA148+UW\nd1/cYrucCZn+/ftnuxWRw9qxYwennnoqe/bs4bXXXuOss84KWys0ZI6iCYWMSDu7/PLLWbBgQfgn\nVxruJiJZo5ARkVAKGREJpZARkVAKGREJpZARkVAKGREJpZARkVAKGREJpZARkVAKGREJpZARkVAK\nGREJpZARkVAKGREJpZARkVBJQsbMfmVm75vZqhT1RCR3pDqSeQT4RqJaHc7+/fsZNWoUAGPHjmX3\n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\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85f006a90>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(long_walks[7]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 451,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nAElFTkSuQmCC\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85efd7208>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(long_walks[8]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 416,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['RFLRFFRFFFFRLRFRFFRLLFFFFFRRLRRL',\n",
+ " 'FFFFRFRLRLFRLRLRFRRLLFFRFRLFLRRFLRRL',\n",
+ " 'RLLRLFFFRFFLLRRLLFRLLRRFLLRRLLFFFFLRFLRF',\n",
+ " 'FFLRRLFRLFLFFFFLLRFRLFFFFLLRLRRL',\n",
+ " 'FLFRFLFRFFFLFRLFRLLFFLRRFLRLLFRLRLRRLLFFFRFLFLRLRL',\n",
+ " 'LRFRLRFLFFFFFRRFLRLRFRLRLFRLFFRRLR',\n",
+ " 'LRFLFLRLRRFLFFRRFFFLFRFFLRFRFLLRFFRRLLRFFRLRRFFLLRLR',\n",
+ " 'LFRLFFFRLLRLLFFRRLLRLFFFLRRLLFFL',\n",
+ " 'FLRFFLFFRLFRLLFRLLFFFRLFRRLFLFFL',\n",
+ " 'LLRFRLRRLRLFRFFFFRLRFFLRFFRLRRLFRFFL']"
+ ]
+ },
+ "execution_count": 416,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "walks"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 452,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n8v89qQ80wuYWhQAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85eaed1d0>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour('FLFFLRFRLFRRRR'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 582,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(408, [8, 16, 20])"
+ ]
+ },
+ "execution_count": 582,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "w = random_walk()\n",
+ "ms = mistake_positions(w)\n",
+ "len(ms), returns_to_origin(ms)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 583,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nCYIgIoz/D/EoAGQ0K3jsAAAAAElFTkSuQmCC\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85ce54208>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(w))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 488,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "walks_m = {i: list() for i in range(4)}\n",
+ "while all(len(w_m) < 10 for w_m in walks_m.values()):\n",
+ " w = random_walk()\n",
+ " ps = mistake_positions(w)\n",
+ " if not ps or ps[0][0] > 30:\n",
+ " walks_m[0] += [w[:ps[0][0]]]\n",
+ " if len(ps) >= 2\n",
+ " \n",
+ " if len(w) > 30: \n",
+ " walks_m[i] += [w]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 489,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{0: ['LRLRLRLFRFLFFLRFRRLRLFLLRFLRRLLFFFLRLRLLRLF',\n",
+ " 'FFRLLFFFFRFLRFRLLRFFRFFFFFFLLRRLRRFFR',\n",
+ " 'LFRRFLLRFFLFRLRFLRRLLFRRFLFLRRFFLFFLRFFLFFLFLFRRR',\n",
+ " 'FLFLFFLRRFFFFLFRFFLFRFFLFFRLFRRR',\n",
+ " 'LLFLLRFFRLLFRFLFRLRFFRFFLFFLRLFRLLFLFF',\n",
+ " 'RFRRLRLLRRFLFFRRLRFFFLFRRLFLFLRRR',\n",
+ " 'FFLFFRFLFLRLFFLLFRRFFFRLLFFFRFFRRR',\n",
+ " 'LRRLFRFLRFFFFRLLRLRFLRFLLRRFRLLRFRLFLFLRRR',\n",
+ " 'LRLFLRRFLFRRLRFRFLFLRLLFRRFFRLRFLLFL',\n",
+ " 'RLRRLFLFRRLLFFRFRFLFFLRLFLRLRFLLFRFFFLRRFRFLFFRFLFRLFFRRR'],\n",
+ " 1: ['RRFLRRLLFLRLRRLFRLFFFRLLFRFLFRRLLLL',\n",
+ " 'LRLFFLRRFLLRLRRLLRLRFLRLFFLLLFLRRR',\n",
+ " 'RFRRLFRLRLRRFLLRFLFFLRRFLRRFRRL',\n",
+ " 'FFFRFLFRLFFLFLLLFLFFLRFFRFFFRRLRRLF',\n",
+ " 'FLFRFFRLLRFRLLRFFRFLFLFLRFFFLRRLLLF',\n",
+ " 'FRRLRLLFRFLRFRLRRFRFFFLRFFRLRFFLLFRFLRFFRLFRRLLL',\n",
+ " 'FFLRLRFLFLRRFFLFFRRRFRLFLFRRLLFRFRLLFFLLF',\n",
+ " 'FLRRFLRLFFFFRFLFLLLFFRFLFRLLFRRLLL',\n",
+ " 'RFFFRFLLRFFRFFFRRRFLRLFRFFLRLLFLF',\n",
+ " 'FFRFLFLLRRLRLFFRLFFLFRLFLRFFLLFFLF'],\n",
+ " 2: ['FFLRFRFRLFRFFFFLRFRLRFRLFLLLRLFLRLFLLRLR',\n",
+ " 'FFLFRLLRLRRFFRLFLRFFFFRLFLRFFLLLFRFLFRRLR',\n",
+ " 'RRLFRRFFFLLRFFLFFLFFLFLRFRLLRFFLFFLFRLLFRF',\n",
+ " 'FFRFLRLLRRFFRRLFFFFFFLLLFRFLFRFL',\n",
+ " 'FFRFFFLFLFRLRFRRLRLLFFLLLFLRFLRFLLLL',\n",
+ " 'FFFFFFFFFFFFFFLLFLFLFRLRFFLRFFRFLFRFLFRRLLRLRLRLFRFLFLLLL',\n",
+ " 'LFFRFFRFFFFRFRLFFRLFRLFFLLRFRLLFLRFLRRLLFR',\n",
+ " 'FRFRLRLLFFRFFLRFLRFRFLLFLRLFFLLL',\n",
+ " 'LRLLLLRFLRRFFLFRFRFFLFLLRRLFRLFRLFLFFFFFFRFRFLFRLFFLRFFLRFRRLLRFFRRLRRL',\n",
+ " 'FLRFLRLLRLRFRLRLLRFLFFLRLRLFRRRLLFLFFRFLLRLLRFLRLFRFLFRRR']}"
+ ]
+ },
+ "execution_count": 489,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "walks_m"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 490,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nTwAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x7fc85eae9c88>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_trace(trace_tour(walks_m[0][0]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "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.5.2+"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
+++ /dev/null
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import unicodedata\n",
- "import string"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "unaccent_specials = ''.maketrans({\"’\": \"'\", '“': '\"', '”': '\"'})"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def unaccent(text):\n",
- " translated_text = text.translate(unaccent_specials)\n",
- " return unicodedata.normalize('NFKD', translated_text).\\\n",
- " encode('ascii', 'ignore').\\\n",
- " decode('utf-8')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def only_lower(text):\n",
- " return all((c in string.ascii_lowercase) for c in text)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "/usr/share/dict/british-english\n",
- "find: ‘/usr/share/doc/google-chrome-stable’: Permission denied\n",
- "/usr/share/man/man5/british-english.5.gz\n"
- ]
- }
- ],
- "source": [
- "# !find /usr -type f -iname 'british-english*'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "total 2.3M\r\n",
- "drwxr-xr-x 2 root root 4.0K Dec 29 12:37 .\r\n",
- "drwxr-xr-x 640 root root 20K Apr 13 17:05 ..\r\n",
- "-rw-r--r-- 1 root root 917K Oct 23 2011 american-english\r\n",
- "-rw-r--r-- 1 root root 917K Oct 23 2011 british-english\r\n",
- "-rw-r--r-- 1 root root 467K Aug 25 2016 cracklib-small\r\n",
- "-rw-r--r-- 1 root root 199 Aug 29 2016 README.select-wordlist\r\n",
- "lrwxrwxrwx 1 root root 30 Nov 10 2014 words -> /etc/dictionaries-common/words\r\n",
- "lrwxrwxrwx 1 root root 16 Jun 18 2014 words.pre-dictionaries-common -> american-english\r\n"
- ]
- }
- ],
- "source": [
- "# !ls -lah /usr/share/dict"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def rude(word):\n",
- " return any(w in word \n",
- " for w in 'piss shit cunt fuck arse crap fart jizz whore bitch'.split())"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 18,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "rude('fucks')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def words_with_len(n):\n",
- " return [unaccent(w.strip()) for w in open('/usr/share/dict/british-english').readlines()\n",
- " if only_lower(unaccent(w.strip()))\n",
- " if len(unaccent(w.strip())) == n\n",
- " if not rude(unaccent(w.strip()))]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "2336 4-letter words\n",
- "4566 5-letter words\n",
- "7223 6-letter words\n"
- ]
- }
- ],
- "source": [
- "dicts = {}\n",
- "\n",
- "for n in [4, 5, 6]:\n",
- " dicts[n] = words_with_len(n)\n",
- " print('{} {}-letter words'.format(len(dicts[n]), n))\n",
- " with open('words{}.txt'.format(n), 'w') as f:\n",
- " f.write('\\n'.join(sorted(set(dicts[n]))))\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "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.5.2+"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
+++ /dev/null
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import string\n",
- "import heapq\n",
- "import collections\n",
- "import random"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "2336"
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "words = [w.strip() for w in open('words4.txt').readlines()]\n",
- "len(words)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['abbe',\n",
- " 'abed',\n",
- " 'abet',\n",
- " 'able',\n",
- " 'ably',\n",
- " 'abut',\n",
- " 'aced',\n",
- " 'aces',\n",
- " 'ache',\n",
- " 'achy']"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "words[:10]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def adjacents_explicit(word):\n",
- " neighbours = []\n",
- " for i in range(len(word)):\n",
- " for l in string.ascii_lowercase:\n",
- " if l != word[i]:\n",
- " neighbours.append(word[0:i] + l + word[i+1:])\n",
- " return neighbours"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def adjacents(word):\n",
- " return [word[0:i] + l + word[i+1:]\n",
- " for i in range(len(word))\n",
- " for l in string.ascii_lowercase\n",
- " if l != word[i]]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "neighbours = {w: [n for n in adjacents(w) if n in words]\n",
- " for w in words}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['able']"
- ]
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "neighbours['abbe']"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['axle', 'abbe', 'ably']"
- ]
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "neighbours['able']"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def distance(w1, w2):\n",
- " return sum(1 for i in range(len(w1))\n",
- " if w1[i] != w2[i])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "0"
- ]
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "distance('abbe', 'abbe')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def extend(chain, closed=None):\n",
- " if closed:\n",
- " nbrs = set(neighbours[chain[-1]]) - closed\n",
- " else:\n",
- " nbrs = neighbours[chain[-1]]\n",
- " return [chain + [s] for s in nbrs\n",
- " if s not in chain]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[['abbe', 'able']]"
- ]
- },
- "execution_count": 12,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "extend(['abbe'])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[['abbe', 'able', 'axle'], ['abbe', 'able', 'ably']]"
- ]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "extend(['abbe', 'able'])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[['abbe', 'able', 'ably', 'ally']]"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "extend(['abbe', 'able', 'ably'])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def bfs_search(start, goal, debug=False):\n",
- " agenda = [[start]]\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " current = agenda[0]\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " successors = extend(current)\n",
- " agenda = agenda[1:] + successors\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def bfs_search_closed(start, goal, debug=False):\n",
- " agenda = [[start]]\n",
- " closed = set()\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " current = agenda[0]\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " closed.add(current[-1])\n",
- " successors = extend(current, closed)\n",
- " agenda = agenda[1:] + successors\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "['abbe']\n",
- "['abbe', 'able']\n",
- "['abbe', 'able', 'axle']\n",
- "['abbe', 'able', 'ably']\n",
- "['abbe', 'able', 'ably', 'ally']\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "['abbe', 'able', 'ably', 'ally']"
- ]
- },
- "execution_count": 17,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "bfs_search('abbe', 'ally', debug=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def dfs_search(start, goal, debug=False):\n",
- " agenda = [[start]]\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " current = agenda[0]\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " successors = extend(current)\n",
- " agenda = successors + agenda[1:]\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "['abbe']\n",
- "['abbe', 'able']\n",
- "['abbe', 'able', 'axle']\n",
- "['abbe', 'able', 'ably']\n",
- "['abbe', 'able', 'ably', 'ally']\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "['abbe', 'able', 'ably', 'ally']"
- ]
- },
- "execution_count": 19,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dfs_search('abbe', 'ally', debug=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "['cart']\n",
- "['cart', 'dart']\n",
- "['cart', 'hart']\n",
- "['cart', 'mart']\n",
- "['cart', 'part']\n",
- "['cart', 'tart']\n",
- "['cart', 'wart']\n",
- "['cart', 'curt']\n",
- "['cart', 'cant']\n",
- "['cart', 'cast']\n",
- "['cart', 'card']\n",
- "['cart', 'care']\n",
- "['cart', 'carp']\n",
- "['cart', 'cars']\n",
- "['cart', 'dart', 'hart']\n",
- "['cart', 'dart', 'mart']\n",
- "['cart', 'dart', 'part']\n",
- "['cart', 'dart', 'tart']\n",
- "['cart', 'dart', 'wart']\n",
- "['cart', 'dart', 'dirt']\n",
- "['cart', 'dart', 'daft']\n",
- "['cart', 'dart', 'dare']\n",
- "['cart', 'dart', 'dark']\n",
- "['cart', 'dart', 'darn']\n",
- "['cart', 'hart', 'dart']\n",
- "['cart', 'hart', 'mart']\n",
- "['cart', 'hart', 'part']\n",
- "['cart', 'hart', 'tart']\n",
- "['cart', 'hart', 'wart']\n",
- "['cart', 'hart', 'hurt']\n",
- "['cart', 'hart', 'haft']\n",
- "['cart', 'hart', 'halt']\n",
- "['cart', 'hart', 'hard']\n",
- "['cart', 'hart', 'hare']\n",
- "['cart', 'hart', 'hark']\n",
- "['cart', 'hart', 'harm']\n",
- "['cart', 'hart', 'harp']\n",
- "['cart', 'mart', 'dart']\n",
- "['cart', 'mart', 'hart']\n",
- "['cart', 'mart', 'part']\n",
- "['cart', 'mart', 'tart']\n",
- "['cart', 'mart', 'wart']\n",
- "['cart', 'mart', 'malt']\n",
- "['cart', 'mart', 'mast']\n",
- "['cart', 'mart', 'matt']\n",
- "['cart', 'mart', 'mare']\n",
- "['cart', 'mart', 'mark']\n",
- "['cart', 'mart', 'mars']\n",
- "['cart', 'part', 'dart']\n",
- "['cart', 'part', 'hart']\n",
- "['cart', 'part', 'mart']\n",
- "['cart', 'part', 'tart']\n",
- "['cart', 'part', 'wart']\n",
- "['cart', 'part', 'pert']\n",
- "['cart', 'part', 'port']\n",
- "['cart', 'part', 'pact']\n",
- "['cart', 'part', 'pant']\n",
- "['cart', 'part', 'past']\n",
- "['cart', 'part', 'pare']\n",
- "['cart', 'part', 'park']\n",
- "['cart', 'part', 'pars']\n",
- "['cart', 'tart', 'dart']\n",
- "['cart', 'tart', 'hart']\n",
- "['cart', 'tart', 'mart']\n",
- "['cart', 'tart', 'part']\n",
- "['cart', 'tart', 'wart']\n",
- "['cart', 'tart', 'tort']\n",
- "['cart', 'tart', 'tact']\n",
- "['cart', 'tart', 'taut']\n",
- "['cart', 'tart', 'tare']\n",
- "['cart', 'tart', 'taro']\n",
- "['cart', 'tart', 'tarp']\n",
- "['cart', 'tart', 'tars']\n",
- "['cart', 'wart', 'dart']\n",
- "['cart', 'wart', 'hart']\n",
- "['cart', 'wart', 'mart']\n",
- "['cart', 'wart', 'part']\n",
- "['cart', 'wart', 'tart']\n",
- "['cart', 'wart', 'waft']\n",
- "['cart', 'wart', 'wait']\n",
- "['cart', 'wart', 'want']\n",
- "['cart', 'wart', 'watt']\n",
- "['cart', 'wart', 'ward']\n",
- "['cart', 'wart', 'ware']\n",
- "['cart', 'wart', 'warm']\n",
- "['cart', 'wart', 'warn']\n",
- "['cart', 'wart', 'warp']\n",
- "['cart', 'wart', 'wars']\n",
- "['cart', 'wart', 'wary']\n",
- "['cart', 'curt', 'hurt']\n",
- "['cart', 'curt', 'cult']\n",
- "['cart', 'curt', 'curb']\n",
- "['cart', 'curt', 'curd']\n",
- "['cart', 'curt', 'cure']\n",
- "['cart', 'curt', 'curl']\n",
- "['cart', 'curt', 'curs']\n",
- "['cart', 'cant', 'pant']\n",
- "['cart', 'cant', 'rant']\n",
- "['cart', 'cant', 'want']\n",
- "['cart', 'cant', 'cent']\n",
- "['cart', 'cant', 'cast']\n",
- "['cart', 'cant', 'cane']\n",
- "['cart', 'cant', 'cans']\n",
- "['cart', 'cast', 'bast']\n",
- "['cart', 'cast', 'east']\n",
- "['cart', 'cast', 'fast']\n",
- "['cart', 'cast', 'last']\n",
- "['cart', 'cast', 'mast']\n",
- "['cart', 'cast', 'past']\n",
- "['cart', 'cast', 'vast']\n",
- "['cart', 'cast', 'cost']\n",
- "['cart', 'cast', 'cyst']\n",
- "['cart', 'cast', 'cant']\n",
- "['cart', 'cast', 'case']\n",
- "['cart', 'cast', 'cash']\n",
- "['cart', 'cast', 'cask']\n",
- "['cart', 'card', 'bard']\n",
- "['cart', 'card', 'hard']\n",
- "['cart', 'card', 'lard']\n",
- "['cart', 'card', 'ward']\n",
- "['cart', 'card', 'yard']\n",
- "['cart', 'card', 'cord']\n",
- "['cart', 'card', 'curd']\n",
- "['cart', 'card', 'care']\n",
- "['cart', 'card', 'carp']\n",
- "['cart', 'card', 'cars']\n",
- "['cart', 'care', 'bare']\n",
- "['cart', 'care', 'dare']\n",
- "['cart', 'care', 'fare']\n",
- "['cart', 'care', 'hare']\n",
- "['cart', 'care', 'mare']\n",
- "['cart', 'care', 'pare']\n",
- "['cart', 'care', 'rare']\n",
- "['cart', 'care', 'tare']\n",
- "['cart', 'care', 'ware']\n",
- "['cart', 'care', 'core']\n",
- "['cart', 'care', 'cure']\n",
- "['cart', 'care', 'cafe']\n",
- "['cart', 'care', 'cage']\n",
- "['cart', 'care', 'cake']\n",
- "['cart', 'care', 'came']\n",
- "['cart', 'care', 'cane']\n",
- "['cart', 'care', 'cape']\n",
- "['cart', 'care', 'case']\n",
- "['cart', 'care', 'cave']\n",
- "['cart', 'care', 'card']\n",
- "['cart', 'care', 'carp']\n",
- "['cart', 'care', 'cars']\n",
- "['cart', 'carp', 'harp']\n",
- "['cart', 'carp', 'tarp']\n",
- "['cart', 'carp', 'warp']\n",
- "['cart', 'carp', 'camp']\n",
- "['cart', 'carp', 'card']\n",
- "['cart', 'carp', 'care']\n",
- "['cart', 'carp', 'cars']\n",
- "['cart', 'cars', 'bars']\n",
- "['cart', 'cars', 'ears']\n",
- "['cart', 'cars', 'jars']\n",
- "['cart', 'cars', 'mars']\n",
- "['cart', 'cars', 'oars']\n",
- "['cart', 'cars', 'pars']\n",
- "['cart', 'cars', 'tars']\n",
- "['cart', 'cars', 'wars']\n",
- "['cart', 'cars', 'curs']\n",
- "['cart', 'cars', 'cabs']\n",
- "['cart', 'cars', 'cads']\n",
- "['cart', 'cars', 'cams']\n",
- "['cart', 'cars', 'cans']\n",
- "['cart', 'cars', 'caps']\n",
- "['cart', 'cars', 'cats']\n",
- "['cart', 'cars', 'caws']\n",
- "['cart', 'cars', 'card']\n",
- "['cart', 'cars', 'care']\n",
- "['cart', 'cars', 'carp']\n",
- "['cart', 'dart', 'hart', 'mart']\n",
- "['cart', 'dart', 'hart', 'part']\n",
- "['cart', 'dart', 'hart', 'tart']\n",
- "['cart', 'dart', 'hart', 'wart']\n",
- "['cart', 'dart', 'hart', 'hurt']\n",
- "['cart', 'dart', 'hart', 'haft']\n",
- "['cart', 'dart', 'hart', 'halt']\n",
- "['cart', 'dart', 'hart', 'hard']\n",
- "['cart', 'dart', 'hart', 'hare']\n",
- "['cart', 'dart', 'hart', 'hark']\n",
- "['cart', 'dart', 'hart', 'harm']\n",
- "['cart', 'dart', 'hart', 'harp']\n",
- "['cart', 'dart', 'mart', 'hart']\n",
- "['cart', 'dart', 'mart', 'part']\n",
- "['cart', 'dart', 'mart', 'tart']\n",
- "['cart', 'dart', 'mart', 'wart']\n",
- "['cart', 'dart', 'mart', 'malt']\n",
- "['cart', 'dart', 'mart', 'mast']\n",
- "['cart', 'dart', 'mart', 'matt']\n",
- "['cart', 'dart', 'mart', 'mare']\n",
- "['cart', 'dart', 'mart', 'mark']\n",
- "['cart', 'dart', 'mart', 'mars']\n",
- "['cart', 'dart', 'part', 'hart']\n",
- "['cart', 'dart', 'part', 'mart']\n",
- "['cart', 'dart', 'part', 'tart']\n",
- "['cart', 'dart', 'part', 'wart']\n",
- "['cart', 'dart', 'part', 'pert']\n",
- "['cart', 'dart', 'part', 'port']\n",
- "['cart', 'dart', 'part', 'pact']\n",
- "['cart', 'dart', 'part', 'pant']\n",
- "['cart', 'dart', 'part', 'past']\n",
- "['cart', 'dart', 'part', 'pare']\n",
- "['cart', 'dart', 'part', 'park']\n",
- "['cart', 'dart', 'part', 'pars']\n",
- "['cart', 'dart', 'tart', 'hart']\n",
- "['cart', 'dart', 'tart', 'mart']\n",
- "['cart', 'dart', 'tart', 'part']\n",
- "['cart', 'dart', 'tart', 'wart']\n",
- "['cart', 'dart', 'tart', 'tort']\n",
- "['cart', 'dart', 'tart', 'tact']\n",
- "['cart', 'dart', 'tart', 'taut']\n",
- "['cart', 'dart', 'tart', 'tare']\n",
- "['cart', 'dart', 'tart', 'taro']\n",
- "['cart', 'dart', 'tart', 'tarp']\n",
- "['cart', 'dart', 'tart', 'tars']\n",
- "['cart', 'dart', 'wart', 'hart']\n",
- "['cart', 'dart', 'wart', 'mart']\n",
- "['cart', 'dart', 'wart', 'part']\n",
- "['cart', 'dart', 'wart', 'tart']\n",
- "['cart', 'dart', 'wart', 'waft']\n",
- "['cart', 'dart', 'wart', 'wait']\n",
- "['cart', 'dart', 'wart', 'want']\n",
- "['cart', 'dart', 'wart', 'watt']\n",
- "['cart', 'dart', 'wart', 'ward']\n",
- "['cart', 'dart', 'wart', 'ware']\n",
- "['cart', 'dart', 'wart', 'warm']\n",
- "['cart', 'dart', 'wart', 'warn']\n",
- "['cart', 'dart', 'wart', 'warp']\n",
- "['cart', 'dart', 'wart', 'wars']\n",
- "['cart', 'dart', 'wart', 'wary']\n",
- "['cart', 'dart', 'dirt', 'girt']\n",
- "['cart', 'dart', 'dirt', 'diet']\n",
- "['cart', 'dart', 'dirt', 'dint']\n",
- "['cart', 'dart', 'dirt', 'dire']\n",
- "['cart', 'dart', 'dirt', 'dirk']\n",
- "['cart', 'dart', 'daft', 'haft']\n",
- "['cart', 'dart', 'daft', 'raft']\n",
- "['cart', 'dart', 'daft', 'waft']\n",
- "['cart', 'dart', 'daft', 'deft']\n",
- "['cart', 'dart', 'dare', 'bare']\n",
- "['cart', 'dart', 'dare', 'care']\n",
- "['cart', 'dart', 'dare', 'fare']\n",
- "['cart', 'dart', 'dare', 'hare']\n",
- "['cart', 'dart', 'dare', 'mare']\n",
- "['cart', 'dart', 'dare', 'pare']\n",
- "['cart', 'dart', 'dare', 'rare']\n",
- "['cart', 'dart', 'dare', 'tare']\n",
- "['cart', 'dart', 'dare', 'ware']\n",
- "['cart', 'dart', 'dare', 'dire']\n",
- "['cart', 'dart', 'dare', 'dale']\n",
- "['cart', 'dart', 'dare', 'dame']\n",
- "['cart', 'dart', 'dare', 'date']\n",
- "['cart', 'dart', 'dare', 'daze']\n",
- "['cart', 'dart', 'dare', 'dark']\n",
- "['cart', 'dart', 'dare', 'darn']\n",
- "['cart', 'dart', 'dark', 'bark']\n",
- "['cart', 'dart', 'dark', 'hark']\n",
- "['cart', 'dart', 'dark', 'lark']\n",
- "['cart', 'dart', 'dark', 'mark']\n",
- "['cart', 'dart', 'dark', 'nark']\n",
- "['cart', 'dart', 'dark', 'park']\n",
- "['cart', 'dart', 'dark', 'dirk']\n",
- "['cart', 'dart', 'dark', 'dork']\n",
- "['cart', 'dart', 'dark', 'dank']\n",
- "['cart', 'dart', 'dark', 'dare']\n",
- "['cart', 'dart', 'dark', 'darn']\n",
- "['cart', 'dart', 'darn', 'barn']\n",
- "['cart', 'dart', 'darn', 'earn']\n",
- "['cart', 'dart', 'darn', 'warn']\n",
- "['cart', 'dart', 'darn', 'yarn']\n",
- "['cart', 'dart', 'darn', 'damn']\n",
- "['cart', 'dart', 'darn', 'dawn']\n",
- "['cart', 'dart', 'darn', 'dare']\n",
- "['cart', 'dart', 'darn', 'dark']\n",
- "['cart', 'hart', 'dart', 'mart']\n",
- "['cart', 'hart', 'dart', 'part']\n",
- "['cart', 'hart', 'dart', 'tart']\n",
- "['cart', 'hart', 'dart', 'wart']\n",
- "['cart', 'hart', 'dart', 'dirt']\n",
- "['cart', 'hart', 'dart', 'daft']\n",
- "['cart', 'hart', 'dart', 'dare']\n",
- "['cart', 'hart', 'dart', 'dark']\n",
- "['cart', 'hart', 'dart', 'darn']\n",
- "['cart', 'hart', 'mart', 'dart']\n",
- "['cart', 'hart', 'mart', 'part']\n",
- "['cart', 'hart', 'mart', 'tart']\n",
- "['cart', 'hart', 'mart', 'wart']\n",
- "['cart', 'hart', 'mart', 'malt']\n",
- "['cart', 'hart', 'mart', 'mast']\n",
- "['cart', 'hart', 'mart', 'matt']\n",
- "['cart', 'hart', 'mart', 'mare']\n",
- "['cart', 'hart', 'mart', 'mark']\n",
- "['cart', 'hart', 'mart', 'mars']\n",
- "['cart', 'hart', 'part', 'dart']\n",
- "['cart', 'hart', 'part', 'mart']\n",
- "['cart', 'hart', 'part', 'tart']\n",
- "['cart', 'hart', 'part', 'wart']\n",
- "['cart', 'hart', 'part', 'pert']\n",
- "['cart', 'hart', 'part', 'port']\n",
- "['cart', 'hart', 'part', 'pact']\n",
- "['cart', 'hart', 'part', 'pant']\n",
- "['cart', 'hart', 'part', 'past']\n",
- "['cart', 'hart', 'part', 'pare']\n",
- "['cart', 'hart', 'part', 'park']\n",
- "['cart', 'hart', 'part', 'pars']\n",
- "['cart', 'hart', 'tart', 'dart']\n",
- "['cart', 'hart', 'tart', 'mart']\n",
- "['cart', 'hart', 'tart', 'part']\n",
- "['cart', 'hart', 'tart', 'wart']\n",
- "['cart', 'hart', 'tart', 'tort']\n",
- "['cart', 'hart', 'tart', 'tact']\n",
- "['cart', 'hart', 'tart', 'taut']\n",
- "['cart', 'hart', 'tart', 'tare']\n",
- "['cart', 'hart', 'tart', 'taro']\n",
- "['cart', 'hart', 'tart', 'tarp']\n",
- "['cart', 'hart', 'tart', 'tars']\n",
- "['cart', 'hart', 'wart', 'dart']\n",
- "['cart', 'hart', 'wart', 'mart']\n",
- "['cart', 'hart', 'wart', 'part']\n",
- "['cart', 'hart', 'wart', 'tart']\n",
- "['cart', 'hart', 'wart', 'waft']\n",
- "['cart', 'hart', 'wart', 'wait']\n",
- "['cart', 'hart', 'wart', 'want']\n",
- "['cart', 'hart', 'wart', 'watt']\n",
- "['cart', 'hart', 'wart', 'ward']\n",
- "['cart', 'hart', 'wart', 'ware']\n",
- "['cart', 'hart', 'wart', 'warm']\n",
- "['cart', 'hart', 'wart', 'warn']\n",
- "['cart', 'hart', 'wart', 'warp']\n",
- "['cart', 'hart', 'wart', 'wars']\n",
- "['cart', 'hart', 'wart', 'wary']\n",
- "['cart', 'hart', 'hurt', 'curt']\n",
- "['cart', 'hart', 'hurt', 'hunt']\n",
- "['cart', 'hart', 'hurt', 'hurl']\n",
- "['cart', 'hart', 'haft', 'daft']\n",
- "['cart', 'hart', 'haft', 'raft']\n",
- "['cart', 'hart', 'haft', 'waft']\n",
- "['cart', 'hart', 'haft', 'heft']\n",
- "['cart', 'hart', 'haft', 'halt']\n",
- "['cart', 'hart', 'halt', 'malt']\n",
- "['cart', 'hart', 'halt', 'salt']\n",
- "['cart', 'hart', 'halt', 'hilt']\n",
- "['cart', 'hart', 'halt', 'haft']\n",
- "['cart', 'hart', 'halt', 'hale']\n",
- "['cart', 'hart', 'halt', 'half']\n",
- "['cart', 'hart', 'halt', 'hall']\n",
- "['cart', 'hart', 'halt', 'halo']\n",
- "['cart', 'hart', 'hard', 'bard']\n",
- "['cart', 'hart', 'hard', 'card']\n",
- "['cart', 'hart', 'hard', 'lard']\n",
- "['cart', 'hart', 'hard', 'ward']\n",
- "['cart', 'hart', 'hard', 'yard']\n",
- "['cart', 'hart', 'hard', 'herd']\n",
- "['cart', 'hart', 'hard', 'hand']\n",
- "['cart', 'hart', 'hard', 'hare']\n",
- "['cart', 'hart', 'hard', 'hark']\n",
- "['cart', 'hart', 'hard', 'harm']\n",
- "['cart', 'hart', 'hard', 'harp']\n",
- "['cart', 'hart', 'hare', 'bare']\n",
- "['cart', 'hart', 'hare', 'care']\n",
- "['cart', 'hart', 'hare', 'dare']\n",
- "['cart', 'hart', 'hare', 'fare']\n",
- "['cart', 'hart', 'hare', 'mare']\n",
- "['cart', 'hart', 'hare', 'pare']\n",
- "['cart', 'hart', 'hare', 'rare']\n",
- "['cart', 'hart', 'hare', 'tare']\n",
- "['cart', 'hart', 'hare', 'ware']\n",
- "['cart', 'hart', 'hare', 'here']\n",
- "['cart', 'hart', 'hare', 'hire']\n",
- "['cart', 'hart', 'hare', 'hake']\n",
- "['cart', 'hart', 'hare', 'hale']\n",
- "['cart', 'hart', 'hare', 'hate']\n",
- "['cart', 'hart', 'hare', 'have']\n",
- "['cart', 'hart', 'hare', 'haze']\n",
- "['cart', 'hart', 'hare', 'hard']\n",
- "['cart', 'hart', 'hare', 'hark']\n",
- "['cart', 'hart', 'hare', 'harm']\n",
- "['cart', 'hart', 'hare', 'harp']\n",
- "['cart', 'hart', 'hark', 'bark']\n",
- "['cart', 'hart', 'hark', 'dark']\n",
- "['cart', 'hart', 'hark', 'lark']\n",
- "['cart', 'hart', 'hark', 'mark']\n",
- "['cart', 'hart', 'hark', 'nark']\n",
- "['cart', 'hart', 'hark', 'park']\n",
- "['cart', 'hart', 'hark', 'hack']\n",
- "['cart', 'hart', 'hark', 'hank']\n",
- "['cart', 'hart', 'hark', 'hawk']\n",
- "['cart', 'hart', 'hark', 'hard']\n",
- "['cart', 'hart', 'hark', 'hare']\n",
- "['cart', 'hart', 'hark', 'harm']\n",
- "['cart', 'hart', 'hark', 'harp']\n",
- "['cart', 'hart', 'harm', 'farm']\n",
- "['cart', 'hart', 'harm', 'warm']\n",
- "['cart', 'hart', 'harm', 'hard']\n",
- "['cart', 'hart', 'harm', 'hare']\n",
- "['cart', 'hart', 'harm', 'hark']\n",
- "['cart', 'hart', 'harm', 'harp']\n",
- "['cart', 'hart', 'harp', 'carp']\n",
- "['cart', 'hart', 'harp', 'tarp']\n",
- "['cart', 'hart', 'harp', 'warp']\n",
- "['cart', 'hart', 'harp', 'hasp']\n",
- "['cart', 'hart', 'harp', 'hard']\n",
- "['cart', 'hart', 'harp', 'hare']\n",
- "['cart', 'hart', 'harp', 'hark']\n",
- "['cart', 'hart', 'harp', 'harm']\n",
- "['cart', 'mart', 'dart', 'hart']\n",
- "['cart', 'mart', 'dart', 'part']\n",
- "['cart', 'mart', 'dart', 'tart']\n",
- "['cart', 'mart', 'dart', 'wart']\n",
- "['cart', 'mart', 'dart', 'dirt']\n",
- "['cart', 'mart', 'dart', 'daft']\n",
- "['cart', 'mart', 'dart', 'dare']\n",
- "['cart', 'mart', 'dart', 'dark']\n",
- "['cart', 'mart', 'dart', 'darn']\n",
- "['cart', 'mart', 'hart', 'dart']\n",
- "['cart', 'mart', 'hart', 'part']\n",
- "['cart', 'mart', 'hart', 'tart']\n",
- "['cart', 'mart', 'hart', 'wart']\n",
- "['cart', 'mart', 'hart', 'hurt']\n",
- "['cart', 'mart', 'hart', 'haft']\n",
- "['cart', 'mart', 'hart', 'halt']\n",
- "['cart', 'mart', 'hart', 'hard']\n",
- "['cart', 'mart', 'hart', 'hare']\n",
- "['cart', 'mart', 'hart', 'hark']\n",
- "['cart', 'mart', 'hart', 'harm']\n",
- "['cart', 'mart', 'hart', 'harp']\n",
- "['cart', 'mart', 'part', 'dart']\n",
- "['cart', 'mart', 'part', 'hart']\n",
- "['cart', 'mart', 'part', 'tart']\n",
- "['cart', 'mart', 'part', 'wart']\n",
- "['cart', 'mart', 'part', 'pert']\n",
- "['cart', 'mart', 'part', 'port']\n",
- "['cart', 'mart', 'part', 'pact']\n",
- "['cart', 'mart', 'part', 'pant']\n",
- "['cart', 'mart', 'part', 'past']\n",
- "['cart', 'mart', 'part', 'pare']\n",
- "['cart', 'mart', 'part', 'park']\n",
- "['cart', 'mart', 'part', 'pars']\n",
- "['cart', 'mart', 'tart', 'dart']\n",
- "['cart', 'mart', 'tart', 'hart']\n",
- "['cart', 'mart', 'tart', 'part']\n",
- "['cart', 'mart', 'tart', 'wart']\n",
- "['cart', 'mart', 'tart', 'tort']\n",
- "['cart', 'mart', 'tart', 'tact']\n",
- "['cart', 'mart', 'tart', 'taut']\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "['cart', 'mart', 'tart', 'tare']\n",
- "['cart', 'mart', 'tart', 'taro']\n",
- "['cart', 'mart', 'tart', 'tarp']\n",
- "['cart', 'mart', 'tart', 'tars']\n",
- "['cart', 'mart', 'wart', 'dart']\n",
- "['cart', 'mart', 'wart', 'hart']\n",
- "['cart', 'mart', 'wart', 'part']\n",
- "['cart', 'mart', 'wart', 'tart']\n",
- "['cart', 'mart', 'wart', 'waft']\n",
- "['cart', 'mart', 'wart', 'wait']\n",
- "['cart', 'mart', 'wart', 'want']\n",
- "['cart', 'mart', 'wart', 'watt']\n",
- "['cart', 'mart', 'wart', 'ward']\n",
- "['cart', 'mart', 'wart', 'ware']\n",
- "['cart', 'mart', 'wart', 'warm']\n",
- "['cart', 'mart', 'wart', 'warn']\n",
- "['cart', 'mart', 'wart', 'warp']\n",
- "['cart', 'mart', 'wart', 'wars']\n",
- "['cart', 'mart', 'wart', 'wary']\n",
- "['cart', 'mart', 'malt', 'halt']\n",
- "['cart', 'mart', 'malt', 'salt']\n",
- "['cart', 'mart', 'malt', 'melt']\n",
- "['cart', 'mart', 'malt', 'mast']\n",
- "['cart', 'mart', 'malt', 'matt']\n",
- "['cart', 'mart', 'malt', 'male']\n",
- "['cart', 'mart', 'malt', 'mall']\n",
- "['cart', 'mart', 'mast', 'bast']\n",
- "['cart', 'mart', 'mast', 'cast']\n",
- "['cart', 'mart', 'mast', 'east']\n",
- "['cart', 'mart', 'mast', 'fast']\n",
- "['cart', 'mart', 'mast', 'last']\n",
- "['cart', 'mart', 'mast', 'past']\n",
- "['cart', 'mart', 'mast', 'vast']\n",
- "['cart', 'mart', 'mast', 'mist']\n",
- "['cart', 'mart', 'mast', 'most']\n",
- "['cart', 'mart', 'mast', 'must']\n",
- "['cart', 'mart', 'mast', 'malt']\n",
- "['cart', 'mart', 'mast', 'matt']\n",
- "['cart', 'mart', 'mast', 'mash']\n",
- "['cart', 'mart', 'mast', 'mask']\n",
- "['cart', 'mart', 'mast', 'mass']\n",
- "['cart', 'mart', 'matt', 'watt']\n",
- "['cart', 'mart', 'matt', 'mitt']\n",
- "['cart', 'mart', 'matt', 'mutt']\n",
- "['cart', 'mart', 'matt', 'malt']\n",
- "['cart', 'mart', 'matt', 'mast']\n",
- "['cart', 'mart', 'matt', 'mate']\n",
- "['cart', 'mart', 'matt', 'math']\n",
- "['cart', 'mart', 'matt', 'mats']\n",
- "['cart', 'mart', 'mare', 'bare']\n",
- "['cart', 'mart', 'mare', 'care']\n",
- "['cart', 'mart', 'mare', 'dare']\n",
- "['cart', 'mart', 'mare', 'fare']\n",
- "['cart', 'mart', 'mare', 'hare']\n",
- "['cart', 'mart', 'mare', 'pare']\n",
- "['cart', 'mart', 'mare', 'rare']\n",
- "['cart', 'mart', 'mare', 'tare']\n",
- "['cart', 'mart', 'mare', 'ware']\n",
- "['cart', 'mart', 'mare', 'mere']\n",
- "['cart', 'mart', 'mare', 'mire']\n",
- "['cart', 'mart', 'mare', 'more']\n",
- "['cart', 'mart', 'mare', 'mace']\n",
- "['cart', 'mart', 'mare', 'made']\n",
- "['cart', 'mart', 'mare', 'make']\n",
- "['cart', 'mart', 'mare', 'male']\n",
- "['cart', 'mart', 'mare', 'mane']\n",
- "['cart', 'mart', 'mare', 'mate']\n",
- "['cart', 'mart', 'mare', 'maze']\n",
- "['cart', 'mart', 'mare', 'mark']\n",
- "['cart', 'mart', 'mare', 'mars']\n",
- "['cart', 'mart', 'mark', 'bark']\n",
- "['cart', 'mart', 'mark', 'dark']\n",
- "['cart', 'mart', 'mark', 'hark']\n",
- "['cart', 'mart', 'mark', 'lark']\n",
- "['cart', 'mart', 'mark', 'nark']\n",
- "['cart', 'mart', 'mark', 'park']\n",
- "['cart', 'mart', 'mark', 'murk']\n",
- "['cart', 'mart', 'mark', 'mask']\n",
- "['cart', 'mart', 'mark', 'mare']\n",
- "['cart', 'mart', 'mark', 'mars']\n",
- "['cart', 'mart', 'mars', 'bars']\n",
- "['cart', 'mart', 'mars', 'cars']\n",
- "['cart', 'mart', 'mars', 'ears']\n",
- "['cart', 'mart', 'mars', 'jars']\n",
- "['cart', 'mart', 'mars', 'oars']\n",
- "['cart', 'mart', 'mars', 'pars']\n",
- "['cart', 'mart', 'mars', 'tars']\n",
- "['cart', 'mart', 'mars', 'wars']\n",
- "['cart', 'mart', 'mars', 'mads']\n",
- "['cart', 'mart', 'mars', 'mans']\n",
- "['cart', 'mart', 'mars', 'maps']\n",
- "['cart', 'mart', 'mars', 'mass']\n",
- "['cart', 'mart', 'mars', 'mats']\n",
- "['cart', 'mart', 'mars', 'maws']\n",
- "['cart', 'mart', 'mars', 'mare']\n",
- "['cart', 'mart', 'mars', 'mark']\n",
- "['cart', 'part', 'dart', 'hart']\n",
- "['cart', 'part', 'dart', 'mart']\n",
- "['cart', 'part', 'dart', 'tart']\n",
- "['cart', 'part', 'dart', 'wart']\n",
- "['cart', 'part', 'dart', 'dirt']\n",
- "['cart', 'part', 'dart', 'daft']\n",
- "['cart', 'part', 'dart', 'dare']\n",
- "['cart', 'part', 'dart', 'dark']\n",
- "['cart', 'part', 'dart', 'darn']\n",
- "['cart', 'part', 'hart', 'dart']\n",
- "['cart', 'part', 'hart', 'mart']\n",
- "['cart', 'part', 'hart', 'tart']\n",
- "['cart', 'part', 'hart', 'wart']\n",
- "['cart', 'part', 'hart', 'hurt']\n",
- "['cart', 'part', 'hart', 'haft']\n",
- "['cart', 'part', 'hart', 'halt']\n",
- "['cart', 'part', 'hart', 'hard']\n",
- "['cart', 'part', 'hart', 'hare']\n",
- "['cart', 'part', 'hart', 'hark']\n",
- "['cart', 'part', 'hart', 'harm']\n",
- "['cart', 'part', 'hart', 'harp']\n",
- "['cart', 'part', 'mart', 'dart']\n",
- "['cart', 'part', 'mart', 'hart']\n",
- "['cart', 'part', 'mart', 'tart']\n",
- "['cart', 'part', 'mart', 'wart']\n",
- "['cart', 'part', 'mart', 'malt']\n",
- "['cart', 'part', 'mart', 'mast']\n",
- "['cart', 'part', 'mart', 'matt']\n",
- "['cart', 'part', 'mart', 'mare']\n",
- "['cart', 'part', 'mart', 'mark']\n",
- "['cart', 'part', 'mart', 'mars']\n",
- "['cart', 'part', 'tart', 'dart']\n",
- "['cart', 'part', 'tart', 'hart']\n",
- "['cart', 'part', 'tart', 'mart']\n",
- "['cart', 'part', 'tart', 'wart']\n",
- "['cart', 'part', 'tart', 'tort']\n",
- "['cart', 'part', 'tart', 'tact']\n",
- "['cart', 'part', 'tart', 'taut']\n",
- "['cart', 'part', 'tart', 'tare']\n",
- "['cart', 'part', 'tart', 'taro']\n",
- "['cart', 'part', 'tart', 'tarp']\n",
- "['cart', 'part', 'tart', 'tars']\n",
- "['cart', 'part', 'wart', 'dart']\n",
- "['cart', 'part', 'wart', 'hart']\n",
- "['cart', 'part', 'wart', 'mart']\n",
- "['cart', 'part', 'wart', 'tart']\n",
- "['cart', 'part', 'wart', 'waft']\n",
- "['cart', 'part', 'wart', 'wait']\n",
- "['cart', 'part', 'wart', 'want']\n",
- "['cart', 'part', 'wart', 'watt']\n",
- "['cart', 'part', 'wart', 'ward']\n",
- "['cart', 'part', 'wart', 'ware']\n",
- "['cart', 'part', 'wart', 'warm']\n",
- "['cart', 'part', 'wart', 'warn']\n",
- "['cart', 'part', 'wart', 'warp']\n",
- "['cart', 'part', 'wart', 'wars']\n",
- "['cart', 'part', 'wart', 'wary']\n",
- "['cart', 'part', 'pert', 'port']\n",
- "['cart', 'part', 'pert', 'peat']\n",
- "['cart', 'part', 'pert', 'pelt']\n",
- "['cart', 'part', 'pert', 'pent']\n",
- "['cart', 'part', 'pert', 'pest']\n",
- "['cart', 'part', 'pert', 'perk']\n",
- "['cart', 'part', 'pert', 'perm']\n",
- "['cart', 'part', 'port', 'fort']\n",
- "['cart', 'part', 'port', 'sort']\n",
- "['cart', 'part', 'port', 'tort']\n",
- "['cart', 'part', 'port', 'pert']\n",
- "['cart', 'part', 'port', 'poet']\n",
- "['cart', 'part', 'port', 'post']\n",
- "['cart', 'part', 'port', 'pout']\n",
- "['cart', 'part', 'port', 'pore']\n",
- "['cart', 'part', 'port', 'pork']\n",
- "['cart', 'part', 'port', 'porn']\n",
- "['cart', 'part', 'pact', 'fact']\n",
- "['cart', 'part', 'pact', 'tact']\n",
- "['cart', 'part', 'pact', 'pant']\n",
- "['cart', 'part', 'pact', 'past']\n",
- "['cart', 'part', 'pact', 'pace']\n",
- "['cart', 'part', 'pact', 'pack']\n",
- "['cart', 'part', 'pant', 'cant']\n",
- "['cart', 'part', 'pant', 'rant']\n",
- "['cart', 'part', 'pant', 'want']\n",
- "['cart', 'part', 'pant', 'pent']\n",
- "['cart', 'part', 'pant', 'pint']\n",
- "['cart', 'part', 'pant', 'punt']\n",
- "['cart', 'part', 'pant', 'pact']\n",
- "['cart', 'part', 'pant', 'past']\n",
- "['cart', 'part', 'pant', 'pane']\n",
- "['cart', 'part', 'pant', 'pang']\n",
- "['cart', 'part', 'pant', 'pans']\n",
- "['cart', 'part', 'past', 'bast']\n",
- "['cart', 'part', 'past', 'cast']\n",
- "['cart', 'part', 'past', 'east']\n",
- "['cart', 'part', 'past', 'fast']\n",
- "['cart', 'part', 'past', 'last']\n",
- "['cart', 'part', 'past', 'mast']\n",
- "['cart', 'part', 'past', 'vast']\n",
- "['cart', 'part', 'past', 'pest']\n",
- "['cart', 'part', 'past', 'post']\n",
- "['cart', 'part', 'past', 'psst']\n",
- "['cart', 'part', 'past', 'pact']\n",
- "['cart', 'part', 'past', 'pant']\n",
- "['cart', 'part', 'past', 'pass']\n",
- "['cart', 'part', 'pare', 'bare']\n",
- "['cart', 'part', 'pare', 'care']\n",
- "['cart', 'part', 'pare', 'dare']\n",
- "['cart', 'part', 'pare', 'fare']\n",
- "['cart', 'part', 'pare', 'hare']\n",
- "['cart', 'part', 'pare', 'mare']\n",
- "['cart', 'part', 'pare', 'rare']\n",
- "['cart', 'part', 'pare', 'tare']\n",
- "['cart', 'part', 'pare', 'ware']\n",
- "['cart', 'part', 'pare', 'pore']\n",
- "['cart', 'part', 'pare', 'pure']\n",
- "['cart', 'part', 'pare', 'pyre']\n",
- "['cart', 'part', 'pare', 'pace']\n",
- "['cart', 'part', 'pare', 'page']\n",
- "['cart', 'part', 'pare', 'pale']\n",
- "['cart', 'part', 'pare', 'pane']\n",
- "['cart', 'part', 'pare', 'pate']\n",
- "['cart', 'part', 'pare', 'pave']\n",
- "['cart', 'part', 'pare', 'park']\n",
- "['cart', 'part', 'pare', 'pars']\n",
- "['cart', 'part', 'park', 'bark']\n",
- "['cart', 'part', 'park', 'dark']\n",
- "['cart', 'part', 'park', 'hark']\n",
- "['cart', 'part', 'park', 'lark']\n",
- "['cart', 'part', 'park', 'mark']\n",
- "['cart', 'part', 'park', 'nark']\n",
- "['cart', 'part', 'park', 'perk']\n",
- "['cart', 'part', 'park', 'pork']\n",
- "['cart', 'part', 'park', 'pack']\n",
- "['cart', 'part', 'park', 'pare']\n",
- "['cart', 'part', 'park', 'pars']\n",
- "['cart', 'part', 'pars', 'bars']\n",
- "['cart', 'part', 'pars', 'cars']\n",
- "['cart', 'part', 'pars', 'ears']\n",
- "['cart', 'part', 'pars', 'jars']\n",
- "['cart', 'part', 'pars', 'mars']\n",
- "['cart', 'part', 'pars', 'oars']\n",
- "['cart', 'part', 'pars', 'tars']\n",
- "['cart', 'part', 'pars', 'wars']\n",
- "['cart', 'part', 'pars', 'pads']\n",
- "['cart', 'part', 'pars', 'pals']\n",
- "['cart', 'part', 'pars', 'pans']\n",
- "['cart', 'part', 'pars', 'paps']\n",
- "['cart', 'part', 'pars', 'pass']\n",
- "['cart', 'part', 'pars', 'pats']\n",
- "['cart', 'part', 'pars', 'paws']\n",
- "['cart', 'part', 'pars', 'pays']\n",
- "['cart', 'part', 'pars', 'pare']\n",
- "['cart', 'part', 'pars', 'park']\n",
- "['cart', 'tart', 'dart', 'hart']\n",
- "['cart', 'tart', 'dart', 'mart']\n",
- "['cart', 'tart', 'dart', 'part']\n",
- "['cart', 'tart', 'dart', 'wart']\n",
- "['cart', 'tart', 'dart', 'dirt']\n",
- "['cart', 'tart', 'dart', 'daft']\n",
- "['cart', 'tart', 'dart', 'dare']\n",
- "['cart', 'tart', 'dart', 'dark']\n",
- "['cart', 'tart', 'dart', 'darn']\n",
- "['cart', 'tart', 'hart', 'dart']\n",
- "['cart', 'tart', 'hart', 'mart']\n",
- "['cart', 'tart', 'hart', 'part']\n",
- "['cart', 'tart', 'hart', 'wart']\n",
- "['cart', 'tart', 'hart', 'hurt']\n",
- "['cart', 'tart', 'hart', 'haft']\n",
- "['cart', 'tart', 'hart', 'halt']\n",
- "['cart', 'tart', 'hart', 'hard']\n",
- "['cart', 'tart', 'hart', 'hare']\n",
- "['cart', 'tart', 'hart', 'hark']\n",
- "['cart', 'tart', 'hart', 'harm']\n",
- "['cart', 'tart', 'hart', 'harp']\n",
- "['cart', 'tart', 'mart', 'dart']\n",
- "['cart', 'tart', 'mart', 'hart']\n",
- "['cart', 'tart', 'mart', 'part']\n",
- "['cart', 'tart', 'mart', 'wart']\n",
- "['cart', 'tart', 'mart', 'malt']\n",
- "['cart', 'tart', 'mart', 'mast']\n",
- "['cart', 'tart', 'mart', 'matt']\n",
- "['cart', 'tart', 'mart', 'mare']\n",
- "['cart', 'tart', 'mart', 'mark']\n",
- "['cart', 'tart', 'mart', 'mars']\n",
- "['cart', 'tart', 'part', 'dart']\n",
- "['cart', 'tart', 'part', 'hart']\n",
- "['cart', 'tart', 'part', 'mart']\n",
- "['cart', 'tart', 'part', 'wart']\n",
- "['cart', 'tart', 'part', 'pert']\n",
- "['cart', 'tart', 'part', 'port']\n",
- "['cart', 'tart', 'part', 'pact']\n",
- "['cart', 'tart', 'part', 'pant']\n",
- "['cart', 'tart', 'part', 'past']\n",
- "['cart', 'tart', 'part', 'pare']\n",
- "['cart', 'tart', 'part', 'park']\n",
- "['cart', 'tart', 'part', 'pars']\n",
- "['cart', 'tart', 'wart', 'dart']\n",
- "['cart', 'tart', 'wart', 'hart']\n",
- "['cart', 'tart', 'wart', 'mart']\n",
- "['cart', 'tart', 'wart', 'part']\n",
- "['cart', 'tart', 'wart', 'waft']\n",
- "['cart', 'tart', 'wart', 'wait']\n",
- "['cart', 'tart', 'wart', 'want']\n",
- "['cart', 'tart', 'wart', 'watt']\n",
- "['cart', 'tart', 'wart', 'ward']\n",
- "['cart', 'tart', 'wart', 'ware']\n",
- "['cart', 'tart', 'wart', 'warm']\n",
- "['cart', 'tart', 'wart', 'warn']\n",
- "['cart', 'tart', 'wart', 'warp']\n",
- "['cart', 'tart', 'wart', 'wars']\n",
- "['cart', 'tart', 'wart', 'wary']\n",
- "['cart', 'tart', 'tort', 'fort']\n",
- "['cart', 'tart', 'tort', 'port']\n",
- "['cart', 'tart', 'tort', 'sort']\n",
- "['cart', 'tart', 'tort', 'toot']\n",
- "['cart', 'tart', 'tort', 'tost']\n",
- "['cart', 'tart', 'tort', 'tout']\n",
- "['cart', 'tart', 'tort', 'tore']\n",
- "['cart', 'tart', 'tort', 'torn']\n",
- "['cart', 'tart', 'tort', 'tors']\n",
- "['cart', 'tart', 'tact', 'fact']\n",
- "['cart', 'tart', 'tact', 'pact']\n",
- "['cart', 'tart', 'tact', 'taut']\n",
- "['cart', 'tart', 'tact', 'tack']\n",
- "['cart', 'tart', 'tact', 'taco']\n",
- "['cart', 'tart', 'taut', 'tout']\n",
- "['cart', 'tart', 'taut', 'tact']\n",
- "['cart', 'tart', 'tare', 'bare']\n",
- "['cart', 'tart', 'tare', 'care']\n",
- "['cart', 'tart', 'tare', 'dare']\n",
- "['cart', 'tart', 'tare', 'fare']\n",
- "['cart', 'tart', 'tare', 'hare']\n",
- "['cart', 'tart', 'tare', 'mare']\n",
- "['cart', 'tart', 'tare', 'pare']\n",
- "['cart', 'tart', 'tare', 'rare']\n",
- "['cart', 'tart', 'tare', 'ware']\n",
- "['cart', 'tart', 'tare', 'tire']\n",
- "['cart', 'tart', 'tare', 'tore']\n",
- "['cart', 'tart', 'tare', 'tyre']\n",
- "['cart', 'tart', 'tare', 'take']\n",
- "['cart', 'tart', 'tare', 'tale']\n",
- "['cart', 'tart', 'tare', 'tame']\n",
- "['cart', 'tart', 'tare', 'tape']\n",
- "['cart', 'tart', 'tare', 'taro']\n",
- "['cart', 'tart', 'tare', 'tarp']\n",
- "['cart', 'tart', 'tare', 'tars']\n",
- "['cart', 'tart', 'taro', 'tiro']\n",
- "['cart', 'tart', 'taro', 'tyro']\n",
- "['cart', 'tart', 'taro', 'taco']\n",
- "['cart', 'tart', 'taro', 'tare']\n",
- "['cart', 'tart', 'taro', 'tarp']\n",
- "['cart', 'tart', 'taro', 'tars']\n",
- "['cart', 'tart', 'tarp', 'carp']\n",
- "['cart', 'tart', 'tarp', 'harp']\n",
- "['cart', 'tart', 'tarp', 'warp']\n",
- "['cart', 'tart', 'tarp', 'tamp']\n",
- "['cart', 'tart', 'tarp', 'tare']\n",
- "['cart', 'tart', 'tarp', 'taro']\n",
- "['cart', 'tart', 'tarp', 'tars']\n",
- "['cart', 'tart', 'tars', 'bars']\n",
- "['cart', 'tart', 'tars', 'cars']\n",
- "['cart', 'tart', 'tars', 'ears']\n",
- "['cart', 'tart', 'tars', 'jars']\n",
- "['cart', 'tart', 'tars', 'mars']\n",
- "['cart', 'tart', 'tars', 'oars']\n",
- "['cart', 'tart', 'tars', 'pars']\n",
- "['cart', 'tart', 'tars', 'wars']\n",
- "['cart', 'tart', 'tars', 'tors']\n",
- "['cart', 'tart', 'tars', 'tabs']\n",
- "['cart', 'tart', 'tars', 'tads']\n",
- "['cart', 'tart', 'tars', 'tags']\n",
- "['cart', 'tart', 'tars', 'tams']\n",
- "['cart', 'tart', 'tars', 'tans']\n",
- "['cart', 'tart', 'tars', 'taps']\n",
- "['cart', 'tart', 'tars', 'tats']\n",
- "['cart', 'tart', 'tars', 'tare']\n",
- "['cart', 'tart', 'tars', 'taro']\n",
- "['cart', 'tart', 'tars', 'tarp']\n",
- "['cart', 'wart', 'dart', 'hart']\n",
- "['cart', 'wart', 'dart', 'mart']\n",
- "['cart', 'wart', 'dart', 'part']\n",
- "['cart', 'wart', 'dart', 'tart']\n",
- "['cart', 'wart', 'dart', 'dirt']\n",
- "['cart', 'wart', 'dart', 'daft']\n",
- "['cart', 'wart', 'dart', 'dare']\n",
- "['cart', 'wart', 'dart', 'dark']\n",
- "['cart', 'wart', 'dart', 'darn']\n",
- "['cart', 'wart', 'hart', 'dart']\n",
- "['cart', 'wart', 'hart', 'mart']\n",
- "['cart', 'wart', 'hart', 'part']\n",
- "['cart', 'wart', 'hart', 'tart']\n",
- "['cart', 'wart', 'hart', 'hurt']\n",
- "['cart', 'wart', 'hart', 'haft']\n",
- "['cart', 'wart', 'hart', 'halt']\n",
- "['cart', 'wart', 'hart', 'hard']\n",
- "['cart', 'wart', 'hart', 'hare']\n",
- "['cart', 'wart', 'hart', 'hark']\n",
- "['cart', 'wart', 'hart', 'harm']\n",
- "['cart', 'wart', 'hart', 'harp']\n",
- "['cart', 'wart', 'mart', 'dart']\n",
- "['cart', 'wart', 'mart', 'hart']\n",
- "['cart', 'wart', 'mart', 'part']\n",
- "['cart', 'wart', 'mart', 'tart']\n",
- "['cart', 'wart', 'mart', 'malt']\n",
- "['cart', 'wart', 'mart', 'mast']\n",
- "['cart', 'wart', 'mart', 'matt']\n",
- "['cart', 'wart', 'mart', 'mare']\n",
- "['cart', 'wart', 'mart', 'mark']\n",
- "['cart', 'wart', 'mart', 'mars']\n",
- "['cart', 'wart', 'part', 'dart']\n",
- "['cart', 'wart', 'part', 'hart']\n",
- "['cart', 'wart', 'part', 'mart']\n",
- "['cart', 'wart', 'part', 'tart']\n",
- "['cart', 'wart', 'part', 'pert']\n",
- "['cart', 'wart', 'part', 'port']\n",
- "['cart', 'wart', 'part', 'pact']\n",
- "['cart', 'wart', 'part', 'pant']\n",
- "['cart', 'wart', 'part', 'past']\n",
- "['cart', 'wart', 'part', 'pare']\n",
- "['cart', 'wart', 'part', 'park']\n",
- "['cart', 'wart', 'part', 'pars']\n",
- "['cart', 'wart', 'tart', 'dart']\n",
- "['cart', 'wart', 'tart', 'hart']\n",
- "['cart', 'wart', 'tart', 'mart']\n",
- "['cart', 'wart', 'tart', 'part']\n",
- "['cart', 'wart', 'tart', 'tort']\n",
- "['cart', 'wart', 'tart', 'tact']\n",
- "['cart', 'wart', 'tart', 'taut']\n",
- "['cart', 'wart', 'tart', 'tare']\n",
- "['cart', 'wart', 'tart', 'taro']\n",
- "['cart', 'wart', 'tart', 'tarp']\n",
- "['cart', 'wart', 'tart', 'tars']\n",
- "['cart', 'wart', 'waft', 'daft']\n",
- "['cart', 'wart', 'waft', 'haft']\n",
- "['cart', 'wart', 'waft', 'raft']\n",
- "['cart', 'wart', 'waft', 'weft']\n",
- "['cart', 'wart', 'waft', 'wait']\n",
- "['cart', 'wart', 'waft', 'want']\n",
- "['cart', 'wart', 'waft', 'watt']\n",
- "['cart', 'wart', 'wait', 'bait']\n",
- "['cart', 'wart', 'wait', 'gait']\n",
- "['cart', 'wart', 'wait', 'whit']\n",
- "['cart', 'wart', 'wait', 'writ']\n",
- "['cart', 'wart', 'wait', 'waft']\n",
- "['cart', 'wart', 'wait', 'want']\n",
- "['cart', 'wart', 'wait', 'watt']\n",
- "['cart', 'wart', 'wait', 'waif']\n",
- "['cart', 'wart', 'wait', 'wail']\n",
- "['cart', 'wart', 'want', 'cant']\n",
- "['cart', 'wart', 'want', 'pant']\n",
- "['cart', 'wart', 'want', 'rant']\n",
- "['cart', 'wart', 'want', 'went']\n",
- "['cart', 'wart', 'want', 'wont']\n",
- "['cart', 'wart', 'want', 'waft']\n",
- "['cart', 'wart', 'want', 'wait']\n",
- "['cart', 'wart', 'want', 'watt']\n",
- "['cart', 'wart', 'want', 'wand']\n",
- "['cart', 'wart', 'want', 'wane']\n",
- "['cart', 'wart', 'watt', 'matt']\n",
- "['cart', 'wart', 'watt', 'waft']\n",
- "['cart', 'wart', 'watt', 'wait']\n",
- "['cart', 'wart', 'watt', 'want']\n",
- "['cart', 'wart', 'ward', 'bard']\n",
- "['cart', 'wart', 'ward', 'card']\n",
- "['cart', 'wart', 'ward', 'hard']\n",
- "['cart', 'wart', 'ward', 'lard']\n",
- "['cart', 'wart', 'ward', 'yard']\n",
- "['cart', 'wart', 'ward', 'word']\n",
- "['cart', 'wart', 'ward', 'wand']\n",
- "['cart', 'wart', 'ward', 'ware']\n",
- "['cart', 'wart', 'ward', 'warm']\n",
- "['cart', 'wart', 'ward', 'warn']\n",
- "['cart', 'wart', 'ward', 'warp']\n",
- "['cart', 'wart', 'ward', 'wars']\n",
- "['cart', 'wart', 'ward', 'wary']\n",
- "['cart', 'wart', 'ware', 'bare']\n",
- "['cart', 'wart', 'ware', 'care']\n",
- "['cart', 'wart', 'ware', 'dare']\n",
- "['cart', 'wart', 'ware', 'fare']\n",
- "['cart', 'wart', 'ware', 'hare']\n",
- "['cart', 'wart', 'ware', 'mare']\n",
- "['cart', 'wart', 'ware', 'pare']\n",
- "['cart', 'wart', 'ware', 'rare']\n",
- "['cart', 'wart', 'ware', 'tare']\n",
- "['cart', 'wart', 'ware', 'were']\n",
- "['cart', 'wart', 'ware', 'wire']\n",
- "['cart', 'wart', 'ware', 'wore']\n",
- "['cart', 'wart', 'ware', 'wade']\n",
- "['cart', 'wart', 'ware', 'wage']\n"
- ]
- },
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "['cart', 'wart', 'ware', 'wake']\n",
- "['cart', 'wart', 'ware', 'wale']\n",
- "['cart', 'wart', 'ware', 'wane']\n",
- "['cart', 'wart', 'ware', 'wave']\n",
- "['cart', 'wart', 'ware', 'ward']\n",
- "['cart', 'wart', 'ware', 'warm']\n",
- "['cart', 'wart', 'ware', 'warn']\n",
- "['cart', 'wart', 'ware', 'warp']\n",
- "['cart', 'wart', 'ware', 'wars']\n",
- "['cart', 'wart', 'ware', 'wary']\n",
- "['cart', 'wart', 'warm', 'farm']\n",
- "['cart', 'wart', 'warm', 'harm']\n",
- "['cart', 'wart', 'warm', 'worm']\n",
- "['cart', 'wart', 'warm', 'ward']\n",
- "['cart', 'wart', 'warm', 'ware']\n",
- "['cart', 'wart', 'warm', 'warn']\n",
- "['cart', 'wart', 'warm', 'warp']\n",
- "['cart', 'wart', 'warm', 'wars']\n",
- "['cart', 'wart', 'warm', 'wary']\n",
- "['cart', 'wart', 'warn', 'barn']\n",
- "['cart', 'wart', 'warn', 'darn']\n",
- "['cart', 'wart', 'warn', 'earn']\n",
- "['cart', 'wart', 'warn', 'yarn']\n",
- "['cart', 'wart', 'warn', 'worn']\n",
- "['cart', 'wart', 'warn', 'ward']\n",
- "['cart', 'wart', 'warn', 'ware']\n",
- "['cart', 'wart', 'warn', 'warm']\n",
- "['cart', 'wart', 'warn', 'warp']\n",
- "['cart', 'wart', 'warn', 'wars']\n",
- "['cart', 'wart', 'warn', 'wary']\n",
- "['cart', 'wart', 'warp', 'carp']\n",
- "['cart', 'wart', 'warp', 'harp']\n",
- "['cart', 'wart', 'warp', 'tarp']\n",
- "['cart', 'wart', 'warp', 'wasp']\n",
- "['cart', 'wart', 'warp', 'ward']\n",
- "['cart', 'wart', 'warp', 'ware']\n",
- "['cart', 'wart', 'warp', 'warm']\n",
- "['cart', 'wart', 'warp', 'warn']\n",
- "['cart', 'wart', 'warp', 'wars']\n",
- "['cart', 'wart', 'warp', 'wary']\n",
- "['cart', 'wart', 'wars', 'bars']\n",
- "['cart', 'wart', 'wars', 'cars']\n",
- "['cart', 'wart', 'wars', 'ears']\n",
- "['cart', 'wart', 'wars', 'jars']\n",
- "['cart', 'wart', 'wars', 'mars']\n",
- "['cart', 'wart', 'wars', 'oars']\n",
- "['cart', 'wart', 'wars', 'pars']\n",
- "['cart', 'wart', 'wars', 'tars']\n",
- "['cart', 'wart', 'wars', 'wads']\n",
- "['cart', 'wart', 'wars', 'wags']\n",
- "['cart', 'wart', 'wars', 'ways']\n",
- "['cart', 'wart', 'wars', 'ward']\n",
- "['cart', 'wart', 'wars', 'ware']\n",
- "['cart', 'wart', 'wars', 'warm']\n",
- "['cart', 'wart', 'wars', 'warn']\n",
- "['cart', 'wart', 'wars', 'warp']\n",
- "['cart', 'wart', 'wars', 'wary']\n",
- "['cart', 'wart', 'wary', 'nary']\n",
- "['cart', 'wart', 'wary', 'vary']\n",
- "['cart', 'wart', 'wary', 'wiry']\n",
- "['cart', 'wart', 'wary', 'wavy']\n",
- "['cart', 'wart', 'wary', 'waxy']\n",
- "['cart', 'wart', 'wary', 'ward']\n",
- "['cart', 'wart', 'wary', 'ware']\n",
- "['cart', 'wart', 'wary', 'warm']\n",
- "['cart', 'wart', 'wary', 'warn']\n",
- "['cart', 'wart', 'wary', 'warp']\n",
- "['cart', 'wart', 'wary', 'wars']\n",
- "['cart', 'curt', 'hurt', 'hart']\n",
- "['cart', 'curt', 'hurt', 'hunt']\n",
- "['cart', 'curt', 'hurt', 'hurl']\n",
- "['cart', 'curt', 'cult', 'colt']\n",
- "['cart', 'curt', 'cult', 'cull']\n",
- "['cart', 'curt', 'curb', 'curd']\n",
- "['cart', 'curt', 'curb', 'cure']\n",
- "['cart', 'curt', 'curb', 'curl']\n",
- "['cart', 'curt', 'curb', 'curs']\n",
- "['cart', 'curt', 'curd', 'turd']\n",
- "['cart', 'curt', 'curd', 'card']\n",
- "['cart', 'curt', 'curd', 'cord']\n",
- "['cart', 'curt', 'curd', 'cued']\n",
- "['cart', 'curt', 'curd', 'curb']\n",
- "['cart', 'curt', 'curd', 'cure']\n",
- "['cart', 'curt', 'curd', 'curl']\n",
- "['cart', 'curt', 'curd', 'curs']\n",
- "['cart', 'curt', 'cure', 'lure']\n",
- "['cart', 'curt', 'cure', 'pure']\n",
- "['cart', 'curt', 'cure', 'sure']\n",
- "['cart', 'curt', 'cure', 'care']\n",
- "['cart', 'curt', 'cure', 'core']\n",
- "['cart', 'curt', 'cure', 'cube']\n",
- "['cart', 'curt', 'cure', 'cute']\n",
- "['cart', 'curt', 'cure', 'curb']\n",
- "['cart', 'curt', 'cure', 'curd']\n",
- "['cart', 'curt', 'cure', 'curl']\n",
- "['cart', 'curt', 'cure', 'curs']\n",
- "['cart', 'curt', 'curl', 'furl']\n",
- "['cart', 'curt', 'curl', 'hurl']\n",
- "['cart', 'curt', 'curl', 'purl']\n",
- "['cart', 'curt', 'curl', 'cull']\n",
- "['cart', 'curt', 'curl', 'curb']\n",
- "['cart', 'curt', 'curl', 'curd']\n",
- "['cart', 'curt', 'curl', 'cure']\n",
- "['cart', 'curt', 'curl', 'curs']\n",
- "['cart', 'curt', 'curs', 'burs']\n",
- "['cart', 'curt', 'curs', 'furs']\n",
- "['cart', 'curt', 'curs', 'ours']\n",
- "['cart', 'curt', 'curs', 'cars']\n",
- "['cart', 'curt', 'curs', 'cubs']\n",
- "['cart', 'curt', 'curs', 'cuds']\n",
- "['cart', 'curt', 'curs', 'cues']\n",
- "['cart', 'curt', 'curs', 'cums']\n",
- "['cart', 'curt', 'curs', 'cups']\n",
- "['cart', 'curt', 'curs', 'cuss']\n",
- "['cart', 'curt', 'curs', 'cuts']\n",
- "['cart', 'curt', 'curs', 'curb']\n",
- "['cart', 'curt', 'curs', 'curd']\n",
- "['cart', 'curt', 'curs', 'cure']\n",
- "['cart', 'curt', 'curs', 'curl']\n",
- "['cart', 'cant', 'pant', 'rant']\n",
- "['cart', 'cant', 'pant', 'want']\n",
- "['cart', 'cant', 'pant', 'pent']\n",
- "['cart', 'cant', 'pant', 'pint']\n",
- "['cart', 'cant', 'pant', 'punt']\n",
- "['cart', 'cant', 'pant', 'pact']\n",
- "['cart', 'cant', 'pant', 'part']\n",
- "['cart', 'cant', 'pant', 'past']\n",
- "['cart', 'cant', 'pant', 'pane']\n",
- "['cart', 'cant', 'pant', 'pang']\n",
- "['cart', 'cant', 'pant', 'pans']\n",
- "['cart', 'cant', 'rant', 'pant']\n",
- "['cart', 'cant', 'rant', 'want']\n",
- "['cart', 'cant', 'rant', 'rent']\n",
- "['cart', 'cant', 'rant', 'runt']\n",
- "['cart', 'cant', 'rant', 'raft']\n",
- "['cart', 'cant', 'rant', 'rapt']\n",
- "['cart', 'cant', 'rant', 'rang']\n",
- "['cart', 'cant', 'rant', 'rank']\n",
- "['cart', 'cant', 'want', 'pant']\n",
- "['cart', 'cant', 'want', 'rant']\n",
- "['cart', 'cant', 'want', 'went']\n",
- "['cart', 'cant', 'want', 'wont']\n",
- "['cart', 'cant', 'want', 'waft']\n",
- "['cart', 'cant', 'want', 'wait']\n",
- "['cart', 'cant', 'want', 'wart']\n",
- "['cart', 'cant', 'want', 'watt']\n",
- "['cart', 'cant', 'want', 'wand']\n",
- "['cart', 'cant', 'want', 'wane']\n",
- "['cart', 'cant', 'cent', 'bent']\n",
- "['cart', 'cant', 'cent', 'dent']\n",
- "['cart', 'cant', 'cent', 'gent']\n",
- "['cart', 'cant', 'cent', 'lent']\n",
- "['cart', 'cant', 'cent', 'pent']\n",
- "['cart', 'cant', 'cent', 'rent']\n",
- "['cart', 'cant', 'cent', 'sent']\n",
- "['cart', 'cant', 'cent', 'tent']\n",
- "['cart', 'cant', 'cent', 'vent']\n",
- "['cart', 'cant', 'cent', 'went']\n",
- "['cart', 'cant', 'cast', 'bast']\n",
- "['cart', 'cant', 'cast', 'east']\n",
- "['cart', 'cant', 'cast', 'fast']\n",
- "['cart', 'cant', 'cast', 'last']\n",
- "['cart', 'cant', 'cast', 'mast']\n",
- "['cart', 'cant', 'cast', 'past']\n",
- "['cart', 'cant', 'cast', 'vast']\n",
- "['cart', 'cant', 'cast', 'cost']\n",
- "['cart', 'cant', 'cast', 'cyst']\n",
- "['cart', 'cant', 'cast', 'case']\n",
- "['cart', 'cant', 'cast', 'cash']\n",
- "['cart', 'cant', 'cast', 'cask']\n",
- "['cart', 'cant', 'cane', 'bane']\n",
- "['cart', 'cant', 'cane', 'lane']\n",
- "['cart', 'cant', 'cane', 'mane']\n",
- "['cart', 'cant', 'cane', 'pane']\n",
- "['cart', 'cant', 'cane', 'sane']\n",
- "['cart', 'cant', 'cane', 'vane']\n",
- "['cart', 'cant', 'cane', 'wane']\n",
- "['cart', 'cant', 'cane', 'cone']\n",
- "['cart', 'cant', 'cane', 'cafe']\n",
- "['cart', 'cant', 'cane', 'cage']\n",
- "['cart', 'cant', 'cane', 'cake']\n",
- "['cart', 'cant', 'cane', 'came']\n",
- "['cart', 'cant', 'cane', 'cape']\n",
- "['cart', 'cant', 'cane', 'care']\n",
- "['cart', 'cant', 'cane', 'case']\n",
- "['cart', 'cant', 'cane', 'cave']\n",
- "['cart', 'cant', 'cane', 'cans']\n",
- "['cart', 'cant', 'cans', 'bans']\n",
- "['cart', 'cant', 'cans', 'fans']\n",
- "['cart', 'cant', 'cans', 'mans']\n",
- "['cart', 'cant', 'cans', 'pans']\n",
- "['cart', 'cant', 'cans', 'sans']\n",
- "['cart', 'cant', 'cans', 'tans']\n",
- "['cart', 'cant', 'cans', 'vans']\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "['cart', 'cant', 'cans', 'vans']"
- ]
- },
- "execution_count": 20,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "bfs_search('cart', 'vans', debug=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['cart', 'cant', 'cane', 'vane']"
- ]
- },
- "execution_count": 21,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "bfs_search('cart', 'vane')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['cart',\n",
- " 'dart',\n",
- " 'hart',\n",
- " 'mart',\n",
- " 'part',\n",
- " 'tart',\n",
- " 'wart',\n",
- " 'waft',\n",
- " 'daft',\n",
- " 'haft',\n",
- " 'raft',\n",
- " 'rift',\n",
- " 'gift',\n",
- " 'lift',\n",
- " 'sift',\n",
- " 'soft',\n",
- " 'loft',\n",
- " 'left',\n",
- " 'deft',\n",
- " 'heft',\n",
- " 'weft',\n",
- " 'welt',\n",
- " 'belt',\n",
- " 'felt',\n",
- " 'gelt',\n",
- " 'melt',\n",
- " 'pelt',\n",
- " 'peat',\n",
- " 'beat',\n",
- " 'feat',\n",
- " 'heat',\n",
- " 'meat',\n",
- " 'neat',\n",
- " 'seat',\n",
- " 'teat',\n",
- " 'that',\n",
- " 'chat',\n",
- " 'shat',\n",
- " 'what',\n",
- " 'whet',\n",
- " 'whit',\n",
- " 'chit',\n",
- " 'chic',\n",
- " 'chid',\n",
- " 'chin',\n",
- " 'shin',\n",
- " 'thin',\n",
- " 'twin',\n",
- " 'twig',\n",
- " 'swig',\n",
- " 'swag',\n",
- " 'shag',\n",
- " 'slag',\n",
- " 'flag',\n",
- " 'flog',\n",
- " 'blog',\n",
- " 'clog',\n",
- " 'slog',\n",
- " 'smog',\n",
- " 'smug',\n",
- " 'slug',\n",
- " 'plug',\n",
- " 'plum',\n",
- " 'alum',\n",
- " 'glum',\n",
- " 'slum',\n",
- " 'scum',\n",
- " 'swum',\n",
- " 'swam',\n",
- " 'scam',\n",
- " 'seam',\n",
- " 'beam',\n",
- " 'ream',\n",
- " 'team',\n",
- " 'tram',\n",
- " 'cram',\n",
- " 'dram',\n",
- " 'gram',\n",
- " 'pram',\n",
- " 'prim',\n",
- " 'brim',\n",
- " 'grim',\n",
- " 'trim',\n",
- " 'trig',\n",
- " 'brig',\n",
- " 'brag',\n",
- " 'crag',\n",
- " 'drag',\n",
- " 'drug',\n",
- " 'drub',\n",
- " 'grub',\n",
- " 'grab',\n",
- " 'crab',\n",
- " 'drab',\n",
- " 'draw',\n",
- " 'craw',\n",
- " 'claw',\n",
- " 'flaw',\n",
- " 'slaw',\n",
- " 'slew',\n",
- " 'blew',\n",
- " 'clew',\n",
- " 'flew',\n",
- " 'flow',\n",
- " 'blow',\n",
- " 'glow',\n",
- " 'slow',\n",
- " 'scow',\n",
- " 'show',\n",
- " 'chow',\n",
- " 'crow',\n",
- " 'brow',\n",
- " 'grow',\n",
- " 'prow',\n",
- " 'prod',\n",
- " 'trod',\n",
- " 'trot',\n",
- " 'toot',\n",
- " 'boot',\n",
- " 'coot',\n",
- " 'foot',\n",
- " 'hoot',\n",
- " 'loot',\n",
- " 'moot',\n",
- " 'root',\n",
- " 'soot',\n",
- " 'shot',\n",
- " 'slot',\n",
- " 'blot',\n",
- " 'clot',\n",
- " 'plot',\n",
- " 'plod',\n",
- " 'clod',\n",
- " 'clad',\n",
- " 'glad',\n",
- " 'goad',\n",
- " 'load',\n",
- " 'road',\n",
- " 'toad',\n",
- " 'toed',\n",
- " 'coed',\n",
- " 'hoed',\n",
- " 'heed',\n",
- " 'deed',\n",
- " 'feed',\n",
- " 'geed',\n",
- " 'need',\n",
- " 'peed',\n",
- " 'reed',\n",
- " 'seed',\n",
- " 'teed',\n",
- " 'weed',\n",
- " 'weld',\n",
- " 'geld',\n",
- " 'held',\n",
- " 'meld',\n",
- " 'veld',\n",
- " 'vend',\n",
- " 'bend',\n",
- " 'fend',\n",
- " 'lend',\n",
- " 'mend',\n",
- " 'rend',\n",
- " 'send',\n",
- " 'tend',\n",
- " 'wend',\n",
- " 'wand',\n",
- " 'band',\n",
- " 'hand',\n",
- " 'land',\n",
- " 'sand',\n",
- " 'said',\n",
- " 'laid',\n",
- " 'maid',\n",
- " 'paid',\n",
- " 'raid',\n",
- " 'rail',\n",
- " 'bail',\n",
- " 'fail',\n",
- " 'hail',\n",
- " 'jail',\n",
- " 'mail',\n",
- " 'nail',\n",
- " 'pail',\n",
- " 'sail',\n",
- " 'tail',\n",
- " 'wail',\n",
- " 'wall',\n",
- " 'ball',\n",
- " 'call',\n",
- " 'fall',\n",
- " 'gall',\n",
- " 'hall',\n",
- " 'mall',\n",
- " 'pall',\n",
- " 'tall',\n",
- " 'tell',\n",
- " 'bell',\n",
- " 'cell',\n",
- " 'dell',\n",
- " 'fell',\n",
- " 'hell',\n",
- " 'jell',\n",
- " 'sell',\n",
- " 'well',\n",
- " 'yell',\n",
- " 'yelp',\n",
- " 'help',\n",
- " 'kelp',\n",
- " 'keep',\n",
- " 'beep',\n",
- " 'deep',\n",
- " 'jeep',\n",
- " 'peep',\n",
- " 'seep',\n",
- " 'veep',\n",
- " 'weep',\n",
- " 'week',\n",
- " 'geek',\n",
- " 'leek',\n",
- " 'meek',\n",
- " 'peek',\n",
- " 'reek',\n",
- " 'seek',\n",
- " 'seem',\n",
- " 'deem',\n",
- " 'teem',\n",
- " 'them',\n",
- " 'thee',\n",
- " 'tree',\n",
- " 'free',\n",
- " 'flee',\n",
- " 'glee',\n",
- " 'glue',\n",
- " 'blue',\n",
- " 'clue',\n",
- " 'flue',\n",
- " 'slue',\n",
- " 'sloe',\n",
- " 'aloe',\n",
- " 'floe',\n",
- " 'flop',\n",
- " 'clop',\n",
- " 'glop',\n",
- " 'plop',\n",
- " 'slop',\n",
- " 'shop',\n",
- " 'chop',\n",
- " 'coop',\n",
- " 'goop',\n",
- " 'hoop',\n",
- " 'loop',\n",
- " 'poop',\n",
- " 'prop',\n",
- " 'crop',\n",
- " 'drop',\n",
- " 'drip',\n",
- " 'grip',\n",
- " 'trip',\n",
- " 'trap',\n",
- " 'tray',\n",
- " 'bray',\n",
- " 'dray',\n",
- " 'fray',\n",
- " 'gray',\n",
- " 'pray',\n",
- " 'play',\n",
- " 'clay',\n",
- " 'flay',\n",
- " 'slay',\n",
- " 'spay',\n",
- " 'stay',\n",
- " 'sway',\n",
- " 'away',\n",
- " 'awry',\n",
- " 'aery',\n",
- " 'eery',\n",
- " 'very',\n",
- " 'vary',\n",
- " 'nary',\n",
- " 'wary',\n",
- " 'wiry',\n",
- " 'airy',\n",
- " 'airs',\n",
- " 'firs',\n",
- " 'sirs',\n",
- " 'sics',\n",
- " 'tics',\n",
- " 'ties',\n",
- " 'dies',\n",
- " 'hies',\n",
- " 'lies',\n",
- " 'pies',\n",
- " 'vies',\n",
- " 'vied',\n",
- " 'died',\n",
- " 'hied',\n",
- " 'lied',\n",
- " 'pied',\n",
- " 'tied',\n",
- " 'tier',\n",
- " 'bier',\n",
- " 'pier',\n",
- " 'peer',\n",
- " 'beer',\n",
- " 'deer',\n",
- " 'jeer',\n",
- " 'leer',\n",
- " 'seer',\n",
- " 'veer',\n",
- " 'weer',\n",
- " 'wear',\n",
- " 'bear',\n",
- " 'dear',\n",
- " 'fear',\n",
- " 'gear',\n",
- " 'hear',\n",
- " 'near',\n",
- " 'pear',\n",
- " 'rear',\n",
- " 'sear',\n",
- " 'tear',\n",
- " 'year',\n",
- " 'yeah',\n",
- " 'yeas',\n",
- " 'leas',\n",
- " 'peas',\n",
- " 'seas',\n",
- " 'teas',\n",
- " 'tees',\n",
- " 'bees',\n",
- " 'fees',\n",
- " 'gees',\n",
- " 'lees',\n",
- " 'pees',\n",
- " 'sees',\n",
- " 'wees',\n",
- " 'woes',\n",
- " 'does',\n",
- " 'foes',\n",
- " 'goes',\n",
- " 'hoes',\n",
- " 'noes',\n",
- " 'roes',\n",
- " 'toes',\n",
- " 'togs',\n",
- " 'bogs',\n",
- " 'cogs',\n",
- " 'dogs',\n",
- " 'fogs',\n",
- " 'hogs',\n",
- " 'jogs',\n",
- " 'logs',\n",
- " 'lags',\n",
- " 'bags',\n",
- " 'fags',\n",
- " 'gags',\n",
- " 'hags',\n",
- " 'jags',\n",
- " 'nags',\n",
- " 'rags',\n",
- " 'sags',\n",
- " 'tags',\n",
- " 'wags',\n",
- " 'wigs',\n",
- " 'digs',\n",
- " 'figs',\n",
- " 'gigs',\n",
- " 'jigs',\n",
- " 'pigs',\n",
- " 'rigs',\n",
- " 'rugs',\n",
- " 'bugs',\n",
- " 'hugs',\n",
- " 'jugs',\n",
- " 'lugs',\n",
- " 'mugs',\n",
- " 'pugs',\n",
- " 'tugs',\n",
- " 'tubs',\n",
- " 'cubs',\n",
- " 'dubs',\n",
- " 'hubs',\n",
- " 'nubs',\n",
- " 'pubs',\n",
- " 'rubs',\n",
- " 'subs',\n",
- " 'sobs',\n",
- " 'bobs',\n",
- " 'cobs',\n",
- " 'fobs',\n",
- " 'gobs',\n",
- " 'hobs',\n",
- " 'jobs',\n",
- " 'lobs',\n",
- " 'mobs',\n",
- " 'robs',\n",
- " 'ribs',\n",
- " 'bibs',\n",
- " 'fibs',\n",
- " 'jibs',\n",
- " 'nibs',\n",
- " 'nabs',\n",
- " 'cabs',\n",
- " 'dabs',\n",
- " 'gabs',\n",
- " 'jabs',\n",
- " 'labs',\n",
- " 'tabs',\n",
- " 'tads',\n",
- " 'cads',\n",
- " 'dads',\n",
- " 'fads',\n",
- " 'gads',\n",
- " 'lads',\n",
- " 'mads',\n",
- " 'pads',\n",
- " 'wads',\n",
- " 'weds',\n",
- " 'beds',\n",
- " 'feds',\n",
- " 'reds',\n",
- " 'rids',\n",
- " 'aids',\n",
- " 'bids',\n",
- " 'kids',\n",
- " 'lids',\n",
- " 'lips',\n",
- " 'dips',\n",
- " 'hips',\n",
- " 'nips',\n",
- " 'pips',\n",
- " 'rips',\n",
- " 'sips',\n",
- " 'tips',\n",
- " 'yips',\n",
- " 'zips',\n",
- " 'zaps',\n",
- " 'caps',\n",
- " 'gaps',\n",
- " 'laps',\n",
- " 'maps',\n",
- " 'naps',\n",
- " 'paps',\n",
- " 'raps',\n",
- " 'saps',\n",
- " 'taps',\n",
- " 'yaps',\n",
- " 'yeps',\n",
- " 'peps',\n",
- " 'reps',\n",
- " 'refs',\n",
- " 'reis',\n",
- " 'leis',\n",
- " 'legs',\n",
- " 'begs',\n",
- " 'kegs',\n",
- " 'megs',\n",
- " 'pegs',\n",
- " 'pens',\n",
- " 'dens',\n",
- " 'fens',\n",
- " 'hens',\n",
- " 'kens',\n",
- " 'lens',\n",
- " 'tens',\n",
- " 'wens',\n",
- " 'yens',\n",
- " 'yews',\n",
- " 'hews',\n",
- " 'mews',\n",
- " 'news',\n",
- " 'pews',\n",
- " 'sews',\n",
- " 'saws',\n",
- " 'caws',\n",
- " 'haws',\n",
- " 'jaws',\n",
- " 'laws',\n",
- " 'maws',\n",
- " 'paws',\n",
- " 'yaws',\n",
- " 'yaks',\n",
- " 'oaks',\n",
- " 'oafs',\n",
- " 'oars',\n",
- " 'bars',\n",
- " 'cars',\n",
- " 'ears',\n",
- " 'jars',\n",
- " 'mars',\n",
- " 'pars',\n",
- " 'tars',\n",
- " 'wars',\n",
- " 'ways',\n",
- " 'bays',\n",
- " 'days',\n",
- " 'gays',\n",
- " 'hays',\n",
- " 'jays',\n",
- " 'lays',\n",
- " 'nays',\n",
- " 'pays',\n",
- " 'rays',\n",
- " 'says',\n",
- " 'sacs',\n",
- " 'secs',\n",
- " 'sets',\n",
- " 'bets',\n",
- " 'gets',\n",
- " 'jets',\n",
- " 'lets',\n",
- " 'nets',\n",
- " 'pets',\n",
- " 'vets',\n",
- " 'wets',\n",
- " 'wits',\n",
- " 'bits',\n",
- " 'fits',\n",
- " 'hits',\n",
- " 'kits',\n",
- " 'nits',\n",
- " 'pits',\n",
- " 'sits',\n",
- " 'tits',\n",
- " 'tats',\n",
- " 'bats',\n",
- " 'cats',\n",
- " 'eats',\n",
- " 'fats',\n",
- " 'hats',\n",
- " 'lats',\n",
- " 'mats',\n",
- " 'oats',\n",
- " 'pats',\n",
- " 'rats',\n",
- " 'vats',\n",
- " 'vans',\n",
- " 'bans',\n",
- " 'cans',\n",
- " 'fans',\n",
- " 'mans',\n",
- " 'pans',\n",
- " 'sans',\n",
- " 'tans',\n",
- " 'tins',\n",
- " 'bins',\n",
- " 'dins',\n",
- " 'fins',\n",
- " 'gins',\n",
- " 'pins',\n",
- " 'sins',\n",
- " 'wins',\n",
- " 'wind',\n",
- " 'bind',\n",
- " 'find',\n",
- " 'hind',\n",
- " 'kind',\n",
- " 'mind',\n",
- " 'rind',\n",
- " 'ring',\n",
- " 'ding',\n",
- " 'king',\n",
- " 'ping',\n",
- " 'sing',\n",
- " 'ting',\n",
- " 'wing',\n",
- " 'wine',\n",
- " 'dine',\n",
- " 'fine',\n",
- " 'line',\n",
- " 'mine',\n",
- " 'nine',\n",
- " 'pine',\n",
- " 'sine',\n",
- " 'tine',\n",
- " 'vine',\n",
- " 'vane']"
- ]
- },
- "execution_count": 22,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "dfs_search('cart', 'vane')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def astar_search(start, goal, debug=False):\n",
- " agenda = [(distance(start, goal), [start])]\n",
- " heapq.heapify(agenda)\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " _, current = heapq.heappop(agenda)\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " successors = extend(current)\n",
- " for s in successors:\n",
- " heapq.heappush(agenda, (len(current) + distance(s[-1], goal) - 1, s))\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "['cart']\n",
- "['cart', 'cant']\n",
- "['cart', 'cant', 'cane']\n",
- "['cart', 'cant', 'cane', 'vane']\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "['cart', 'cant', 'cane', 'vane']"
- ]
- },
- "execution_count": 24,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search('cart', 'vane', debug=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def astar_search_closed(start, goal, debug=False):\n",
- " agenda = [(distance(start, goal), [start])]\n",
- " heapq.heapify(agenda)\n",
- " closed = set()\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " _, current = heapq.heappop(agenda)\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " closed.add(current[-1])\n",
- " successors = extend(current, closed)\n",
- " for s in successors:\n",
- " heapq.heappush(agenda, (len(current) + distance(s[-1], goal) - 1, s))\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "['cart']\n",
- "['cart', 'cant']\n",
- "['cart', 'cant', 'cane']\n",
- "['cart', 'cant', 'cane', 'vane']\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "['cart', 'cant', 'cane', 'vane']"
- ]
- },
- "execution_count": 26,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search_closed('cart', 'vane', debug=True)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Mutually-reachable sets\n",
- "\n",
- "Find the transitive closure of the `neighbours` relation, so we can see which words can be transformed into which other words."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 77,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "94"
- ]
- },
- "execution_count": 77,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "candidates = [set([k] + neighbours[k]) for k in neighbours]\n",
- "reachables = []\n",
- "while candidates:\n",
- " current = set(candidates.pop())\n",
- " altered = False\n",
- " for other in candidates:\n",
- " if current.intersection(other):\n",
- " altered = True\n",
- " current.update(other)\n",
- " candidates.remove(other)\n",
- " if altered:\n",
- " candidates.append(current)\n",
- " else:\n",
- " reachables.append(current)\n",
- "\n",
- "len(reachables)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 78,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "2204"
- ]
- },
- "execution_count": 78,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(max(reachables, key=len))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 79,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "1"
- ]
- },
- "execution_count": 79,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(min(reachables, key=len))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 80,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "Counter({1: 75, 2: 6, 3: 7, 4: 2, 5: 2, 6: 1, 2204: 1})"
- ]
- },
- "execution_count": 80,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "collections.Counter(len(r) for r in reachables)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 81,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[5]"
- ]
- },
- "execution_count": 81,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[len(r) for r in reachables if 'abbe' in r]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 82,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[{'abbe', 'able', 'ably', 'ally', 'axle'}]"
- ]
- },
- "execution_count": 82,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[r for r in reachables if 'abbe' in r]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 83,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['buns', 'bunk', 'punk']"
- ]
- },
- "execution_count": 83,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search('buns', 'punk')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 84,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "for a in reachables:\n",
- " for b in reachables:\n",
- " if a != b:\n",
- " if not a.isdisjoint(b):\n",
- " print(a, b)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 85,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# longest_chain = []\n",
- "# with open('all-chains-4.txt', 'w', 1) as f:\n",
- "# for ws in reachables:\n",
- "# for s in ws:\n",
- "# for t in ws:\n",
- "# if s < t:\n",
- "# chain = astar_search(s, t)\n",
- "# if chain:\n",
- "# f.write('{}\\n'.format(chain))\n",
- "# if len(chain) > len(longest_chain):\n",
- "# longest_chain = chain\n",
- "\n",
- "# longest_chain"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 86,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "bigset = max(reachables, key=len)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 87,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "['late', 'lats', 'lets', 'leas', 'seas', 'seam', 'swam', 'sway']\n",
- "['leap', 'heap', 'hear', 'dear', 'deer']\n",
- "['peel', 'peek', 'perk', 'park', 'nark']\n",
- "['sing', 'sang', 'sand', 'said', 'sail', 'hail', 'haul']\n",
- "['vats', 'bats', 'bets', 'bees', 'been', 'teen', 'then', 'thin', 'this', 'thus', 'thud']\n",
- "['sues', 'sees', 'seen', 'sewn', 'hewn']\n",
- "['rash', 'bash', 'bast', 'bait', 'bail', 'hail', 'hair', 'heir']\n",
- "['apex', 'aped', 'sped', 'seed', 'deed', 'dead', 'deal', 'veal']\n",
- "['gulf', 'golf', 'gold', 'bold', 'bond', 'bony', 'tony']\n",
- "['snag', 'shag', 'shat', 'seat', 'peat', 'pent', 'pint', 'mint']\n",
- "['rife', 'rime', 'rims', 'rums', 'cums', 'cuss']\n",
- "['diss', 'kiss', 'kits']\n",
- "['gyps', 'gaps', 'gads', 'wads', 'wade', 'wide', 'tide']\n",
- "['bilk', 'bill', 'bell', 'tell', 'teal', 'tear', 'tzar']\n",
- "['logo', 'loge', 'lode', 'lade', 'jade', 'jape']\n",
- "['hunt', 'bunt', 'buns', 'nuns', 'nubs']\n",
- "['glow', 'glop', 'plop', 'prop', 'prep', 'peep', 'keep']\n",
- "['iamb', 'lamb', 'lams', 'laps', 'lips', 'pips']\n",
- "['pain', 'lain', 'laid', 'land', 'lend', 'vend', 'veld']\n",
- "['fake', 'bake', 'bare', 'bars', 'ears', 'errs', 'ergs', 'eggs', 'egos']\n"
- ]
- }
- ],
- "source": [
- "for _ in range(20):\n",
- " start, goal = random.sample(bigset, 2)\n",
- " print(astar_search_closed(start, goal))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 38,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['cops', 'coos', 'coon', 'coin', 'chin', 'thin', 'this', 'thus', 'thug']"
- ]
- },
- "execution_count": 38,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search('cops', 'thug')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 39,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[2204]"
- ]
- },
- "execution_count": 39,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[len(r) for r in reachables if 'love' in r if 'hate' in r]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 40,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['hate', 'have', 'hove', 'love']"
- ]
- },
- "execution_count": 40,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search('hate', 'love')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 41,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['wars', 'ware', 'wave', 'wove', 'love']"
- ]
- },
- "execution_count": 41,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search('wars', 'love')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 61,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 0 ns, sys: 0 ns, total: 0 ns\n",
- "Wall time: 210 µs\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "5"
- ]
- },
- "execution_count": 61,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(astar_search('wars', 'love'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 62,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 0 ns, sys: 0 ns, total: 0 ns\n",
- "Wall time: 252 µs\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "5"
- ]
- },
- "execution_count": 62,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(astar_search_closed('wars', 'love'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 63,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 24 ms, sys: 0 ns, total: 24 ms\n",
- "Wall time: 24.2 ms\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "404"
- ]
- },
- "execution_count": 63,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(dfs_search('wars', 'love'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 64,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 5min 20s, sys: 76 ms, total: 5min 20s\n",
- "Wall time: 5min 20s\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "5"
- ]
- },
- "execution_count": 64,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(bfs_search('wars', 'love'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 65,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 1.44 s, sys: 0 ns, total: 1.44 s\n",
- "Wall time: 1.43 s\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "5"
- ]
- },
- "execution_count": 65,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(bfs_search_closed('wars', 'love'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 42,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['fear', 'feat', 'fest', 'lest', 'lost', 'lose', 'love']"
- ]
- },
- "execution_count": 42,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search('fear', 'love')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 43,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['fail', 'fall', 'pall', 'pals', 'pass']"
- ]
- },
- "execution_count": 43,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search('fail', 'pass')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 44,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['star', 'soar', 'boar', 'boor', 'boon', 'born']"
- ]
- },
- "execution_count": 44,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search('star', 'born')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 45,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['open',\n",
- " 'oven',\n",
- " 'even',\n",
- " 'eves',\n",
- " 'eyes',\n",
- " 'byes',\n",
- " 'bees',\n",
- " 'begs',\n",
- " 'bags',\n",
- " 'bass',\n",
- " 'pass']"
- ]
- },
- "execution_count": 45,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search('open', 'pass')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 46,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['bass',\n",
- " 'lass',\n",
- " 'mass',\n",
- " 'sass',\n",
- " 'puss',\n",
- " 'pads',\n",
- " 'pals',\n",
- " 'pans',\n",
- " 'paps',\n",
- " 'pars',\n",
- " 'pats',\n",
- " 'paws',\n",
- " 'pays',\n",
- " 'past']"
- ]
- },
- "execution_count": 46,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "neighbours['pass']"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 47,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[1]"
- ]
- },
- "execution_count": 47,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[len(r) for r in reachables if 'exam' in r]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 48,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[2204]"
- ]
- },
- "execution_count": 48,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[len(r) for r in reachables if 'star' in r if 'born' in r]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 49,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "1 loop, best of 3: 7.9 s per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "astar_search('bats', 'exit')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 50,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "10 loops, best of 3: 141 ms per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "astar_search_closed('bats', 'exit')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 51,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['bats',\n",
- " 'bans',\n",
- " 'band',\n",
- " 'sand',\n",
- " 'said',\n",
- " 'skid',\n",
- " 'skit',\n",
- " 'smit',\n",
- " 'emit',\n",
- " 'exit']"
- ]
- },
- "execution_count": 51,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search_closed('bats', 'exit')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 88,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "{2: [['heel', 'keel'], ['wane', 'wave'], ['cell', 'sell'], ['cons', 'cobs']],\n",
- " 3: [['hank', 'haws'], ['bars', 'bets'], ['rats', 'paws'], ['lock', 'hack']],\n",
- " 4: [['rule', 'sore'], ['wavy', 'rape'], ['peas', 'ping'], ['bond', 'toll']],\n",
- " 5: [['cope', 'yowl'], ['lose', 'loci'], ['rump', 'dash'], ['four', 'dyes']],\n",
- " 6: [['boon', 'sell'], ['lots', 'pomp'], ['cola', 'turn'], ['boos', 'laid']],\n",
- " 7: [['eave', 'inns'], ['meek', 'mere'], ['keys', 'wily'], ['slam', 'yore']],\n",
- " 8: [['hack', 'flip'], ['crag', 'huge'], ['flux', 'gill'], ['play', 'busy']],\n",
- " 9: [['lacy', 'whey'], ['wren', 'rook'], ['lire', 'drip'], ['grab', 'lame']],\n",
- " 10: [['over', 'turn'], ['worn', 'anew'], ['stow', 'elks'], ['ergo', 'rich']],\n",
- " 11: [['bask', 'idea'], ['gabs', 'thud'], ['idea', 'clod'], ['mark', 'ibis']],\n",
- " 12: [['umps', 'torn'], ['futz', 'shun'], ['abut', 'face'], ['slug', 'open']],\n",
- " 13: [['umps', 'skin'], ['chum', 'rats'], ['fury', 'chum'], ['omen', 'zany']],\n",
- " 14: [['chug', 'gaff'], ['atom', 'fizz']],\n",
- " 15: [['chug', 'oxen']]}"
- ]
- },
- "execution_count": 88,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "solutions = {}\n",
- "for _ in range(10000):\n",
- " start, goal = random.sample(bigset, 2)\n",
- " solution = astar_search_closed(start, goal)\n",
- " sl = len(solution)\n",
- " if sl not in solutions:\n",
- " solutions[sl] = []\n",
- " if len(solutions[sl]) < 4:\n",
- " solutions[sl].append([start, goal])\n",
- " \n",
- "# if len(solution) >= 10:\n",
- "# solutions += [solution]\n",
- " \n",
- "solutions"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 91,
- "metadata": {},
- "outputs": [],
- "source": [
- "solutions = {2: [['heel', 'keel'], ['wane', 'wave'], ['cell', 'sell'], ['cons', 'cobs']],\n",
- " 3: [['hank', 'haws'], ['bars', 'bets'], ['rats', 'paws'], ['lock', 'hack']],\n",
- " 4: [['rule', 'sore'], ['wavy', 'rape'], ['peas', 'ping'], ['bond', 'toll']],\n",
- " 5: [['cope', 'yowl'], ['lose', 'loci'], ['rump', 'dash'], ['four', 'dyes']],\n",
- " 6: [['boon', 'sell'], ['lots', 'pomp'], ['cola', 'turn'], ['boos', 'laid']],\n",
- " 7: [['eave', 'inns'], ['meek', 'mere'], ['keys', 'wily'], ['slam', 'yore']],\n",
- " 8: [['hack', 'flip'], ['crag', 'huge'], ['flux', 'gill'], ['play', 'busy']],\n",
- " 9: [['lacy', 'whey'], ['wren', 'rook'], ['lire', 'drip'], ['grab', 'lame']],\n",
- " 10: [['over', 'turn'], ['worn', 'anew'], ['stow', 'elks'], ['ergo', 'rich']],\n",
- " 11: [['bask', 'idea'], ['gabs', 'thud'], ['idea', 'clod'], ['mark', 'ibis']],\n",
- " 12: [['umps', 'torn'], ['futz', 'shun'], ['abut', 'face'], ['slug', 'open']],\n",
- " 13: [['umps', 'skin'], ['chum', 'rats'], ['fury', 'chum'], ['omen', 'zany']],\n",
- " 14: [['chug', 'gaff'], ['atom', 'fizz'], ['chug', 'jinn'], ['amen', 'flog'],\n",
- " ['buzz', 'grog'], ['imps', 'pros']],\n",
- " 15: [['chug', 'oxen'], ['amen', 'doff']]}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 54,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "[('amen', 'doff', 15), ('chug', 'jinn', 14), ('amen', 'flog', 14)]"
- ]
- },
- "execution_count": 54,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "[(s[0], s[-1], len(s)) for s in solutions if len(s) >= 14]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 55,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "1 loop, best of 3: 360 ms per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "astar_search_closed('blab', 'amen')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 56,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 384 ms, sys: 0 ns, total: 384 ms\n",
- "Wall time: 385 ms\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "14"
- ]
- },
- "execution_count": 56,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(astar_search_closed('blab', 'amen'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 57,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 124 ms, sys: 0 ns, total: 124 ms\n",
- "Wall time: 121 ms\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "15"
- ]
- },
- "execution_count": 57,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(astar_search_closed('amen', 'doff'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 58,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 32 ms, sys: 0 ns, total: 32 ms\n",
- "Wall time: 32.4 ms\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "14"
- ]
- },
- "execution_count": 58,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(astar_search_closed('chug', 'jinn'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 59,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 16 ms, sys: 0 ns, total: 16 ms\n",
- "Wall time: 17.1 ms\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "14"
- ]
- },
- "execution_count": 59,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(astar_search_closed('amen', 'flog'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 73,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 268 ms, sys: 4 ms, total: 272 ms\n",
- "Wall time: 272 ms\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "14"
- ]
- },
- "execution_count": 73,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(astar_search_closed('buzz', 'grog'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 74,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "CPU times: user 64 ms, sys: 0 ns, total: 64 ms\n",
- "Wall time: 64.1 ms\n"
- ]
- },
- {
- "data": {
- "text/plain": [
- "14"
- ]
- },
- "execution_count": 74,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "%time len(astar_search_closed('imps', 'pros'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "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.5.2+"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
+++ /dev/null
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Word chains\n",
- "\n",
- "\"Word chain\" puzzles are where you transform one word into another, by changing one letter at a time, with all the intermediate steps being valid words. \n",
- "\n",
- "For instance, you can transform 'rash' to 'jags' like this:\n",
- "\n",
- "```\n",
- "rash\n",
- "Bash\n",
- "basS\n",
- "baGs\n",
- "Jags\n",
- "```\n",
- "\n",
- "(the capital letter is the one changed in each step).\n",
- "\n",
- "## Part 1\n",
- "\n",
- "Given this [list of words](words4.txt), what is the minimum number of steps to go from `vice` to `wars`?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "import string\n",
- "import heapq"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "2336"
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "words = [w.strip() for w in open('words4.txt').readlines()]\n",
- "len(words)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def adjacents(word):\n",
- " return [word[0:i] + l + word[i+1:]\n",
- " for i in range(len(word))\n",
- " for l in string.ascii_lowercase\n",
- " if l != word[i]]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "neighbours = {w: [n for n in adjacents(w) if n in words]\n",
- " for w in words}"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def distance(w1, w2):\n",
- " return sum(1 for i in range(len(w1))\n",
- " if w1[i] != w2[i])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# def extend(chain):\n",
- "# return [chain + [s] for s in neighbours[chain[-1]]\n",
- "# if s not in chain]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def extend(chain, closed=None):\n",
- " if closed:\n",
- " nbrs = set(neighbours[chain[-1]]) - closed\n",
- " else:\n",
- " nbrs = neighbours[chain[-1]]\n",
- " return [chain + [s] for s in nbrs\n",
- " if s not in chain]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def extend_raw(chain):\n",
- " nbrs = [w for w in adjacents(chain[-1]) if w in words]\n",
- " return [chain + [s] for s in nbrs\n",
- " if s not in chain]"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def bfs_search(start, goal, debug=False):\n",
- " agenda = [[start]]\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " current = agenda[0]\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " successors = extend(current)\n",
- " agenda = agenda[1:] + successors\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def bfs_search_closed(start, goal, debug=False):\n",
- " agenda = [[start]]\n",
- " closed = set()\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " current = agenda[0]\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " closed.add(current[-1])\n",
- " successors = extend(current, closed)\n",
- " agenda = agenda[1:] + successors\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def dfs_search(start, goal, debug=False):\n",
- " agenda = [[start]]\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " current = agenda[0]\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " successors = extend(current)\n",
- " agenda = successors + agenda[1:]\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def astar_search(start, goal, debug=False):\n",
- " agenda = [(distance(start, goal), [start])]\n",
- " heapq.heapify(agenda)\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " _, current = heapq.heappop(agenda)\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " successors = extend(current)\n",
- " for s in successors:\n",
- " heapq.heappush(agenda, (len(current) + distance(s[-1], goal) - 1, s))\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "# Uses direct lookup of successors, rather than using cached neighbours in the dict\n",
- "def astar_search_raw(start, goal, debug=False):\n",
- " agenda = [(distance(start, goal), [start])]\n",
- " heapq.heapify(agenda)\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " _, current = heapq.heappop(agenda)\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " successors = extend_raw(current) # Difference here\n",
- " for s in successors:\n",
- " heapq.heappush(agenda, (len(current) + distance(s[-1], goal) - 1, s))\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def astar_search_closed(start, goal, debug=False):\n",
- " agenda = [(distance(start, goal), [start])]\n",
- " heapq.heapify(agenda)\n",
- " closed = set()\n",
- " finished = False\n",
- " while not finished and agenda:\n",
- " _, current = heapq.heappop(agenda)\n",
- " if debug:\n",
- " print(current)\n",
- " if current[-1] == goal:\n",
- " finished = True\n",
- " else:\n",
- " closed.add(current[-1])\n",
- " successors = extend(current, closed)\n",
- " for s in successors:\n",
- " heapq.heappush(agenda, (len(current) + distance(s[-1], goal) - 1, s))\n",
- " if agenda:\n",
- " return current\n",
- " else:\n",
- " return None "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['vice', 'dice', 'dire', 'dare', 'ware', 'wars']"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search('vice', 'wars')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "['vice', 'dice', 'dire', 'dare', 'ware', 'wars']"
- ]
- },
- "execution_count": 15,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "astar_search_raw('vice', 'wars')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "6"
- ]
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(astar_search('vice', 'wars'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "6"
- ]
- },
- "execution_count": 17,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(bfs_search('vice', 'wars'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "6"
- ]
- },
- "execution_count": 20,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(bfs_search_closed('vice', 'wars'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 21,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "793"
- ]
- },
- "execution_count": 21,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(dfs_search('vice', 'wars'))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "10000 loops, best of 3: 158 µs per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "astar_search('vice', 'wars')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 23,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "100 loops, best of 3: 15.6 ms per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "astar_search_raw('vice', 'wars')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "10000 loops, best of 3: 168 µs per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "astar_search_closed('vice', 'wars')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "1 loop, best of 3: 1min 40s per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "bfs_search('vice', 'wars')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "1 loop, best of 3: 597 ms per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "bfs_search_closed('vice', 'wars')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 27,
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "10 loops, best of 3: 85.5 ms per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "dfs_search('vice', 'wars')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Part 2\n",
- "\n",
- "The example shows that `jags` is reachable in four steps from `rash`. There are 11 words one step away from `rash`: \n",
- "`bash`, `cash`, `dash`, `gash`, `hash`, `lash`, `mash`, `rasp`, `rush`, `sash`, and `wash`. \n",
- "\n",
- "There are 47 words reachable in one or two steps from `rash`. They are `base`, `bash`, `bask`, `bass`, `bast`, `bath`, `bosh`, `bush`, `case`, `cash`, `cask`, `cast`, `dash`, `dish`, `gash`, `gasp`, `gosh`, `gush`, `hash`, `hasp`, `hath`, `hush`, `lash`, `lass`, `last`, `lath`, `lush`, `mash`, `mask`, `mass`, `mast`, `math`, `mesh`, `mush`, `push`, `ramp`, `rasp`, `ruse`, `rush`, `rusk`, `rust`, `sash`, `sass`, `tush`, `wash`, `wasp`, and `wish`.\n",
- "\n",
- "There are 180 words reachable in up to three steps from `rash`.\n",
- "\n",
- "How many words are reachable in up to ten steps from `vice`?"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 28,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": [
- "def reachable_in(word, n, trim_extras=False):\n",
- " reachable = set()\n",
- " boundary = set([word])\n",
- " for i in range(n):\n",
- " extras = set()\n",
- " for w in boundary:\n",
- " extras.update(neighbours[w])\n",
- " if trim_extras:\n",
- " extras.difference_update(reachable)\n",
- " reachable.update(boundary)\n",
- " boundary = extras.copy()\n",
- " return reachable.union(extras).difference(set([word]))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 29,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(11,\n",
- " '`bash`, `cash`, `dash`, `gash`, `hash`, `lash`, `mash`, `rasp`, `rush`, `sash`, `wash`')"
- ]
- },
- "execution_count": 29,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(reachable_in('rash', 1)), ', '.join(sorted('`{}`'.format(r) for r in reachable_in('rash', 1)))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 30,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(47,\n",
- " '`base`, `bash`, `bask`, `bass`, `bast`, `bath`, `bosh`, `bush`, `case`, `cash`, `cask`, `cast`, `dash`, `dish`, `gash`, `gasp`, `gosh`, `gush`, `hash`, `hasp`, `hath`, `hush`, `lash`, `lass`, `last`, `lath`, `lush`, `mash`, `mask`, `mass`, `mast`, `math`, `mesh`, `mush`, `push`, `ramp`, `rasp`, `ruse`, `rush`, `rusk`, `rust`, `sash`, `sass`, `tush`, `wash`, `wasp`, `wish`')"
- ]
- },
- "execution_count": 30,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(reachable_in('rash', 2)), ', '.join(sorted('`{}`'.format(r) for r in reachable_in('rash', 2)))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 31,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "180"
- ]
- },
- "execution_count": 31,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(reachable_in('rash', 3))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 32,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "2195"
- ]
- },
- "execution_count": 32,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(reachable_in('rash', 10))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 33,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "2192"
- ]
- },
- "execution_count": 33,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "len(reachable_in('vice', 10))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 34,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "100 loops, best of 3: 5.82 ms per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "len(reachable_in('rash', 10))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 35,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "100 loops, best of 3: 2.75 ms per loop\n"
- ]
- }
- ],
- "source": [
- "%%timeit\n",
- "len(reachable_in('rash', 10, trim_extras=True))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "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.5.2+"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
+++ /dev/null
-abbe
-abed
-abet
-able
-ably
-abut
-aced
-aces
-ache
-achy
-acid
-acme
-acne
-acre
-acts
-adds
-adze
-aeon
-aery
-afar
-agar
-aged
-ages
-agog
-ague
-ahem
-ahoy
-aide
-aids
-ails
-aims
-airs
-airy
-ajar
-akin
-alas
-albs
-ales
-alga
-alit
-ally
-alms
-aloe
-also
-alto
-alum
-amen
-amid
-amir
-ammo
-amok
-amps
-anal
-anew
-ankh
-anon
-ante
-anti
-ants
-anus
-aped
-apes
-apex
-apse
-aqua
-arch
-arcs
-area
-ares
-aria
-arid
-arks
-arms
-army
-arts
-arty
-ashy
-asks
-asps
-atom
-atop
-auks
-aunt
-aura
-auto
-aver
-avid
-avow
-away
-awed
-awes
-awls
-awol
-awry
-axed
-axes
-axis
-axle
-axon
-ayes
-baas
-babe
-baby
-back
-bade
-bags
-bail
-bait
-bake
-bald
-bale
-balk
-ball
-balm
-band
-bane
-bang
-bani
-bank
-bans
-barb
-bard
-bare
-barf
-bark
-barn
-bars
-base
-bash
-bask
-bass
-bast
-bate
-bath
-bats
-baud
-bawl
-bays
-bead
-beak
-beam
-bean
-bear
-beat
-beau
-beck
-beds
-beef
-been
-beep
-beer
-bees
-beet
-begs
-bell
-belt
-bend
-bent
-berg
-berm
-best
-beta
-bets
-bevy
-bias
-bibs
-bide
-bids
-bier
-bike
-bile
-bilk
-bill
-bind
-bins
-bird
-bite
-bits
-blab
-blah
-bled
-blew
-blip
-blob
-bloc
-blog
-blot
-blow
-blue
-blur
-boar
-boas
-boat
-bobs
-bode
-body
-bogs
-bogy
-boil
-bola
-bold
-bole
-boll
-bolt
-bomb
-bond
-bone
-bong
-bony
-boob
-book
-boom
-boon
-boor
-boos
-boot
-bops
-bore
-born
-bosh
-boss
-both
-bout
-bowl
-bows
-boys
-bozo
-brad
-brag
-bran
-bras
-brat
-bray
-bred
-brew
-brig
-brim
-brow
-buck
-buds
-buff
-bugs
-bulb
-bulk
-bull
-bump
-bums
-bung
-bunk
-buns
-bunt
-buoy
-burg
-burn
-burp
-burr
-burs
-bury
-bush
-buss
-bust
-busy
-buts
-butt
-buys
-buzz
-byes
-byte
-cabs
-cads
-cafe
-cage
-cagy
-cake
-calf
-call
-calm
-came
-camp
-cams
-cane
-cans
-cant
-cape
-caps
-card
-care
-carp
-cars
-cart
-case
-cash
-cask
-cast
-cats
-cave
-caws
-cede
-cell
-cent
-chap
-char
-chat
-chef
-chew
-chic
-chid
-chin
-chip
-chit
-chop
-chow
-chug
-chum
-cite
-city
-clad
-clam
-clan
-clap
-claw
-clay
-clef
-clew
-clip
-clod
-clog
-clop
-clot
-cloy
-club
-clue
-coal
-coat
-coax
-cobs
-cock
-coda
-code
-cods
-coed
-cogs
-coif
-coil
-coin
-coke
-cola
-cold
-cols
-colt
-coma
-comb
-come
-cone
-conk
-cons
-cook
-cool
-coon
-coop
-coos
-coot
-cope
-cops
-copy
-cord
-core
-cork
-corm
-corn
-cost
-cosy
-cote
-cots
-coup
-cove
-cowl
-cows
-crab
-crag
-cram
-craw
-crew
-crib
-crop
-crow
-crud
-crux
-cube
-cubs
-cuds
-cued
-cues
-cuff
-cull
-cult
-cums
-cups
-curb
-curd
-cure
-curl
-curs
-curt
-cusp
-cuss
-cute
-cuts
-cyst
-czar
-dabs
-dado
-dads
-daft
-dais
-dale
-dame
-damn
-damp
-dams
-dank
-dare
-dark
-darn
-dart
-dash
-data
-date
-daub
-dawn
-days
-daze
-dead
-deaf
-deal
-dean
-dear
-debs
-debt
-deck
-deed
-deem
-deep
-deer
-deft
-defy
-deli
-dell
-demo
-dens
-dent
-deny
-desk
-dewy
-dial
-dice
-dick
-died
-dies
-diet
-digs
-dike
-dill
-dime
-dims
-dine
-ding
-dins
-dint
-dips
-dire
-dirk
-dirt
-disc
-dish
-disk
-diss
-diva
-dive
-dock
-docs
-dodo
-doer
-does
-doff
-dogs
-dole
-doll
-dolt
-dome
-done
-dons
-doom
-door
-dope
-dopy
-dork
-dorm
-dory
-dose
-dote
-doth
-dots
-dour
-dove
-down
-doze
-drab
-drag
-dram
-draw
-dray
-drew
-drip
-drop
-drub
-drug
-drum
-drys
-dual
-dubs
-duck
-duct
-dude
-duds
-duel
-dues
-duet
-duff
-duke
-dull
-duly
-dumb
-dump
-dune
-dung
-dunk
-duns
-duos
-dupe
-dusk
-dust
-duty
-dyed
-dyer
-dyes
-dyke
-each
-earl
-earn
-ears
-ease
-east
-easy
-eats
-eave
-ebbs
-echo
-ecru
-eddy
-edge
-edgy
-edit
-eels
-eery
-eggs
-egis
-egos
-eked
-ekes
-elan
-elks
-ells
-elms
-else
-emir
-emit
-emus
-ends
-envy
-eons
-epee
-epic
-eras
-ergo
-ergs
-errs
-espy
-etch
-euro
-even
-ever
-eves
-evil
-ewer
-ewes
-exam
-exec
-exes
-exit
-expo
-eyed
-eyes
-face
-fact
-fade
-fads
-fags
-fail
-fain
-fair
-fake
-fall
-fame
-fang
-fans
-fare
-farm
-fast
-fate
-fats
-faun
-fawn
-faze
-fear
-feat
-feds
-feed
-feel
-fees
-feet
-fell
-felt
-fend
-fens
-fern
-fest
-feta
-fete
-feud
-fiat
-fibs
-fief
-fife
-figs
-file
-fill
-film
-find
-fine
-fink
-fins
-fire
-firm
-firs
-fish
-fist
-fits
-five
-fizz
-flab
-flag
-flak
-flan
-flap
-flat
-flaw
-flax
-flay
-flea
-fled
-flee
-flew
-flex
-flip
-flit
-floe
-flog
-flop
-flow
-flub
-flue
-flux
-foal
-foam
-fobs
-foci
-foes
-fogs
-fogy
-foil
-fold
-folk
-fond
-font
-food
-fool
-foot
-fops
-fora
-ford
-fore
-fork
-form
-fort
-foul
-four
-fowl
-foxy
-frat
-fray
-free
-fret
-frog
-from
-fuel
-full
-fume
-fund
-funk
-furl
-furs
-fury
-fuse
-fuss
-futz
-fuze
-fuzz
-gabs
-gads
-gaff
-gage
-gags
-gain
-gait
-gala
-gale
-gall
-gals
-game
-gamy
-gang
-gape
-gaps
-garb
-gash
-gasp
-gate
-gave
-gawk
-gays
-gaze
-gear
-geed
-geek
-gees
-geez
-geld
-gels
-gelt
-gems
-gene
-gent
-germ
-gets
-gibe
-gift
-gigs
-gild
-gill
-gilt
-gins
-gird
-girl
-girt
-gist
-give
-glad
-glee
-glen
-glib
-glob
-glop
-glow
-glue
-glum
-glut
-gnat
-gnaw
-gnus
-goad
-goal
-goat
-gobs
-gods
-goes
-gold
-golf
-gone
-gong
-good
-goof
-gook
-goon
-goop
-gore
-gory
-gosh
-gout
-gown
-grab
-grad
-gram
-gray
-grew
-grey
-grid
-grim
-grin
-grip
-grit
-grog
-grow
-grub
-guff
-gulf
-gull
-gulp
-gums
-gunk
-guns
-guru
-gush
-gust
-guts
-guys
-gybe
-gyms
-gyps
-gyro
-hack
-haft
-hags
-hail
-hair
-hake
-hale
-half
-hall
-halo
-halt
-hams
-hand
-hang
-hank
-hard
-hare
-hark
-harm
-harp
-hart
-hash
-hasp
-hate
-hath
-hats
-haul
-have
-hawk
-haws
-hays
-haze
-hazy
-head
-heal
-heap
-hear
-heat
-heck
-heed
-heel
-heft
-heir
-held
-hell
-helm
-help
-hemp
-hems
-hens
-herb
-herd
-here
-hero
-hers
-hewn
-hews
-hick
-hide
-hied
-hies
-high
-hike
-hill
-hilt
-hims
-hind
-hint
-hips
-hire
-hiss
-hits
-hive
-hoax
-hobo
-hobs
-hock
-hods
-hoed
-hoes
-hogs
-hold
-hole
-holy
-home
-homy
-hone
-honk
-hood
-hoof
-hook
-hoop
-hoot
-hope
-hops
-horn
-hose
-host
-hour
-hove
-howl
-hows
-hubs
-hued
-hues
-huff
-huge
-hugs
-hula
-hulk
-hull
-hump
-hums
-hung
-hunk
-hunt
-hurl
-hurt
-hush
-husk
-huts
-hymn
-hype
-hypo
-iamb
-ibex
-ibis
-iced
-ices
-icky
-icon
-idea
-ides
-idle
-idly
-idol
-idyl
-iffy
-ikon
-ilks
-ills
-imam
-imps
-inch
-info
-inks
-inky
-inns
-into
-ions
-iota
-iris
-irks
-iron
-isle
-isms
-itch
-item
-jabs
-jack
-jade
-jags
-jail
-jamb
-jams
-jape
-jars
-jaws
-jays
-jazz
-jeep
-jeer
-jeez
-jell
-jerk
-jest
-jets
-jibe
-jibs
-jigs
-jilt
-jinn
-jinx
-jive
-jobs
-jock
-jogs
-john
-join
-joke
-jolt
-josh
-jots
-jowl
-joys
-judo
-jugs
-jump
-junk
-jury
-just
-jute
-juts
-kale
-keel
-keen
-keep
-kegs
-kelp
-kens
-kept
-kerb
-keys
-khan
-kick
-kids
-kill
-kiln
-kilo
-kilt
-kind
-king
-kink
-kiss
-kite
-kith
-kits
-kiwi
-knee
-knew
-knit
-knob
-knot
-know
-kook
-labs
-lace
-lack
-lacy
-lade
-lads
-lady
-lags
-laid
-lain
-lair
-lake
-lama
-lamb
-lame
-lamp
-lams
-land
-lane
-lank
-laps
-lard
-lark
-lash
-lass
-last
-late
-lath
-lats
-laud
-lava
-lawn
-laws
-lays
-laze
-lazy
-lead
-leaf
-leak
-lean
-leap
-leas
-leek
-leer
-lees
-left
-legs
-leis
-lend
-lens
-lent
-lept
-less
-lest
-lets
-levy
-lewd
-liar
-lice
-lick
-lids
-lied
-lief
-lien
-lies
-lieu
-life
-lift
-like
-lilt
-lily
-limb
-lime
-limn
-limo
-limp
-limy
-line
-link
-lint
-lion
-lips
-lira
-lire
-lisp
-list
-lite
-live
-load
-loaf
-loam
-loan
-lobe
-lobs
-loci
-lock
-loco
-lode
-loft
-loge
-logo
-logs
-loin
-loll
-lone
-long
-look
-loom
-loon
-loop
-loot
-lope
-lops
-lord
-lore
-lorn
-lose
-loss
-lost
-loth
-lots
-loud
-lout
-love
-lows
-luau
-lube
-luck
-lugs
-lull
-lump
-lung
-lure
-lurk
-lush
-lust
-lute
-lynx
-lyre
-mace
-made
-mads
-maid
-mail
-maim
-main
-make
-male
-mall
-malt
-mama
-mane
-mans
-many
-maps
-mare
-mark
-mars
-mart
-mash
-mask
-mass
-mast
-mate
-math
-mats
-matt
-maul
-maws
-mayo
-maze
-mead
-meal
-mean
-meat
-meek
-meet
-megs
-meld
-melt
-memo
-mend
-menu
-meow
-mere
-mesa
-mesh
-mess
-mete
-mewl
-mews
-mica
-mice
-mien
-miff
-mike
-mild
-mile
-milk
-mill
-mils
-mime
-mind
-mine
-mini
-mink
-mint
-minx
-mire
-miss
-mist
-mite
-mitt
-moan
-moat
-mobs
-mock
-mode
-mods
-mold
-mole
-moll
-moms
-monk
-mono
-mood
-moon
-moor
-moos
-moot
-mope
-mops
-more
-morn
-moss
-most
-mote
-moth
-move
-mown
-mows
-much
-muck
-muff
-mugs
-mule
-mull
-mums
-murk
-muse
-mush
-musk
-muss
-must
-mute
-mutt
-myna
-myth
-nabs
-nags
-nail
-name
-nape
-naps
-narc
-nark
-nary
-nave
-navy
-nays
-near
-neat
-neck
-need
-neon
-nerd
-nest
-nets
-news
-newt
-next
-nibs
-nice
-nick
-nigh
-nine
-nips
-nite
-nits
-node
-nods
-noel
-noes
-none
-nook
-noon
-nope
-norm
-nose
-nosh
-nosy
-note
-noun
-nous
-nova
-nubs
-nude
-nuke
-null
-numb
-nuns
-nuts
-oafs
-oaks
-oars
-oath
-oats
-obey
-obit
-oboe
-odds
-odes
-odor
-offs
-ogle
-ogre
-ohms
-oils
-oily
-oink
-okra
-oleo
-omen
-omit
-once
-ones
-only
-onto
-onus
-onyx
-oops
-ooze
-opal
-open
-opts
-opus
-oral
-orbs
-ores
-orgy
-ouch
-ours
-oust
-outs
-oval
-oven
-over
-ovum
-owed
-owes
-owls
-owns
-oxen
-pace
-pack
-pact
-pads
-page
-paid
-pail
-pain
-pair
-pale
-pall
-palm
-pals
-pane
-pang
-pans
-pant
-papa
-paps
-pare
-park
-pars
-part
-pass
-past
-pate
-path
-pats
-pave
-pawl
-pawn
-paws
-pays
-peak
-peal
-pear
-peas
-peat
-peck
-peed
-peek
-peel
-peep
-peer
-pees
-pegs
-pelt
-pens
-pent
-peon
-peps
-perk
-perm
-pert
-peso
-pest
-pets
-pews
-pica
-pick
-pied
-pier
-pies
-pigs
-pike
-pile
-pill
-pimp
-pine
-ping
-pink
-pins
-pint
-pipe
-pips
-pita
-pith
-pits
-pity
-pixy
-plan
-play
-plea
-pled
-plod
-plop
-plot
-ploy
-plug
-plum
-plus
-pock
-pods
-poem
-poet
-poke
-poky
-pole
-poll
-polo
-pols
-pomp
-pond
-pone
-pony
-pooh
-pool
-poop
-poor
-pope
-pops
-pore
-pork
-porn
-port
-pose
-posh
-post
-posy
-pots
-pour
-pout
-pram
-pray
-prep
-prey
-prig
-prim
-prod
-prof
-prom
-prop
-pros
-prow
-psst
-pubs
-puck
-puff
-pugs
-puke
-pull
-pulp
-puma
-pump
-punk
-puns
-punt
-puny
-pupa
-pups
-pure
-purl
-purr
-push
-puss
-puts
-putt
-pyre
-quad
-quay
-quid
-quip
-quit
-quiz
-race
-rack
-racy
-raft
-raga
-rage
-rags
-raid
-rail
-rain
-raja
-rake
-ramp
-rams
-rang
-rank
-rant
-rape
-raps
-rapt
-rare
-rash
-rasp
-rate
-rats
-rave
-rays
-raze
-razz
-read
-real
-ream
-reap
-rear
-redo
-reds
-reed
-reef
-reek
-reel
-refs
-rein
-reis
-rely
-rend
-rent
-reps
-rest
-revs
-rhea
-ribs
-rice
-rich
-rick
-ride
-rids
-rife
-riff
-rift
-rigs
-rile
-rill
-rime
-rims
-rind
-ring
-rink
-riot
-ripe
-rips
-rise
-risk
-rite
-road
-roam
-roan
-roar
-robe
-robs
-rock
-rode
-rods
-roes
-roil
-role
-roll
-romp
-rood
-roof
-rook
-room
-root
-rope
-rose
-rosy
-rote
-rots
-roue
-rout
-rove
-rows
-rube
-rubs
-ruby
-rude
-rued
-rues
-ruff
-rugs
-ruin
-rule
-rump
-rums
-rune
-rung
-runs
-runt
-ruse
-rush
-rusk
-rust
-ruts
-sack
-sacs
-safe
-saga
-sage
-sago
-sags
-said
-sail
-sake
-saki
-sale
-salt
-same
-sand
-sane
-sang
-sank
-sans
-saps
-sari
-sash
-sass
-sate
-save
-sawn
-saws
-says
-scab
-scad
-scam
-scan
-scar
-scat
-scow
-scud
-scum
-seal
-seam
-sear
-seas
-seat
-secs
-sect
-seed
-seek
-seem
-seen
-seep
-seer
-sees
-self
-sell
-semi
-send
-sent
-sera
-sere
-serf
-sets
-sewn
-sews
-sexy
-shad
-shag
-shah
-sham
-shat
-shed
-shes
-shim
-shin
-ship
-shod
-shoe
-shoo
-shop
-shot
-show
-shun
-shut
-sick
-sics
-side
-sift
-sigh
-sign
-silk
-sill
-silo
-silt
-sine
-sing
-sink
-sins
-sips
-sire
-sirs
-site
-sits
-size
-skew
-skid
-skim
-skin
-skip
-skis
-skit
-slab
-slag
-slam
-slap
-slat
-slaw
-slay
-sled
-slew
-slid
-slim
-slip
-slit
-slob
-sloe
-slog
-slop
-slot
-slow
-slue
-slug
-slum
-slur
-slut
-smit
-smog
-smug
-smut
-snag
-snap
-snip
-snit
-snob
-snot
-snow
-snub
-snug
-soak
-soap
-soar
-sobs
-sock
-soda
-sods
-sofa
-soft
-soil
-sold
-sole
-soli
-solo
-sols
-some
-song
-sons
-soon
-soot
-sops
-sore
-sort
-sots
-soul
-soup
-sour
-sown
-sows
-soya
-span
-spar
-spas
-spat
-spay
-spec
-sped
-spew
-spin
-spit
-spot
-spry
-spud
-spun
-spur
-stab
-stag
-star
-stay
-stem
-step
-stew
-stir
-stop
-stow
-stub
-stud
-stun
-stye
-subs
-such
-suck
-suds
-sued
-sues
-suet
-suit
-sulk
-sumo
-sump
-sums
-sung
-sunk
-suns
-sups
-sure
-surf
-swab
-swag
-swam
-swan
-swap
-swat
-sway
-swig
-swim
-swop
-swum
-sync
-tabs
-tabu
-tack
-taco
-tact
-tads
-tags
-tail
-take
-talc
-tale
-talk
-tall
-tame
-tamp
-tams
-tang
-tank
-tans
-tape
-taps
-tare
-taro
-tarp
-tars
-tart
-task
-tats
-taut
-taxi
-teak
-teal
-team
-tear
-teas
-teat
-teed
-teem
-teen
-tees
-tell
-temp
-tend
-tens
-tent
-term
-tern
-test
-text
-than
-that
-thaw
-thee
-them
-then
-they
-thin
-this
-thou
-thru
-thud
-thug
-thus
-tick
-tics
-tide
-tidy
-tied
-tier
-ties
-tiff
-tike
-tile
-till
-tilt
-time
-tine
-ting
-tins
-tint
-tiny
-tipi
-tips
-tire
-tiro
-tits
-toad
-toed
-toes
-tofu
-toga
-togs
-toil
-toke
-told
-toll
-tomb
-tome
-toms
-tone
-tong
-tons
-tony
-took
-tool
-toot
-tops
-tore
-torn
-tors
-tort
-toss
-tost
-tote
-tots
-tour
-tout
-town
-tows
-toys
-tram
-trap
-tray
-tree
-trek
-trig
-trim
-trio
-trip
-trod
-trot
-troy
-true
-tsar
-tuba
-tube
-tubs
-tuck
-tuft
-tugs
-tuna
-tune
-tuns
-turd
-turf
-turn
-tush
-tusk
-tutu
-twee
-twig
-twin
-twit
-twos
-tyke
-type
-typo
-tyre
-tyro
-tzar
-ugly
-ulna
-umps
-undo
-unit
-unto
-upon
-urea
-urge
-uric
-urns
-used
-user
-uses
-vain
-vale
-vamp
-vane
-vans
-vary
-vase
-vast
-vats
-veal
-veep
-veer
-veil
-vein
-veld
-vend
-vent
-verb
-very
-vest
-veto
-vets
-vial
-vibe
-vice
-vied
-vies
-view
-vile
-vine
-viol
-visa
-vise
-viva
-void
-vole
-volt
-vote
-vows
-wade
-wadi
-wads
-waft
-wage
-wags
-waif
-wail
-wait
-wake
-wale
-walk
-wall
-wand
-wane
-want
-ward
-ware
-warm
-warn
-warp
-wars
-wart
-wary
-wash
-wasp
-watt
-wave
-wavy
-waxy
-ways
-weak
-weal
-wean
-wear
-webs
-weds
-weed
-week
-weep
-weer
-wees
-weft
-weir
-weld
-well
-welt
-wend
-wens
-went
-wept
-were
-west
-wets
-wham
-what
-when
-whet
-whew
-whey
-whim
-whip
-whir
-whit
-whiz
-whoa
-whom
-whys
-wick
-wide
-wife
-wigs
-wiki
-wild
-wile
-will
-wilt
-wily
-wimp
-wind
-wine
-wing
-wink
-wino
-wins
-wipe
-wire
-wiry
-wise
-wish
-wisp
-wist
-with
-wits
-wive
-woes
-woke
-woks
-wolf
-womb
-wont
-wood
-woof
-wool
-woos
-word
-wore
-work
-worm
-worn
-wove
-wows
-wrap
-wren
-writ
-wuss
-yack
-yaks
-yams
-yank
-yaps
-yard
-yarn
-yawl
-yawn
-yaws
-yeah
-year
-yeas
-yell
-yelp
-yens
-yeps
-yest
-yeti
-yews
-yips
-yock
-yoga
-yogi
-yoke
-yolk
-yore
-your
-yous
-yowl
-yuck
-yuks
-yule
-yups
-zany
-zaps
-zeal
-zebu
-zeds
-zero
-zest
-zeta
-zinc
-zing
-zips
-zits
-zone
-zoom
-zoos
\ No newline at end of file
--- /dev/null
+abbe
+abed
+abet
+able
+ably
+abut
+aced
+aces
+ache
+achy
+acid
+acme
+acne
+acre
+acts
+adds
+adze
+aeon
+aery
+afar
+agar
+aged
+ages
+agog
+ague
+ahem
+ahoy
+aide
+aids
+ails
+aims
+airs
+airy
+ajar
+akin
+alas
+albs
+ales
+alga
+alit
+ally
+alms
+aloe
+also
+alto
+alum
+amen
+amid
+amir
+ammo
+amok
+amps
+anal
+anew
+ankh
+anon
+ante
+anti
+ants
+anus
+aped
+apes
+apex
+apse
+aqua
+arch
+arcs
+area
+ares
+aria
+arid
+arks
+arms
+army
+arts
+arty
+ashy
+asks
+asps
+atom
+atop
+auks
+aunt
+aura
+auto
+aver
+avid
+avow
+away
+awed
+awes
+awls
+awol
+awry
+axed
+axes
+axis
+axle
+axon
+ayes
+baas
+babe
+baby
+back
+bade
+bags
+bail
+bait
+bake
+bald
+bale
+balk
+ball
+balm
+band
+bane
+bang
+bani
+bank
+bans
+barb
+bard
+bare
+barf
+bark
+barn
+bars
+base
+bash
+bask
+bass
+bast
+bate
+bath
+bats
+baud
+bawl
+bays
+bead
+beak
+beam
+bean
+bear
+beat
+beau
+beck
+beds
+beef
+been
+beep
+beer
+bees
+beet
+begs
+bell
+belt
+bend
+bent
+berg
+berm
+best
+beta
+bets
+bevy
+bias
+bibs
+bide
+bids
+bier
+bike
+bile
+bilk
+bill
+bind
+bins
+bird
+bite
+bits
+blab
+blah
+bled
+blew
+blip
+blob
+bloc
+blog
+blot
+blow
+blue
+blur
+boar
+boas
+boat
+bobs
+bode
+body
+bogs
+bogy
+boil
+bola
+bold
+bole
+boll
+bolt
+bomb
+bond
+bone
+bong
+bony
+boob
+book
+boom
+boon
+boor
+boos
+boot
+bops
+bore
+born
+bosh
+boss
+both
+bout
+bowl
+bows
+boys
+bozo
+brad
+brag
+bran
+bras
+brat
+bray
+bred
+brew
+brig
+brim
+brow
+buck
+buds
+buff
+bugs
+bulb
+bulk
+bull
+bump
+bums
+bung
+bunk
+buns
+bunt
+buoy
+burg
+burn
+burp
+burr
+burs
+bury
+bush
+buss
+bust
+busy
+buts
+butt
+buys
+buzz
+byes
+byte
+cabs
+cads
+cafe
+cage
+cagy
+cake
+calf
+call
+calm
+came
+camp
+cams
+cane
+cans
+cant
+cape
+caps
+card
+care
+carp
+cars
+cart
+case
+cash
+cask
+cast
+cats
+cave
+caws
+cede
+cell
+cent
+chap
+char
+chat
+chef
+chew
+chic
+chid
+chin
+chip
+chit
+chop
+chow
+chug
+chum
+cite
+city
+clad
+clam
+clan
+clap
+claw
+clay
+clef
+clew
+clip
+clod
+clog
+clop
+clot
+cloy
+club
+clue
+coal
+coat
+coax
+cobs
+cock
+coda
+code
+cods
+coed
+cogs
+coif
+coil
+coin
+coke
+cola
+cold
+cols
+colt
+coma
+comb
+come
+cone
+conk
+cons
+cook
+cool
+coon
+coop
+coos
+coot
+cope
+cops
+copy
+cord
+core
+cork
+corm
+corn
+cost
+cosy
+cote
+cots
+coup
+cove
+cowl
+cows
+crab
+crag
+cram
+craw
+crew
+crib
+crop
+crow
+crud
+crux
+cube
+cubs
+cuds
+cued
+cues
+cuff
+cull
+cult
+cums
+cups
+curb
+curd
+cure
+curl
+curs
+curt
+cusp
+cuss
+cute
+cuts
+cyst
+czar
+dabs
+dado
+dads
+daft
+dais
+dale
+dame
+damn
+damp
+dams
+dank
+dare
+dark
+darn
+dart
+dash
+data
+date
+daub
+dawn
+days
+daze
+dead
+deaf
+deal
+dean
+dear
+debs
+debt
+deck
+deed
+deem
+deep
+deer
+deft
+defy
+deli
+dell
+demo
+dens
+dent
+deny
+desk
+dewy
+dial
+dice
+dick
+died
+dies
+diet
+digs
+dike
+dill
+dime
+dims
+dine
+ding
+dins
+dint
+dips
+dire
+dirk
+dirt
+disc
+dish
+disk
+diss
+diva
+dive
+dock
+docs
+dodo
+doer
+does
+doff
+dogs
+dole
+doll
+dolt
+dome
+done
+dons
+doom
+door
+dope
+dopy
+dork
+dorm
+dory
+dose
+dote
+doth
+dots
+dour
+dove
+down
+doze
+drab
+drag
+dram
+draw
+dray
+drew
+drip
+drop
+drub
+drug
+drum
+drys
+dual
+dubs
+duck
+duct
+dude
+duds
+duel
+dues
+duet
+duff
+duke
+dull
+duly
+dumb
+dump
+dune
+dung
+dunk
+duns
+duos
+dupe
+dusk
+dust
+duty
+dyed
+dyer
+dyes
+dyke
+each
+earl
+earn
+ears
+ease
+east
+easy
+eats
+eave
+ebbs
+echo
+ecru
+eddy
+edge
+edgy
+edit
+eels
+eery
+eggs
+egis
+egos
+eked
+ekes
+elan
+elks
+ells
+elms
+else
+emir
+emit
+emus
+ends
+envy
+eons
+epee
+epic
+eras
+ergo
+ergs
+errs
+espy
+etch
+euro
+even
+ever
+eves
+evil
+ewer
+ewes
+exam
+exec
+exes
+exit
+expo
+eyed
+eyes
+face
+fact
+fade
+fads
+fags
+fail
+fain
+fair
+fake
+fall
+fame
+fang
+fans
+fare
+farm
+fast
+fate
+fats
+faun
+fawn
+faze
+fear
+feat
+feds
+feed
+feel
+fees
+feet
+fell
+felt
+fend
+fens
+fern
+fest
+feta
+fete
+feud
+fiat
+fibs
+fief
+fife
+figs
+file
+fill
+film
+find
+fine
+fink
+fins
+fire
+firm
+firs
+fish
+fist
+fits
+five
+fizz
+flab
+flag
+flak
+flan
+flap
+flat
+flaw
+flax
+flay
+flea
+fled
+flee
+flew
+flex
+flip
+flit
+floe
+flog
+flop
+flow
+flub
+flue
+flux
+foal
+foam
+fobs
+foci
+foes
+fogs
+fogy
+foil
+fold
+folk
+fond
+font
+food
+fool
+foot
+fops
+fora
+ford
+fore
+fork
+form
+fort
+foul
+four
+fowl
+foxy
+frat
+fray
+free
+fret
+frog
+from
+fuel
+full
+fume
+fund
+funk
+furl
+furs
+fury
+fuse
+fuss
+futz
+fuze
+fuzz
+gabs
+gads
+gaff
+gage
+gags
+gain
+gait
+gala
+gale
+gall
+gals
+game
+gamy
+gang
+gape
+gaps
+garb
+gash
+gasp
+gate
+gave
+gawk
+gays
+gaze
+gear
+geed
+geek
+gees
+geez
+geld
+gels
+gelt
+gems
+gene
+gent
+germ
+gets
+gibe
+gift
+gigs
+gild
+gill
+gilt
+gins
+gird
+girl
+girt
+gist
+give
+glad
+glee
+glen
+glib
+glob
+glop
+glow
+glue
+glum
+glut
+gnat
+gnaw
+gnus
+goad
+goal
+goat
+gobs
+gods
+goes
+gold
+golf
+gone
+gong
+good
+goof
+gook
+goon
+goop
+gore
+gory
+gosh
+gout
+gown
+grab
+grad
+gram
+gray
+grew
+grey
+grid
+grim
+grin
+grip
+grit
+grog
+grow
+grub
+guff
+gulf
+gull
+gulp
+gums
+gunk
+guns
+guru
+gush
+gust
+guts
+guys
+gybe
+gyms
+gyps
+gyro
+hack
+haft
+hags
+hail
+hair
+hake
+hale
+half
+hall
+halo
+halt
+hams
+hand
+hang
+hank
+hard
+hare
+hark
+harm
+harp
+hart
+hash
+hasp
+hate
+hath
+hats
+haul
+have
+hawk
+haws
+hays
+haze
+hazy
+head
+heal
+heap
+hear
+heat
+heck
+heed
+heel
+heft
+heir
+held
+hell
+helm
+help
+hemp
+hems
+hens
+herb
+herd
+here
+hero
+hers
+hewn
+hews
+hick
+hide
+hied
+hies
+high
+hike
+hill
+hilt
+hims
+hind
+hint
+hips
+hire
+hiss
+hits
+hive
+hoax
+hobo
+hobs
+hock
+hods
+hoed
+hoes
+hogs
+hold
+hole
+holy
+home
+homy
+hone
+honk
+hood
+hoof
+hook
+hoop
+hoot
+hope
+hops
+horn
+hose
+host
+hour
+hove
+howl
+hows
+hubs
+hued
+hues
+huff
+huge
+hugs
+hula
+hulk
+hull
+hump
+hums
+hung
+hunk
+hunt
+hurl
+hurt
+hush
+husk
+huts
+hymn
+hype
+hypo
+iamb
+ibex
+ibis
+iced
+ices
+icky
+icon
+idea
+ides
+idle
+idly
+idol
+idyl
+iffy
+ikon
+ilks
+ills
+imam
+imps
+inch
+info
+inks
+inky
+inns
+into
+ions
+iota
+iris
+irks
+iron
+isle
+isms
+itch
+item
+jabs
+jack
+jade
+jags
+jail
+jamb
+jams
+jape
+jars
+jaws
+jays
+jazz
+jeep
+jeer
+jeez
+jell
+jerk
+jest
+jets
+jibe
+jibs
+jigs
+jilt
+jinn
+jinx
+jive
+jobs
+jock
+jogs
+john
+join
+joke
+jolt
+josh
+jots
+jowl
+joys
+judo
+jugs
+jump
+junk
+jury
+just
+jute
+juts
+kale
+keel
+keen
+keep
+kegs
+kelp
+kens
+kept
+kerb
+keys
+khan
+kick
+kids
+kill
+kiln
+kilo
+kilt
+kind
+king
+kink
+kiss
+kite
+kith
+kits
+kiwi
+knee
+knew
+knit
+knob
+knot
+know
+kook
+labs
+lace
+lack
+lacy
+lade
+lads
+lady
+lags
+laid
+lain
+lair
+lake
+lama
+lamb
+lame
+lamp
+lams
+land
+lane
+lank
+laps
+lard
+lark
+lash
+lass
+last
+late
+lath
+lats
+laud
+lava
+lawn
+laws
+lays
+laze
+lazy
+lead
+leaf
+leak
+lean
+leap
+leas
+leek
+leer
+lees
+left
+legs
+leis
+lend
+lens
+lent
+lept
+less
+lest
+lets
+levy
+lewd
+liar
+lice
+lick
+lids
+lied
+lief
+lien
+lies
+lieu
+life
+lift
+like
+lilt
+lily
+limb
+lime
+limn
+limo
+limp
+limy
+line
+link
+lint
+lion
+lips
+lira
+lire
+lisp
+list
+lite
+live
+load
+loaf
+loam
+loan
+lobe
+lobs
+loci
+lock
+loco
+lode
+loft
+loge
+logo
+logs
+loin
+loll
+lone
+long
+look
+loom
+loon
+loop
+loot
+lope
+lops
+lord
+lore
+lorn
+lose
+loss
+lost
+loth
+lots
+loud
+lout
+love
+lows
+luau
+lube
+luck
+lugs
+lull
+lump
+lung
+lure
+lurk
+lush
+lust
+lute
+lynx
+lyre
+mace
+made
+mads
+maid
+mail
+maim
+main
+make
+male
+mall
+malt
+mama
+mane
+mans
+many
+maps
+mare
+mark
+mars
+mart
+mash
+mask
+mass
+mast
+mate
+math
+mats
+matt
+maul
+maws
+mayo
+maze
+mead
+meal
+mean
+meat
+meek
+meet
+megs
+meld
+melt
+memo
+mend
+menu
+meow
+mere
+mesa
+mesh
+mess
+mete
+mewl
+mews
+mica
+mice
+mien
+miff
+mike
+mild
+mile
+milk
+mill
+mils
+mime
+mind
+mine
+mini
+mink
+mint
+minx
+mire
+miss
+mist
+mite
+mitt
+moan
+moat
+mobs
+mock
+mode
+mods
+mold
+mole
+moll
+moms
+monk
+mono
+mood
+moon
+moor
+moos
+moot
+mope
+mops
+more
+morn
+moss
+most
+mote
+moth
+move
+mown
+mows
+much
+muck
+muff
+mugs
+mule
+mull
+mums
+murk
+muse
+mush
+musk
+muss
+must
+mute
+mutt
+myna
+myth
+nabs
+nags
+nail
+name
+nape
+naps
+narc
+nark
+nary
+nave
+navy
+nays
+near
+neat
+neck
+need
+neon
+nerd
+nest
+nets
+news
+newt
+next
+nibs
+nice
+nick
+nigh
+nine
+nips
+nite
+nits
+node
+nods
+noel
+noes
+none
+nook
+noon
+nope
+norm
+nose
+nosh
+nosy
+note
+noun
+nous
+nova
+nubs
+nude
+nuke
+null
+numb
+nuns
+nuts
+oafs
+oaks
+oars
+oath
+oats
+obey
+obit
+oboe
+odds
+odes
+odor
+offs
+ogle
+ogre
+ohms
+oils
+oily
+oink
+okra
+oleo
+omen
+omit
+once
+ones
+only
+onto
+onus
+onyx
+oops
+ooze
+opal
+open
+opts
+opus
+oral
+orbs
+ores
+orgy
+ouch
+ours
+oust
+outs
+oval
+oven
+over
+ovum
+owed
+owes
+owls
+owns
+oxen
+pace
+pack
+pact
+pads
+page
+paid
+pail
+pain
+pair
+pale
+pall
+palm
+pals
+pane
+pang
+pans
+pant
+papa
+paps
+pare
+park
+pars
+part
+pass
+past
+pate
+path
+pats
+pave
+pawl
+pawn
+paws
+pays
+peak
+peal
+pear
+peas
+peat
+peck
+peed
+peek
+peel
+peep
+peer
+pees
+pegs
+pelt
+pens
+pent
+peon
+peps
+perk
+perm
+pert
+peso
+pest
+pets
+pews
+pica
+pick
+pied
+pier
+pies
+pigs
+pike
+pile
+pill
+pimp
+pine
+ping
+pink
+pins
+pint
+pipe
+pips
+pita
+pith
+pits
+pity
+pixy
+plan
+play
+plea
+pled
+plod
+plop
+plot
+ploy
+plug
+plum
+plus
+pock
+pods
+poem
+poet
+poke
+poky
+pole
+poll
+polo
+pols
+pomp
+pond
+pone
+pony
+pooh
+pool
+poop
+poor
+pope
+pops
+pore
+pork
+porn
+port
+pose
+posh
+post
+posy
+pots
+pour
+pout
+pram
+pray
+prep
+prey
+prig
+prim
+prod
+prof
+prom
+prop
+pros
+prow
+psst
+pubs
+puck
+puff
+pugs
+puke
+pull
+pulp
+puma
+pump
+punk
+puns
+punt
+puny
+pupa
+pups
+pure
+purl
+purr
+push
+puss
+puts
+putt
+pyre
+quad
+quay
+quid
+quip
+quit
+quiz
+race
+rack
+racy
+raft
+raga
+rage
+rags
+raid
+rail
+rain
+raja
+rake
+ramp
+rams
+rang
+rank
+rant
+rape
+raps
+rapt
+rare
+rash
+rasp
+rate
+rats
+rave
+rays
+raze
+razz
+read
+real
+ream
+reap
+rear
+redo
+reds
+reed
+reef
+reek
+reel
+refs
+rein
+reis
+rely
+rend
+rent
+reps
+rest
+revs
+rhea
+ribs
+rice
+rich
+rick
+ride
+rids
+rife
+riff
+rift
+rigs
+rile
+rill
+rime
+rims
+rind
+ring
+rink
+riot
+ripe
+rips
+rise
+risk
+rite
+road
+roam
+roan
+roar
+robe
+robs
+rock
+rode
+rods
+roes
+roil
+role
+roll
+romp
+rood
+roof
+rook
+room
+root
+rope
+rose
+rosy
+rote
+rots
+roue
+rout
+rove
+rows
+rube
+rubs
+ruby
+rude
+rued
+rues
+ruff
+rugs
+ruin
+rule
+rump
+rums
+rune
+rung
+runs
+runt
+ruse
+rush
+rusk
+rust
+ruts
+sack
+sacs
+safe
+saga
+sage
+sago
+sags
+said
+sail
+sake
+saki
+sale
+salt
+same
+sand
+sane
+sang
+sank
+sans
+saps
+sari
+sash
+sass
+sate
+save
+sawn
+saws
+says
+scab
+scad
+scam
+scan
+scar
+scat
+scow
+scud
+scum
+seal
+seam
+sear
+seas
+seat
+secs
+sect
+seed
+seek
+seem
+seen
+seep
+seer
+sees
+self
+sell
+semi
+send
+sent
+sera
+sere
+serf
+sets
+sewn
+sews
+sexy
+shad
+shag
+shah
+sham
+shat
+shed
+shes
+shim
+shin
+ship
+shod
+shoe
+shoo
+shop
+shot
+show
+shun
+shut
+sick
+sics
+side
+sift
+sigh
+sign
+silk
+sill
+silo
+silt
+sine
+sing
+sink
+sins
+sips
+sire
+sirs
+site
+sits
+size
+skew
+skid
+skim
+skin
+skip
+skis
+skit
+slab
+slag
+slam
+slap
+slat
+slaw
+slay
+sled
+slew
+slid
+slim
+slip
+slit
+slob
+sloe
+slog
+slop
+slot
+slow
+slue
+slug
+slum
+slur
+slut
+smit
+smog
+smug
+smut
+snag
+snap
+snip
+snit
+snob
+snot
+snow
+snub
+snug
+soak
+soap
+soar
+sobs
+sock
+soda
+sods
+sofa
+soft
+soil
+sold
+sole
+soli
+solo
+sols
+some
+song
+sons
+soon
+soot
+sops
+sore
+sort
+sots
+soul
+soup
+sour
+sown
+sows
+soya
+span
+spar
+spas
+spat
+spay
+spec
+sped
+spew
+spin
+spit
+spot
+spry
+spud
+spun
+spur
+stab
+stag
+star
+stay
+stem
+step
+stew
+stir
+stop
+stow
+stub
+stud
+stun
+stye
+subs
+such
+suck
+suds
+sued
+sues
+suet
+suit
+sulk
+sumo
+sump
+sums
+sung
+sunk
+suns
+sups
+sure
+surf
+swab
+swag
+swam
+swan
+swap
+swat
+sway
+swig
+swim
+swop
+swum
+sync
+tabs
+tabu
+tack
+taco
+tact
+tads
+tags
+tail
+take
+talc
+tale
+talk
+tall
+tame
+tamp
+tams
+tang
+tank
+tans
+tape
+taps
+tare
+taro
+tarp
+tars
+tart
+task
+tats
+taut
+taxi
+teak
+teal
+team
+tear
+teas
+teat
+teed
+teem
+teen
+tees
+tell
+temp
+tend
+tens
+tent
+term
+tern
+test
+text
+than
+that
+thaw
+thee
+them
+then
+they
+thin
+this
+thou
+thru
+thud
+thug
+thus
+tick
+tics
+tide
+tidy
+tied
+tier
+ties
+tiff
+tike
+tile
+till
+tilt
+time
+tine
+ting
+tins
+tint
+tiny
+tipi
+tips
+tire
+tiro
+tits
+toad
+toed
+toes
+tofu
+toga
+togs
+toil
+toke
+told
+toll
+tomb
+tome
+toms
+tone
+tong
+tons
+tony
+took
+tool
+toot
+tops
+tore
+torn
+tors
+tort
+toss
+tost
+tote
+tots
+tour
+tout
+town
+tows
+toys
+tram
+trap
+tray
+tree
+trek
+trig
+trim
+trio
+trip
+trod
+trot
+troy
+true
+tsar
+tuba
+tube
+tubs
+tuck
+tuft
+tugs
+tuna
+tune
+tuns
+turd
+turf
+turn
+tush
+tusk
+tutu
+twee
+twig
+twin
+twit
+twos
+tyke
+type
+typo
+tyre
+tyro
+tzar
+ugly
+ulna
+umps
+undo
+unit
+unto
+upon
+urea
+urge
+uric
+urns
+used
+user
+uses
+vain
+vale
+vamp
+vane
+vans
+vary
+vase
+vast
+vats
+veal
+veep
+veer
+veil
+vein
+veld
+vend
+vent
+verb
+very
+vest
+veto
+vets
+vial
+vibe
+vice
+vied
+vies
+view
+vile
+vine
+viol
+visa
+vise
+viva
+void
+vole
+volt
+vote
+vows
+wade
+wadi
+wads
+waft
+wage
+wags
+waif
+wail
+wait
+wake
+wale
+walk
+wall
+wand
+wane
+want
+ward
+ware
+warm
+warn
+warp
+wars
+wart
+wary
+wash
+wasp
+watt
+wave
+wavy
+waxy
+ways
+weak
+weal
+wean
+wear
+webs
+weds
+weed
+week
+weep
+weer
+wees
+weft
+weir
+weld
+well
+welt
+wend
+wens
+went
+wept
+were
+west
+wets
+wham
+what
+when
+whet
+whew
+whey
+whim
+whip
+whir
+whit
+whiz
+whoa
+whom
+whys
+wick
+wide
+wife
+wigs
+wiki
+wild
+wile
+will
+wilt
+wily
+wimp
+wind
+wine
+wing
+wink
+wino
+wins
+wipe
+wire
+wiry
+wise
+wish
+wisp
+wist
+with
+wits
+wive
+woes
+woke
+woks
+wolf
+womb
+wont
+wood
+woof
+wool
+woos
+word
+wore
+work
+worm
+worn
+wove
+wows
+wrap
+wren
+writ
+wuss
+yack
+yaks
+yams
+yank
+yaps
+yard
+yarn
+yawl
+yawn
+yaws
+yeah
+year
+yeas
+yell
+yelp
+yens
+yeps
+yest
+yeti
+yews
+yips
+yock
+yoga
+yogi
+yoke
+yolk
+yore
+your
+yous
+yowl
+yuck
+yuks
+yule
+yups
+zany
+zaps
+zeal
+zebu
+zeds
+zero
+zest
+zeta
+zinc
+zing
+zips
+zits
+zone
+zoom
+zoos
\ No newline at end of file
--- /dev/null
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "import unicodedata\n",
+ "import string"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "unaccent_specials = ''.maketrans({\"’\": \"'\", '“': '\"', '”': '\"'})"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def unaccent(text):\n",
+ " translated_text = text.translate(unaccent_specials)\n",
+ " return unicodedata.normalize('NFKD', translated_text).\\\n",
+ " encode('ascii', 'ignore').\\\n",
+ " decode('utf-8')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def only_lower(text):\n",
+ " return all((c in string.ascii_lowercase) for c in text)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "/usr/share/dict/british-english\n",
+ "find: ‘/usr/share/doc/google-chrome-stable’: Permission denied\n",
+ "/usr/share/man/man5/british-english.5.gz\n"
+ ]
+ }
+ ],
+ "source": [
+ "# !find /usr -type f -iname 'british-english*'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "total 2.3M\r\n",
+ "drwxr-xr-x 2 root root 4.0K Dec 29 12:37 .\r\n",
+ "drwxr-xr-x 640 root root 20K Apr 13 17:05 ..\r\n",
+ "-rw-r--r-- 1 root root 917K Oct 23 2011 american-english\r\n",
+ "-rw-r--r-- 1 root root 917K Oct 23 2011 british-english\r\n",
+ "-rw-r--r-- 1 root root 467K Aug 25 2016 cracklib-small\r\n",
+ "-rw-r--r-- 1 root root 199 Aug 29 2016 README.select-wordlist\r\n",
+ "lrwxrwxrwx 1 root root 30 Nov 10 2014 words -> /etc/dictionaries-common/words\r\n",
+ "lrwxrwxrwx 1 root root 16 Jun 18 2014 words.pre-dictionaries-common -> american-english\r\n"
+ ]
+ }
+ ],
+ "source": [
+ "# !ls -lah /usr/share/dict"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def rude(word):\n",
+ " return any(w in word \n",
+ " for w in 'piss shit cunt fuck arse crap fart jizz whore bitch'.split())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "rude('fucks')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def words_with_len(n):\n",
+ " return [unaccent(w.strip()) for w in open('/usr/share/dict/british-english').readlines()\n",
+ " if only_lower(unaccent(w.strip()))\n",
+ " if len(unaccent(w.strip())) == n\n",
+ " if not rude(unaccent(w.strip()))]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2336 4-letter words\n",
+ "4566 5-letter words\n",
+ "7223 6-letter words\n"
+ ]
+ }
+ ],
+ "source": [
+ "dicts = {}\n",
+ "\n",
+ "for n in [4, 5, 6]:\n",
+ " dicts[n] = words_with_len(n)\n",
+ " print('{} {}-letter words'.format(len(dicts[n]), n))\n",
+ " with open('words{}.txt'.format(n), 'w') as f:\n",
+ " f.write('\\n'.join(sorted(set(dicts[n]))))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "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.5.2+"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
--- /dev/null
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "import string\n",
+ "import heapq\n",
+ "import collections\n",
+ "import random"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2336"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "words = [w.strip() for w in open('words4.txt').readlines()]\n",
+ "len(words)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['abbe',\n",
+ " 'abed',\n",
+ " 'abet',\n",
+ " 'able',\n",
+ " 'ably',\n",
+ " 'abut',\n",
+ " 'aced',\n",
+ " 'aces',\n",
+ " 'ache',\n",
+ " 'achy']"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "words[:10]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def adjacents_explicit(word):\n",
+ " neighbours = []\n",
+ " for i in range(len(word)):\n",
+ " for l in string.ascii_lowercase:\n",
+ " if l != word[i]:\n",
+ " neighbours.append(word[0:i] + l + word[i+1:])\n",
+ " return neighbours"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def adjacents(word):\n",
+ " return [word[0:i] + l + word[i+1:]\n",
+ " for i in range(len(word))\n",
+ " for l in string.ascii_lowercase\n",
+ " if l != word[i]]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "neighbours = {w: [n for n in adjacents(w) if n in words]\n",
+ " for w in words}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['able']"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "neighbours['abbe']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['axle', 'abbe', 'ably']"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "neighbours['able']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def distance(w1, w2):\n",
+ " return sum(1 for i in range(len(w1))\n",
+ " if w1[i] != w2[i])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0"
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "distance('abbe', 'abbe')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def extend(chain, closed=None):\n",
+ " if closed:\n",
+ " nbrs = set(neighbours[chain[-1]]) - closed\n",
+ " else:\n",
+ " nbrs = neighbours[chain[-1]]\n",
+ " return [chain + [s] for s in nbrs\n",
+ " if s not in chain]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[['abbe', 'able']]"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "extend(['abbe'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[['abbe', 'able', 'axle'], ['abbe', 'able', 'ably']]"
+ ]
+ },
+ "execution_count": 13,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "extend(['abbe', 'able'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[['abbe', 'able', 'ably', 'ally']]"
+ ]
+ },
+ "execution_count": 14,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "extend(['abbe', 'able', 'ably'])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def bfs_search(start, goal, debug=False):\n",
+ " agenda = [[start]]\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " current = agenda[0]\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " successors = extend(current)\n",
+ " agenda = agenda[1:] + successors\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def bfs_search_closed(start, goal, debug=False):\n",
+ " agenda = [[start]]\n",
+ " closed = set()\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " current = agenda[0]\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " closed.add(current[-1])\n",
+ " successors = extend(current, closed)\n",
+ " agenda = agenda[1:] + successors\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['abbe']\n",
+ "['abbe', 'able']\n",
+ "['abbe', 'able', 'axle']\n",
+ "['abbe', 'able', 'ably']\n",
+ "['abbe', 'able', 'ably', 'ally']\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "['abbe', 'able', 'ably', 'ally']"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bfs_search('abbe', 'ally', debug=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def dfs_search(start, goal, debug=False):\n",
+ " agenda = [[start]]\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " current = agenda[0]\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " successors = extend(current)\n",
+ " agenda = successors + agenda[1:]\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['abbe']\n",
+ "['abbe', 'able']\n",
+ "['abbe', 'able', 'axle']\n",
+ "['abbe', 'able', 'ably']\n",
+ "['abbe', 'able', 'ably', 'ally']\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "['abbe', 'able', 'ably', 'ally']"
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dfs_search('abbe', 'ally', debug=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['cart']\n",
+ "['cart', 'dart']\n",
+ "['cart', 'hart']\n",
+ "['cart', 'mart']\n",
+ "['cart', 'part']\n",
+ "['cart', 'tart']\n",
+ "['cart', 'wart']\n",
+ "['cart', 'curt']\n",
+ "['cart', 'cant']\n",
+ "['cart', 'cast']\n",
+ "['cart', 'card']\n",
+ "['cart', 'care']\n",
+ "['cart', 'carp']\n",
+ "['cart', 'cars']\n",
+ "['cart', 'dart', 'hart']\n",
+ "['cart', 'dart', 'mart']\n",
+ "['cart', 'dart', 'part']\n",
+ "['cart', 'dart', 'tart']\n",
+ "['cart', 'dart', 'wart']\n",
+ "['cart', 'dart', 'dirt']\n",
+ "['cart', 'dart', 'daft']\n",
+ "['cart', 'dart', 'dare']\n",
+ "['cart', 'dart', 'dark']\n",
+ "['cart', 'dart', 'darn']\n",
+ "['cart', 'hart', 'dart']\n",
+ "['cart', 'hart', 'mart']\n",
+ "['cart', 'hart', 'part']\n",
+ "['cart', 'hart', 'tart']\n",
+ "['cart', 'hart', 'wart']\n",
+ "['cart', 'hart', 'hurt']\n",
+ "['cart', 'hart', 'haft']\n",
+ "['cart', 'hart', 'halt']\n",
+ "['cart', 'hart', 'hard']\n",
+ "['cart', 'hart', 'hare']\n",
+ "['cart', 'hart', 'hark']\n",
+ "['cart', 'hart', 'harm']\n",
+ "['cart', 'hart', 'harp']\n",
+ "['cart', 'mart', 'dart']\n",
+ "['cart', 'mart', 'hart']\n",
+ "['cart', 'mart', 'part']\n",
+ "['cart', 'mart', 'tart']\n",
+ "['cart', 'mart', 'wart']\n",
+ "['cart', 'mart', 'malt']\n",
+ "['cart', 'mart', 'mast']\n",
+ "['cart', 'mart', 'matt']\n",
+ "['cart', 'mart', 'mare']\n",
+ "['cart', 'mart', 'mark']\n",
+ "['cart', 'mart', 'mars']\n",
+ "['cart', 'part', 'dart']\n",
+ "['cart', 'part', 'hart']\n",
+ "['cart', 'part', 'mart']\n",
+ "['cart', 'part', 'tart']\n",
+ "['cart', 'part', 'wart']\n",
+ "['cart', 'part', 'pert']\n",
+ "['cart', 'part', 'port']\n",
+ "['cart', 'part', 'pact']\n",
+ "['cart', 'part', 'pant']\n",
+ "['cart', 'part', 'past']\n",
+ "['cart', 'part', 'pare']\n",
+ "['cart', 'part', 'park']\n",
+ "['cart', 'part', 'pars']\n",
+ "['cart', 'tart', 'dart']\n",
+ "['cart', 'tart', 'hart']\n",
+ "['cart', 'tart', 'mart']\n",
+ "['cart', 'tart', 'part']\n",
+ "['cart', 'tart', 'wart']\n",
+ "['cart', 'tart', 'tort']\n",
+ "['cart', 'tart', 'tact']\n",
+ "['cart', 'tart', 'taut']\n",
+ "['cart', 'tart', 'tare']\n",
+ "['cart', 'tart', 'taro']\n",
+ "['cart', 'tart', 'tarp']\n",
+ "['cart', 'tart', 'tars']\n",
+ "['cart', 'wart', 'dart']\n",
+ "['cart', 'wart', 'hart']\n",
+ "['cart', 'wart', 'mart']\n",
+ "['cart', 'wart', 'part']\n",
+ "['cart', 'wart', 'tart']\n",
+ "['cart', 'wart', 'waft']\n",
+ "['cart', 'wart', 'wait']\n",
+ "['cart', 'wart', 'want']\n",
+ "['cart', 'wart', 'watt']\n",
+ "['cart', 'wart', 'ward']\n",
+ "['cart', 'wart', 'ware']\n",
+ "['cart', 'wart', 'warm']\n",
+ "['cart', 'wart', 'warn']\n",
+ "['cart', 'wart', 'warp']\n",
+ "['cart', 'wart', 'wars']\n",
+ "['cart', 'wart', 'wary']\n",
+ "['cart', 'curt', 'hurt']\n",
+ "['cart', 'curt', 'cult']\n",
+ "['cart', 'curt', 'curb']\n",
+ "['cart', 'curt', 'curd']\n",
+ "['cart', 'curt', 'cure']\n",
+ "['cart', 'curt', 'curl']\n",
+ "['cart', 'curt', 'curs']\n",
+ "['cart', 'cant', 'pant']\n",
+ "['cart', 'cant', 'rant']\n",
+ "['cart', 'cant', 'want']\n",
+ "['cart', 'cant', 'cent']\n",
+ "['cart', 'cant', 'cast']\n",
+ "['cart', 'cant', 'cane']\n",
+ "['cart', 'cant', 'cans']\n",
+ "['cart', 'cast', 'bast']\n",
+ "['cart', 'cast', 'east']\n",
+ "['cart', 'cast', 'fast']\n",
+ "['cart', 'cast', 'last']\n",
+ "['cart', 'cast', 'mast']\n",
+ "['cart', 'cast', 'past']\n",
+ "['cart', 'cast', 'vast']\n",
+ "['cart', 'cast', 'cost']\n",
+ "['cart', 'cast', 'cyst']\n",
+ "['cart', 'cast', 'cant']\n",
+ "['cart', 'cast', 'case']\n",
+ "['cart', 'cast', 'cash']\n",
+ "['cart', 'cast', 'cask']\n",
+ "['cart', 'card', 'bard']\n",
+ "['cart', 'card', 'hard']\n",
+ "['cart', 'card', 'lard']\n",
+ "['cart', 'card', 'ward']\n",
+ "['cart', 'card', 'yard']\n",
+ "['cart', 'card', 'cord']\n",
+ "['cart', 'card', 'curd']\n",
+ "['cart', 'card', 'care']\n",
+ "['cart', 'card', 'carp']\n",
+ "['cart', 'card', 'cars']\n",
+ "['cart', 'care', 'bare']\n",
+ "['cart', 'care', 'dare']\n",
+ "['cart', 'care', 'fare']\n",
+ "['cart', 'care', 'hare']\n",
+ "['cart', 'care', 'mare']\n",
+ "['cart', 'care', 'pare']\n",
+ "['cart', 'care', 'rare']\n",
+ "['cart', 'care', 'tare']\n",
+ "['cart', 'care', 'ware']\n",
+ "['cart', 'care', 'core']\n",
+ "['cart', 'care', 'cure']\n",
+ "['cart', 'care', 'cafe']\n",
+ "['cart', 'care', 'cage']\n",
+ "['cart', 'care', 'cake']\n",
+ "['cart', 'care', 'came']\n",
+ "['cart', 'care', 'cane']\n",
+ "['cart', 'care', 'cape']\n",
+ "['cart', 'care', 'case']\n",
+ "['cart', 'care', 'cave']\n",
+ "['cart', 'care', 'card']\n",
+ "['cart', 'care', 'carp']\n",
+ "['cart', 'care', 'cars']\n",
+ "['cart', 'carp', 'harp']\n",
+ "['cart', 'carp', 'tarp']\n",
+ "['cart', 'carp', 'warp']\n",
+ "['cart', 'carp', 'camp']\n",
+ "['cart', 'carp', 'card']\n",
+ "['cart', 'carp', 'care']\n",
+ "['cart', 'carp', 'cars']\n",
+ "['cart', 'cars', 'bars']\n",
+ "['cart', 'cars', 'ears']\n",
+ "['cart', 'cars', 'jars']\n",
+ "['cart', 'cars', 'mars']\n",
+ "['cart', 'cars', 'oars']\n",
+ "['cart', 'cars', 'pars']\n",
+ "['cart', 'cars', 'tars']\n",
+ "['cart', 'cars', 'wars']\n",
+ "['cart', 'cars', 'curs']\n",
+ "['cart', 'cars', 'cabs']\n",
+ "['cart', 'cars', 'cads']\n",
+ "['cart', 'cars', 'cams']\n",
+ "['cart', 'cars', 'cans']\n",
+ "['cart', 'cars', 'caps']\n",
+ "['cart', 'cars', 'cats']\n",
+ "['cart', 'cars', 'caws']\n",
+ "['cart', 'cars', 'card']\n",
+ "['cart', 'cars', 'care']\n",
+ "['cart', 'cars', 'carp']\n",
+ "['cart', 'dart', 'hart', 'mart']\n",
+ "['cart', 'dart', 'hart', 'part']\n",
+ "['cart', 'dart', 'hart', 'tart']\n",
+ "['cart', 'dart', 'hart', 'wart']\n",
+ "['cart', 'dart', 'hart', 'hurt']\n",
+ "['cart', 'dart', 'hart', 'haft']\n",
+ "['cart', 'dart', 'hart', 'halt']\n",
+ "['cart', 'dart', 'hart', 'hard']\n",
+ "['cart', 'dart', 'hart', 'hare']\n",
+ "['cart', 'dart', 'hart', 'hark']\n",
+ "['cart', 'dart', 'hart', 'harm']\n",
+ "['cart', 'dart', 'hart', 'harp']\n",
+ "['cart', 'dart', 'mart', 'hart']\n",
+ "['cart', 'dart', 'mart', 'part']\n",
+ "['cart', 'dart', 'mart', 'tart']\n",
+ "['cart', 'dart', 'mart', 'wart']\n",
+ "['cart', 'dart', 'mart', 'malt']\n",
+ "['cart', 'dart', 'mart', 'mast']\n",
+ "['cart', 'dart', 'mart', 'matt']\n",
+ "['cart', 'dart', 'mart', 'mare']\n",
+ "['cart', 'dart', 'mart', 'mark']\n",
+ "['cart', 'dart', 'mart', 'mars']\n",
+ "['cart', 'dart', 'part', 'hart']\n",
+ "['cart', 'dart', 'part', 'mart']\n",
+ "['cart', 'dart', 'part', 'tart']\n",
+ "['cart', 'dart', 'part', 'wart']\n",
+ "['cart', 'dart', 'part', 'pert']\n",
+ "['cart', 'dart', 'part', 'port']\n",
+ "['cart', 'dart', 'part', 'pact']\n",
+ "['cart', 'dart', 'part', 'pant']\n",
+ "['cart', 'dart', 'part', 'past']\n",
+ "['cart', 'dart', 'part', 'pare']\n",
+ "['cart', 'dart', 'part', 'park']\n",
+ "['cart', 'dart', 'part', 'pars']\n",
+ "['cart', 'dart', 'tart', 'hart']\n",
+ "['cart', 'dart', 'tart', 'mart']\n",
+ "['cart', 'dart', 'tart', 'part']\n",
+ "['cart', 'dart', 'tart', 'wart']\n",
+ "['cart', 'dart', 'tart', 'tort']\n",
+ "['cart', 'dart', 'tart', 'tact']\n",
+ "['cart', 'dart', 'tart', 'taut']\n",
+ "['cart', 'dart', 'tart', 'tare']\n",
+ "['cart', 'dart', 'tart', 'taro']\n",
+ "['cart', 'dart', 'tart', 'tarp']\n",
+ "['cart', 'dart', 'tart', 'tars']\n",
+ "['cart', 'dart', 'wart', 'hart']\n",
+ "['cart', 'dart', 'wart', 'mart']\n",
+ "['cart', 'dart', 'wart', 'part']\n",
+ "['cart', 'dart', 'wart', 'tart']\n",
+ "['cart', 'dart', 'wart', 'waft']\n",
+ "['cart', 'dart', 'wart', 'wait']\n",
+ "['cart', 'dart', 'wart', 'want']\n",
+ "['cart', 'dart', 'wart', 'watt']\n",
+ "['cart', 'dart', 'wart', 'ward']\n",
+ "['cart', 'dart', 'wart', 'ware']\n",
+ "['cart', 'dart', 'wart', 'warm']\n",
+ "['cart', 'dart', 'wart', 'warn']\n",
+ "['cart', 'dart', 'wart', 'warp']\n",
+ "['cart', 'dart', 'wart', 'wars']\n",
+ "['cart', 'dart', 'wart', 'wary']\n",
+ "['cart', 'dart', 'dirt', 'girt']\n",
+ "['cart', 'dart', 'dirt', 'diet']\n",
+ "['cart', 'dart', 'dirt', 'dint']\n",
+ "['cart', 'dart', 'dirt', 'dire']\n",
+ "['cart', 'dart', 'dirt', 'dirk']\n",
+ "['cart', 'dart', 'daft', 'haft']\n",
+ "['cart', 'dart', 'daft', 'raft']\n",
+ "['cart', 'dart', 'daft', 'waft']\n",
+ "['cart', 'dart', 'daft', 'deft']\n",
+ "['cart', 'dart', 'dare', 'bare']\n",
+ "['cart', 'dart', 'dare', 'care']\n",
+ "['cart', 'dart', 'dare', 'fare']\n",
+ "['cart', 'dart', 'dare', 'hare']\n",
+ "['cart', 'dart', 'dare', 'mare']\n",
+ "['cart', 'dart', 'dare', 'pare']\n",
+ "['cart', 'dart', 'dare', 'rare']\n",
+ "['cart', 'dart', 'dare', 'tare']\n",
+ "['cart', 'dart', 'dare', 'ware']\n",
+ "['cart', 'dart', 'dare', 'dire']\n",
+ "['cart', 'dart', 'dare', 'dale']\n",
+ "['cart', 'dart', 'dare', 'dame']\n",
+ "['cart', 'dart', 'dare', 'date']\n",
+ "['cart', 'dart', 'dare', 'daze']\n",
+ "['cart', 'dart', 'dare', 'dark']\n",
+ "['cart', 'dart', 'dare', 'darn']\n",
+ "['cart', 'dart', 'dark', 'bark']\n",
+ "['cart', 'dart', 'dark', 'hark']\n",
+ "['cart', 'dart', 'dark', 'lark']\n",
+ "['cart', 'dart', 'dark', 'mark']\n",
+ "['cart', 'dart', 'dark', 'nark']\n",
+ "['cart', 'dart', 'dark', 'park']\n",
+ "['cart', 'dart', 'dark', 'dirk']\n",
+ "['cart', 'dart', 'dark', 'dork']\n",
+ "['cart', 'dart', 'dark', 'dank']\n",
+ "['cart', 'dart', 'dark', 'dare']\n",
+ "['cart', 'dart', 'dark', 'darn']\n",
+ "['cart', 'dart', 'darn', 'barn']\n",
+ "['cart', 'dart', 'darn', 'earn']\n",
+ "['cart', 'dart', 'darn', 'warn']\n",
+ "['cart', 'dart', 'darn', 'yarn']\n",
+ "['cart', 'dart', 'darn', 'damn']\n",
+ "['cart', 'dart', 'darn', 'dawn']\n",
+ "['cart', 'dart', 'darn', 'dare']\n",
+ "['cart', 'dart', 'darn', 'dark']\n",
+ "['cart', 'hart', 'dart', 'mart']\n",
+ "['cart', 'hart', 'dart', 'part']\n",
+ "['cart', 'hart', 'dart', 'tart']\n",
+ "['cart', 'hart', 'dart', 'wart']\n",
+ "['cart', 'hart', 'dart', 'dirt']\n",
+ "['cart', 'hart', 'dart', 'daft']\n",
+ "['cart', 'hart', 'dart', 'dare']\n",
+ "['cart', 'hart', 'dart', 'dark']\n",
+ "['cart', 'hart', 'dart', 'darn']\n",
+ "['cart', 'hart', 'mart', 'dart']\n",
+ "['cart', 'hart', 'mart', 'part']\n",
+ "['cart', 'hart', 'mart', 'tart']\n",
+ "['cart', 'hart', 'mart', 'wart']\n",
+ "['cart', 'hart', 'mart', 'malt']\n",
+ "['cart', 'hart', 'mart', 'mast']\n",
+ "['cart', 'hart', 'mart', 'matt']\n",
+ "['cart', 'hart', 'mart', 'mare']\n",
+ "['cart', 'hart', 'mart', 'mark']\n",
+ "['cart', 'hart', 'mart', 'mars']\n",
+ "['cart', 'hart', 'part', 'dart']\n",
+ "['cart', 'hart', 'part', 'mart']\n",
+ "['cart', 'hart', 'part', 'tart']\n",
+ "['cart', 'hart', 'part', 'wart']\n",
+ "['cart', 'hart', 'part', 'pert']\n",
+ "['cart', 'hart', 'part', 'port']\n",
+ "['cart', 'hart', 'part', 'pact']\n",
+ "['cart', 'hart', 'part', 'pant']\n",
+ "['cart', 'hart', 'part', 'past']\n",
+ "['cart', 'hart', 'part', 'pare']\n",
+ "['cart', 'hart', 'part', 'park']\n",
+ "['cart', 'hart', 'part', 'pars']\n",
+ "['cart', 'hart', 'tart', 'dart']\n",
+ "['cart', 'hart', 'tart', 'mart']\n",
+ "['cart', 'hart', 'tart', 'part']\n",
+ "['cart', 'hart', 'tart', 'wart']\n",
+ "['cart', 'hart', 'tart', 'tort']\n",
+ "['cart', 'hart', 'tart', 'tact']\n",
+ "['cart', 'hart', 'tart', 'taut']\n",
+ "['cart', 'hart', 'tart', 'tare']\n",
+ "['cart', 'hart', 'tart', 'taro']\n",
+ "['cart', 'hart', 'tart', 'tarp']\n",
+ "['cart', 'hart', 'tart', 'tars']\n",
+ "['cart', 'hart', 'wart', 'dart']\n",
+ "['cart', 'hart', 'wart', 'mart']\n",
+ "['cart', 'hart', 'wart', 'part']\n",
+ "['cart', 'hart', 'wart', 'tart']\n",
+ "['cart', 'hart', 'wart', 'waft']\n",
+ "['cart', 'hart', 'wart', 'wait']\n",
+ "['cart', 'hart', 'wart', 'want']\n",
+ "['cart', 'hart', 'wart', 'watt']\n",
+ "['cart', 'hart', 'wart', 'ward']\n",
+ "['cart', 'hart', 'wart', 'ware']\n",
+ "['cart', 'hart', 'wart', 'warm']\n",
+ "['cart', 'hart', 'wart', 'warn']\n",
+ "['cart', 'hart', 'wart', 'warp']\n",
+ "['cart', 'hart', 'wart', 'wars']\n",
+ "['cart', 'hart', 'wart', 'wary']\n",
+ "['cart', 'hart', 'hurt', 'curt']\n",
+ "['cart', 'hart', 'hurt', 'hunt']\n",
+ "['cart', 'hart', 'hurt', 'hurl']\n",
+ "['cart', 'hart', 'haft', 'daft']\n",
+ "['cart', 'hart', 'haft', 'raft']\n",
+ "['cart', 'hart', 'haft', 'waft']\n",
+ "['cart', 'hart', 'haft', 'heft']\n",
+ "['cart', 'hart', 'haft', 'halt']\n",
+ "['cart', 'hart', 'halt', 'malt']\n",
+ "['cart', 'hart', 'halt', 'salt']\n",
+ "['cart', 'hart', 'halt', 'hilt']\n",
+ "['cart', 'hart', 'halt', 'haft']\n",
+ "['cart', 'hart', 'halt', 'hale']\n",
+ "['cart', 'hart', 'halt', 'half']\n",
+ "['cart', 'hart', 'halt', 'hall']\n",
+ "['cart', 'hart', 'halt', 'halo']\n",
+ "['cart', 'hart', 'hard', 'bard']\n",
+ "['cart', 'hart', 'hard', 'card']\n",
+ "['cart', 'hart', 'hard', 'lard']\n",
+ "['cart', 'hart', 'hard', 'ward']\n",
+ "['cart', 'hart', 'hard', 'yard']\n",
+ "['cart', 'hart', 'hard', 'herd']\n",
+ "['cart', 'hart', 'hard', 'hand']\n",
+ "['cart', 'hart', 'hard', 'hare']\n",
+ "['cart', 'hart', 'hard', 'hark']\n",
+ "['cart', 'hart', 'hard', 'harm']\n",
+ "['cart', 'hart', 'hard', 'harp']\n",
+ "['cart', 'hart', 'hare', 'bare']\n",
+ "['cart', 'hart', 'hare', 'care']\n",
+ "['cart', 'hart', 'hare', 'dare']\n",
+ "['cart', 'hart', 'hare', 'fare']\n",
+ "['cart', 'hart', 'hare', 'mare']\n",
+ "['cart', 'hart', 'hare', 'pare']\n",
+ "['cart', 'hart', 'hare', 'rare']\n",
+ "['cart', 'hart', 'hare', 'tare']\n",
+ "['cart', 'hart', 'hare', 'ware']\n",
+ "['cart', 'hart', 'hare', 'here']\n",
+ "['cart', 'hart', 'hare', 'hire']\n",
+ "['cart', 'hart', 'hare', 'hake']\n",
+ "['cart', 'hart', 'hare', 'hale']\n",
+ "['cart', 'hart', 'hare', 'hate']\n",
+ "['cart', 'hart', 'hare', 'have']\n",
+ "['cart', 'hart', 'hare', 'haze']\n",
+ "['cart', 'hart', 'hare', 'hard']\n",
+ "['cart', 'hart', 'hare', 'hark']\n",
+ "['cart', 'hart', 'hare', 'harm']\n",
+ "['cart', 'hart', 'hare', 'harp']\n",
+ "['cart', 'hart', 'hark', 'bark']\n",
+ "['cart', 'hart', 'hark', 'dark']\n",
+ "['cart', 'hart', 'hark', 'lark']\n",
+ "['cart', 'hart', 'hark', 'mark']\n",
+ "['cart', 'hart', 'hark', 'nark']\n",
+ "['cart', 'hart', 'hark', 'park']\n",
+ "['cart', 'hart', 'hark', 'hack']\n",
+ "['cart', 'hart', 'hark', 'hank']\n",
+ "['cart', 'hart', 'hark', 'hawk']\n",
+ "['cart', 'hart', 'hark', 'hard']\n",
+ "['cart', 'hart', 'hark', 'hare']\n",
+ "['cart', 'hart', 'hark', 'harm']\n",
+ "['cart', 'hart', 'hark', 'harp']\n",
+ "['cart', 'hart', 'harm', 'farm']\n",
+ "['cart', 'hart', 'harm', 'warm']\n",
+ "['cart', 'hart', 'harm', 'hard']\n",
+ "['cart', 'hart', 'harm', 'hare']\n",
+ "['cart', 'hart', 'harm', 'hark']\n",
+ "['cart', 'hart', 'harm', 'harp']\n",
+ "['cart', 'hart', 'harp', 'carp']\n",
+ "['cart', 'hart', 'harp', 'tarp']\n",
+ "['cart', 'hart', 'harp', 'warp']\n",
+ "['cart', 'hart', 'harp', 'hasp']\n",
+ "['cart', 'hart', 'harp', 'hard']\n",
+ "['cart', 'hart', 'harp', 'hare']\n",
+ "['cart', 'hart', 'harp', 'hark']\n",
+ "['cart', 'hart', 'harp', 'harm']\n",
+ "['cart', 'mart', 'dart', 'hart']\n",
+ "['cart', 'mart', 'dart', 'part']\n",
+ "['cart', 'mart', 'dart', 'tart']\n",
+ "['cart', 'mart', 'dart', 'wart']\n",
+ "['cart', 'mart', 'dart', 'dirt']\n",
+ "['cart', 'mart', 'dart', 'daft']\n",
+ "['cart', 'mart', 'dart', 'dare']\n",
+ "['cart', 'mart', 'dart', 'dark']\n",
+ "['cart', 'mart', 'dart', 'darn']\n",
+ "['cart', 'mart', 'hart', 'dart']\n",
+ "['cart', 'mart', 'hart', 'part']\n",
+ "['cart', 'mart', 'hart', 'tart']\n",
+ "['cart', 'mart', 'hart', 'wart']\n",
+ "['cart', 'mart', 'hart', 'hurt']\n",
+ "['cart', 'mart', 'hart', 'haft']\n",
+ "['cart', 'mart', 'hart', 'halt']\n",
+ "['cart', 'mart', 'hart', 'hard']\n",
+ "['cart', 'mart', 'hart', 'hare']\n",
+ "['cart', 'mart', 'hart', 'hark']\n",
+ "['cart', 'mart', 'hart', 'harm']\n",
+ "['cart', 'mart', 'hart', 'harp']\n",
+ "['cart', 'mart', 'part', 'dart']\n",
+ "['cart', 'mart', 'part', 'hart']\n",
+ "['cart', 'mart', 'part', 'tart']\n",
+ "['cart', 'mart', 'part', 'wart']\n",
+ "['cart', 'mart', 'part', 'pert']\n",
+ "['cart', 'mart', 'part', 'port']\n",
+ "['cart', 'mart', 'part', 'pact']\n",
+ "['cart', 'mart', 'part', 'pant']\n",
+ "['cart', 'mart', 'part', 'past']\n",
+ "['cart', 'mart', 'part', 'pare']\n",
+ "['cart', 'mart', 'part', 'park']\n",
+ "['cart', 'mart', 'part', 'pars']\n",
+ "['cart', 'mart', 'tart', 'dart']\n",
+ "['cart', 'mart', 'tart', 'hart']\n",
+ "['cart', 'mart', 'tart', 'part']\n",
+ "['cart', 'mart', 'tart', 'wart']\n",
+ "['cart', 'mart', 'tart', 'tort']\n",
+ "['cart', 'mart', 'tart', 'tact']\n",
+ "['cart', 'mart', 'tart', 'taut']\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['cart', 'mart', 'tart', 'tare']\n",
+ "['cart', 'mart', 'tart', 'taro']\n",
+ "['cart', 'mart', 'tart', 'tarp']\n",
+ "['cart', 'mart', 'tart', 'tars']\n",
+ "['cart', 'mart', 'wart', 'dart']\n",
+ "['cart', 'mart', 'wart', 'hart']\n",
+ "['cart', 'mart', 'wart', 'part']\n",
+ "['cart', 'mart', 'wart', 'tart']\n",
+ "['cart', 'mart', 'wart', 'waft']\n",
+ "['cart', 'mart', 'wart', 'wait']\n",
+ "['cart', 'mart', 'wart', 'want']\n",
+ "['cart', 'mart', 'wart', 'watt']\n",
+ "['cart', 'mart', 'wart', 'ward']\n",
+ "['cart', 'mart', 'wart', 'ware']\n",
+ "['cart', 'mart', 'wart', 'warm']\n",
+ "['cart', 'mart', 'wart', 'warn']\n",
+ "['cart', 'mart', 'wart', 'warp']\n",
+ "['cart', 'mart', 'wart', 'wars']\n",
+ "['cart', 'mart', 'wart', 'wary']\n",
+ "['cart', 'mart', 'malt', 'halt']\n",
+ "['cart', 'mart', 'malt', 'salt']\n",
+ "['cart', 'mart', 'malt', 'melt']\n",
+ "['cart', 'mart', 'malt', 'mast']\n",
+ "['cart', 'mart', 'malt', 'matt']\n",
+ "['cart', 'mart', 'malt', 'male']\n",
+ "['cart', 'mart', 'malt', 'mall']\n",
+ "['cart', 'mart', 'mast', 'bast']\n",
+ "['cart', 'mart', 'mast', 'cast']\n",
+ "['cart', 'mart', 'mast', 'east']\n",
+ "['cart', 'mart', 'mast', 'fast']\n",
+ "['cart', 'mart', 'mast', 'last']\n",
+ "['cart', 'mart', 'mast', 'past']\n",
+ "['cart', 'mart', 'mast', 'vast']\n",
+ "['cart', 'mart', 'mast', 'mist']\n",
+ "['cart', 'mart', 'mast', 'most']\n",
+ "['cart', 'mart', 'mast', 'must']\n",
+ "['cart', 'mart', 'mast', 'malt']\n",
+ "['cart', 'mart', 'mast', 'matt']\n",
+ "['cart', 'mart', 'mast', 'mash']\n",
+ "['cart', 'mart', 'mast', 'mask']\n",
+ "['cart', 'mart', 'mast', 'mass']\n",
+ "['cart', 'mart', 'matt', 'watt']\n",
+ "['cart', 'mart', 'matt', 'mitt']\n",
+ "['cart', 'mart', 'matt', 'mutt']\n",
+ "['cart', 'mart', 'matt', 'malt']\n",
+ "['cart', 'mart', 'matt', 'mast']\n",
+ "['cart', 'mart', 'matt', 'mate']\n",
+ "['cart', 'mart', 'matt', 'math']\n",
+ "['cart', 'mart', 'matt', 'mats']\n",
+ "['cart', 'mart', 'mare', 'bare']\n",
+ "['cart', 'mart', 'mare', 'care']\n",
+ "['cart', 'mart', 'mare', 'dare']\n",
+ "['cart', 'mart', 'mare', 'fare']\n",
+ "['cart', 'mart', 'mare', 'hare']\n",
+ "['cart', 'mart', 'mare', 'pare']\n",
+ "['cart', 'mart', 'mare', 'rare']\n",
+ "['cart', 'mart', 'mare', 'tare']\n",
+ "['cart', 'mart', 'mare', 'ware']\n",
+ "['cart', 'mart', 'mare', 'mere']\n",
+ "['cart', 'mart', 'mare', 'mire']\n",
+ "['cart', 'mart', 'mare', 'more']\n",
+ "['cart', 'mart', 'mare', 'mace']\n",
+ "['cart', 'mart', 'mare', 'made']\n",
+ "['cart', 'mart', 'mare', 'make']\n",
+ "['cart', 'mart', 'mare', 'male']\n",
+ "['cart', 'mart', 'mare', 'mane']\n",
+ "['cart', 'mart', 'mare', 'mate']\n",
+ "['cart', 'mart', 'mare', 'maze']\n",
+ "['cart', 'mart', 'mare', 'mark']\n",
+ "['cart', 'mart', 'mare', 'mars']\n",
+ "['cart', 'mart', 'mark', 'bark']\n",
+ "['cart', 'mart', 'mark', 'dark']\n",
+ "['cart', 'mart', 'mark', 'hark']\n",
+ "['cart', 'mart', 'mark', 'lark']\n",
+ "['cart', 'mart', 'mark', 'nark']\n",
+ "['cart', 'mart', 'mark', 'park']\n",
+ "['cart', 'mart', 'mark', 'murk']\n",
+ "['cart', 'mart', 'mark', 'mask']\n",
+ "['cart', 'mart', 'mark', 'mare']\n",
+ "['cart', 'mart', 'mark', 'mars']\n",
+ "['cart', 'mart', 'mars', 'bars']\n",
+ "['cart', 'mart', 'mars', 'cars']\n",
+ "['cart', 'mart', 'mars', 'ears']\n",
+ "['cart', 'mart', 'mars', 'jars']\n",
+ "['cart', 'mart', 'mars', 'oars']\n",
+ "['cart', 'mart', 'mars', 'pars']\n",
+ "['cart', 'mart', 'mars', 'tars']\n",
+ "['cart', 'mart', 'mars', 'wars']\n",
+ "['cart', 'mart', 'mars', 'mads']\n",
+ "['cart', 'mart', 'mars', 'mans']\n",
+ "['cart', 'mart', 'mars', 'maps']\n",
+ "['cart', 'mart', 'mars', 'mass']\n",
+ "['cart', 'mart', 'mars', 'mats']\n",
+ "['cart', 'mart', 'mars', 'maws']\n",
+ "['cart', 'mart', 'mars', 'mare']\n",
+ "['cart', 'mart', 'mars', 'mark']\n",
+ "['cart', 'part', 'dart', 'hart']\n",
+ "['cart', 'part', 'dart', 'mart']\n",
+ "['cart', 'part', 'dart', 'tart']\n",
+ "['cart', 'part', 'dart', 'wart']\n",
+ "['cart', 'part', 'dart', 'dirt']\n",
+ "['cart', 'part', 'dart', 'daft']\n",
+ "['cart', 'part', 'dart', 'dare']\n",
+ "['cart', 'part', 'dart', 'dark']\n",
+ "['cart', 'part', 'dart', 'darn']\n",
+ "['cart', 'part', 'hart', 'dart']\n",
+ "['cart', 'part', 'hart', 'mart']\n",
+ "['cart', 'part', 'hart', 'tart']\n",
+ "['cart', 'part', 'hart', 'wart']\n",
+ "['cart', 'part', 'hart', 'hurt']\n",
+ "['cart', 'part', 'hart', 'haft']\n",
+ "['cart', 'part', 'hart', 'halt']\n",
+ "['cart', 'part', 'hart', 'hard']\n",
+ "['cart', 'part', 'hart', 'hare']\n",
+ "['cart', 'part', 'hart', 'hark']\n",
+ "['cart', 'part', 'hart', 'harm']\n",
+ "['cart', 'part', 'hart', 'harp']\n",
+ "['cart', 'part', 'mart', 'dart']\n",
+ "['cart', 'part', 'mart', 'hart']\n",
+ "['cart', 'part', 'mart', 'tart']\n",
+ "['cart', 'part', 'mart', 'wart']\n",
+ "['cart', 'part', 'mart', 'malt']\n",
+ "['cart', 'part', 'mart', 'mast']\n",
+ "['cart', 'part', 'mart', 'matt']\n",
+ "['cart', 'part', 'mart', 'mare']\n",
+ "['cart', 'part', 'mart', 'mark']\n",
+ "['cart', 'part', 'mart', 'mars']\n",
+ "['cart', 'part', 'tart', 'dart']\n",
+ "['cart', 'part', 'tart', 'hart']\n",
+ "['cart', 'part', 'tart', 'mart']\n",
+ "['cart', 'part', 'tart', 'wart']\n",
+ "['cart', 'part', 'tart', 'tort']\n",
+ "['cart', 'part', 'tart', 'tact']\n",
+ "['cart', 'part', 'tart', 'taut']\n",
+ "['cart', 'part', 'tart', 'tare']\n",
+ "['cart', 'part', 'tart', 'taro']\n",
+ "['cart', 'part', 'tart', 'tarp']\n",
+ "['cart', 'part', 'tart', 'tars']\n",
+ "['cart', 'part', 'wart', 'dart']\n",
+ "['cart', 'part', 'wart', 'hart']\n",
+ "['cart', 'part', 'wart', 'mart']\n",
+ "['cart', 'part', 'wart', 'tart']\n",
+ "['cart', 'part', 'wart', 'waft']\n",
+ "['cart', 'part', 'wart', 'wait']\n",
+ "['cart', 'part', 'wart', 'want']\n",
+ "['cart', 'part', 'wart', 'watt']\n",
+ "['cart', 'part', 'wart', 'ward']\n",
+ "['cart', 'part', 'wart', 'ware']\n",
+ "['cart', 'part', 'wart', 'warm']\n",
+ "['cart', 'part', 'wart', 'warn']\n",
+ "['cart', 'part', 'wart', 'warp']\n",
+ "['cart', 'part', 'wart', 'wars']\n",
+ "['cart', 'part', 'wart', 'wary']\n",
+ "['cart', 'part', 'pert', 'port']\n",
+ "['cart', 'part', 'pert', 'peat']\n",
+ "['cart', 'part', 'pert', 'pelt']\n",
+ "['cart', 'part', 'pert', 'pent']\n",
+ "['cart', 'part', 'pert', 'pest']\n",
+ "['cart', 'part', 'pert', 'perk']\n",
+ "['cart', 'part', 'pert', 'perm']\n",
+ "['cart', 'part', 'port', 'fort']\n",
+ "['cart', 'part', 'port', 'sort']\n",
+ "['cart', 'part', 'port', 'tort']\n",
+ "['cart', 'part', 'port', 'pert']\n",
+ "['cart', 'part', 'port', 'poet']\n",
+ "['cart', 'part', 'port', 'post']\n",
+ "['cart', 'part', 'port', 'pout']\n",
+ "['cart', 'part', 'port', 'pore']\n",
+ "['cart', 'part', 'port', 'pork']\n",
+ "['cart', 'part', 'port', 'porn']\n",
+ "['cart', 'part', 'pact', 'fact']\n",
+ "['cart', 'part', 'pact', 'tact']\n",
+ "['cart', 'part', 'pact', 'pant']\n",
+ "['cart', 'part', 'pact', 'past']\n",
+ "['cart', 'part', 'pact', 'pace']\n",
+ "['cart', 'part', 'pact', 'pack']\n",
+ "['cart', 'part', 'pant', 'cant']\n",
+ "['cart', 'part', 'pant', 'rant']\n",
+ "['cart', 'part', 'pant', 'want']\n",
+ "['cart', 'part', 'pant', 'pent']\n",
+ "['cart', 'part', 'pant', 'pint']\n",
+ "['cart', 'part', 'pant', 'punt']\n",
+ "['cart', 'part', 'pant', 'pact']\n",
+ "['cart', 'part', 'pant', 'past']\n",
+ "['cart', 'part', 'pant', 'pane']\n",
+ "['cart', 'part', 'pant', 'pang']\n",
+ "['cart', 'part', 'pant', 'pans']\n",
+ "['cart', 'part', 'past', 'bast']\n",
+ "['cart', 'part', 'past', 'cast']\n",
+ "['cart', 'part', 'past', 'east']\n",
+ "['cart', 'part', 'past', 'fast']\n",
+ "['cart', 'part', 'past', 'last']\n",
+ "['cart', 'part', 'past', 'mast']\n",
+ "['cart', 'part', 'past', 'vast']\n",
+ "['cart', 'part', 'past', 'pest']\n",
+ "['cart', 'part', 'past', 'post']\n",
+ "['cart', 'part', 'past', 'psst']\n",
+ "['cart', 'part', 'past', 'pact']\n",
+ "['cart', 'part', 'past', 'pant']\n",
+ "['cart', 'part', 'past', 'pass']\n",
+ "['cart', 'part', 'pare', 'bare']\n",
+ "['cart', 'part', 'pare', 'care']\n",
+ "['cart', 'part', 'pare', 'dare']\n",
+ "['cart', 'part', 'pare', 'fare']\n",
+ "['cart', 'part', 'pare', 'hare']\n",
+ "['cart', 'part', 'pare', 'mare']\n",
+ "['cart', 'part', 'pare', 'rare']\n",
+ "['cart', 'part', 'pare', 'tare']\n",
+ "['cart', 'part', 'pare', 'ware']\n",
+ "['cart', 'part', 'pare', 'pore']\n",
+ "['cart', 'part', 'pare', 'pure']\n",
+ "['cart', 'part', 'pare', 'pyre']\n",
+ "['cart', 'part', 'pare', 'pace']\n",
+ "['cart', 'part', 'pare', 'page']\n",
+ "['cart', 'part', 'pare', 'pale']\n",
+ "['cart', 'part', 'pare', 'pane']\n",
+ "['cart', 'part', 'pare', 'pate']\n",
+ "['cart', 'part', 'pare', 'pave']\n",
+ "['cart', 'part', 'pare', 'park']\n",
+ "['cart', 'part', 'pare', 'pars']\n",
+ "['cart', 'part', 'park', 'bark']\n",
+ "['cart', 'part', 'park', 'dark']\n",
+ "['cart', 'part', 'park', 'hark']\n",
+ "['cart', 'part', 'park', 'lark']\n",
+ "['cart', 'part', 'park', 'mark']\n",
+ "['cart', 'part', 'park', 'nark']\n",
+ "['cart', 'part', 'park', 'perk']\n",
+ "['cart', 'part', 'park', 'pork']\n",
+ "['cart', 'part', 'park', 'pack']\n",
+ "['cart', 'part', 'park', 'pare']\n",
+ "['cart', 'part', 'park', 'pars']\n",
+ "['cart', 'part', 'pars', 'bars']\n",
+ "['cart', 'part', 'pars', 'cars']\n",
+ "['cart', 'part', 'pars', 'ears']\n",
+ "['cart', 'part', 'pars', 'jars']\n",
+ "['cart', 'part', 'pars', 'mars']\n",
+ "['cart', 'part', 'pars', 'oars']\n",
+ "['cart', 'part', 'pars', 'tars']\n",
+ "['cart', 'part', 'pars', 'wars']\n",
+ "['cart', 'part', 'pars', 'pads']\n",
+ "['cart', 'part', 'pars', 'pals']\n",
+ "['cart', 'part', 'pars', 'pans']\n",
+ "['cart', 'part', 'pars', 'paps']\n",
+ "['cart', 'part', 'pars', 'pass']\n",
+ "['cart', 'part', 'pars', 'pats']\n",
+ "['cart', 'part', 'pars', 'paws']\n",
+ "['cart', 'part', 'pars', 'pays']\n",
+ "['cart', 'part', 'pars', 'pare']\n",
+ "['cart', 'part', 'pars', 'park']\n",
+ "['cart', 'tart', 'dart', 'hart']\n",
+ "['cart', 'tart', 'dart', 'mart']\n",
+ "['cart', 'tart', 'dart', 'part']\n",
+ "['cart', 'tart', 'dart', 'wart']\n",
+ "['cart', 'tart', 'dart', 'dirt']\n",
+ "['cart', 'tart', 'dart', 'daft']\n",
+ "['cart', 'tart', 'dart', 'dare']\n",
+ "['cart', 'tart', 'dart', 'dark']\n",
+ "['cart', 'tart', 'dart', 'darn']\n",
+ "['cart', 'tart', 'hart', 'dart']\n",
+ "['cart', 'tart', 'hart', 'mart']\n",
+ "['cart', 'tart', 'hart', 'part']\n",
+ "['cart', 'tart', 'hart', 'wart']\n",
+ "['cart', 'tart', 'hart', 'hurt']\n",
+ "['cart', 'tart', 'hart', 'haft']\n",
+ "['cart', 'tart', 'hart', 'halt']\n",
+ "['cart', 'tart', 'hart', 'hard']\n",
+ "['cart', 'tart', 'hart', 'hare']\n",
+ "['cart', 'tart', 'hart', 'hark']\n",
+ "['cart', 'tart', 'hart', 'harm']\n",
+ "['cart', 'tart', 'hart', 'harp']\n",
+ "['cart', 'tart', 'mart', 'dart']\n",
+ "['cart', 'tart', 'mart', 'hart']\n",
+ "['cart', 'tart', 'mart', 'part']\n",
+ "['cart', 'tart', 'mart', 'wart']\n",
+ "['cart', 'tart', 'mart', 'malt']\n",
+ "['cart', 'tart', 'mart', 'mast']\n",
+ "['cart', 'tart', 'mart', 'matt']\n",
+ "['cart', 'tart', 'mart', 'mare']\n",
+ "['cart', 'tart', 'mart', 'mark']\n",
+ "['cart', 'tart', 'mart', 'mars']\n",
+ "['cart', 'tart', 'part', 'dart']\n",
+ "['cart', 'tart', 'part', 'hart']\n",
+ "['cart', 'tart', 'part', 'mart']\n",
+ "['cart', 'tart', 'part', 'wart']\n",
+ "['cart', 'tart', 'part', 'pert']\n",
+ "['cart', 'tart', 'part', 'port']\n",
+ "['cart', 'tart', 'part', 'pact']\n",
+ "['cart', 'tart', 'part', 'pant']\n",
+ "['cart', 'tart', 'part', 'past']\n",
+ "['cart', 'tart', 'part', 'pare']\n",
+ "['cart', 'tart', 'part', 'park']\n",
+ "['cart', 'tart', 'part', 'pars']\n",
+ "['cart', 'tart', 'wart', 'dart']\n",
+ "['cart', 'tart', 'wart', 'hart']\n",
+ "['cart', 'tart', 'wart', 'mart']\n",
+ "['cart', 'tart', 'wart', 'part']\n",
+ "['cart', 'tart', 'wart', 'waft']\n",
+ "['cart', 'tart', 'wart', 'wait']\n",
+ "['cart', 'tart', 'wart', 'want']\n",
+ "['cart', 'tart', 'wart', 'watt']\n",
+ "['cart', 'tart', 'wart', 'ward']\n",
+ "['cart', 'tart', 'wart', 'ware']\n",
+ "['cart', 'tart', 'wart', 'warm']\n",
+ "['cart', 'tart', 'wart', 'warn']\n",
+ "['cart', 'tart', 'wart', 'warp']\n",
+ "['cart', 'tart', 'wart', 'wars']\n",
+ "['cart', 'tart', 'wart', 'wary']\n",
+ "['cart', 'tart', 'tort', 'fort']\n",
+ "['cart', 'tart', 'tort', 'port']\n",
+ "['cart', 'tart', 'tort', 'sort']\n",
+ "['cart', 'tart', 'tort', 'toot']\n",
+ "['cart', 'tart', 'tort', 'tost']\n",
+ "['cart', 'tart', 'tort', 'tout']\n",
+ "['cart', 'tart', 'tort', 'tore']\n",
+ "['cart', 'tart', 'tort', 'torn']\n",
+ "['cart', 'tart', 'tort', 'tors']\n",
+ "['cart', 'tart', 'tact', 'fact']\n",
+ "['cart', 'tart', 'tact', 'pact']\n",
+ "['cart', 'tart', 'tact', 'taut']\n",
+ "['cart', 'tart', 'tact', 'tack']\n",
+ "['cart', 'tart', 'tact', 'taco']\n",
+ "['cart', 'tart', 'taut', 'tout']\n",
+ "['cart', 'tart', 'taut', 'tact']\n",
+ "['cart', 'tart', 'tare', 'bare']\n",
+ "['cart', 'tart', 'tare', 'care']\n",
+ "['cart', 'tart', 'tare', 'dare']\n",
+ "['cart', 'tart', 'tare', 'fare']\n",
+ "['cart', 'tart', 'tare', 'hare']\n",
+ "['cart', 'tart', 'tare', 'mare']\n",
+ "['cart', 'tart', 'tare', 'pare']\n",
+ "['cart', 'tart', 'tare', 'rare']\n",
+ "['cart', 'tart', 'tare', 'ware']\n",
+ "['cart', 'tart', 'tare', 'tire']\n",
+ "['cart', 'tart', 'tare', 'tore']\n",
+ "['cart', 'tart', 'tare', 'tyre']\n",
+ "['cart', 'tart', 'tare', 'take']\n",
+ "['cart', 'tart', 'tare', 'tale']\n",
+ "['cart', 'tart', 'tare', 'tame']\n",
+ "['cart', 'tart', 'tare', 'tape']\n",
+ "['cart', 'tart', 'tare', 'taro']\n",
+ "['cart', 'tart', 'tare', 'tarp']\n",
+ "['cart', 'tart', 'tare', 'tars']\n",
+ "['cart', 'tart', 'taro', 'tiro']\n",
+ "['cart', 'tart', 'taro', 'tyro']\n",
+ "['cart', 'tart', 'taro', 'taco']\n",
+ "['cart', 'tart', 'taro', 'tare']\n",
+ "['cart', 'tart', 'taro', 'tarp']\n",
+ "['cart', 'tart', 'taro', 'tars']\n",
+ "['cart', 'tart', 'tarp', 'carp']\n",
+ "['cart', 'tart', 'tarp', 'harp']\n",
+ "['cart', 'tart', 'tarp', 'warp']\n",
+ "['cart', 'tart', 'tarp', 'tamp']\n",
+ "['cart', 'tart', 'tarp', 'tare']\n",
+ "['cart', 'tart', 'tarp', 'taro']\n",
+ "['cart', 'tart', 'tarp', 'tars']\n",
+ "['cart', 'tart', 'tars', 'bars']\n",
+ "['cart', 'tart', 'tars', 'cars']\n",
+ "['cart', 'tart', 'tars', 'ears']\n",
+ "['cart', 'tart', 'tars', 'jars']\n",
+ "['cart', 'tart', 'tars', 'mars']\n",
+ "['cart', 'tart', 'tars', 'oars']\n",
+ "['cart', 'tart', 'tars', 'pars']\n",
+ "['cart', 'tart', 'tars', 'wars']\n",
+ "['cart', 'tart', 'tars', 'tors']\n",
+ "['cart', 'tart', 'tars', 'tabs']\n",
+ "['cart', 'tart', 'tars', 'tads']\n",
+ "['cart', 'tart', 'tars', 'tags']\n",
+ "['cart', 'tart', 'tars', 'tams']\n",
+ "['cart', 'tart', 'tars', 'tans']\n",
+ "['cart', 'tart', 'tars', 'taps']\n",
+ "['cart', 'tart', 'tars', 'tats']\n",
+ "['cart', 'tart', 'tars', 'tare']\n",
+ "['cart', 'tart', 'tars', 'taro']\n",
+ "['cart', 'tart', 'tars', 'tarp']\n",
+ "['cart', 'wart', 'dart', 'hart']\n",
+ "['cart', 'wart', 'dart', 'mart']\n",
+ "['cart', 'wart', 'dart', 'part']\n",
+ "['cart', 'wart', 'dart', 'tart']\n",
+ "['cart', 'wart', 'dart', 'dirt']\n",
+ "['cart', 'wart', 'dart', 'daft']\n",
+ "['cart', 'wart', 'dart', 'dare']\n",
+ "['cart', 'wart', 'dart', 'dark']\n",
+ "['cart', 'wart', 'dart', 'darn']\n",
+ "['cart', 'wart', 'hart', 'dart']\n",
+ "['cart', 'wart', 'hart', 'mart']\n",
+ "['cart', 'wart', 'hart', 'part']\n",
+ "['cart', 'wart', 'hart', 'tart']\n",
+ "['cart', 'wart', 'hart', 'hurt']\n",
+ "['cart', 'wart', 'hart', 'haft']\n",
+ "['cart', 'wart', 'hart', 'halt']\n",
+ "['cart', 'wart', 'hart', 'hard']\n",
+ "['cart', 'wart', 'hart', 'hare']\n",
+ "['cart', 'wart', 'hart', 'hark']\n",
+ "['cart', 'wart', 'hart', 'harm']\n",
+ "['cart', 'wart', 'hart', 'harp']\n",
+ "['cart', 'wart', 'mart', 'dart']\n",
+ "['cart', 'wart', 'mart', 'hart']\n",
+ "['cart', 'wart', 'mart', 'part']\n",
+ "['cart', 'wart', 'mart', 'tart']\n",
+ "['cart', 'wart', 'mart', 'malt']\n",
+ "['cart', 'wart', 'mart', 'mast']\n",
+ "['cart', 'wart', 'mart', 'matt']\n",
+ "['cart', 'wart', 'mart', 'mare']\n",
+ "['cart', 'wart', 'mart', 'mark']\n",
+ "['cart', 'wart', 'mart', 'mars']\n",
+ "['cart', 'wart', 'part', 'dart']\n",
+ "['cart', 'wart', 'part', 'hart']\n",
+ "['cart', 'wart', 'part', 'mart']\n",
+ "['cart', 'wart', 'part', 'tart']\n",
+ "['cart', 'wart', 'part', 'pert']\n",
+ "['cart', 'wart', 'part', 'port']\n",
+ "['cart', 'wart', 'part', 'pact']\n",
+ "['cart', 'wart', 'part', 'pant']\n",
+ "['cart', 'wart', 'part', 'past']\n",
+ "['cart', 'wart', 'part', 'pare']\n",
+ "['cart', 'wart', 'part', 'park']\n",
+ "['cart', 'wart', 'part', 'pars']\n",
+ "['cart', 'wart', 'tart', 'dart']\n",
+ "['cart', 'wart', 'tart', 'hart']\n",
+ "['cart', 'wart', 'tart', 'mart']\n",
+ "['cart', 'wart', 'tart', 'part']\n",
+ "['cart', 'wart', 'tart', 'tort']\n",
+ "['cart', 'wart', 'tart', 'tact']\n",
+ "['cart', 'wart', 'tart', 'taut']\n",
+ "['cart', 'wart', 'tart', 'tare']\n",
+ "['cart', 'wart', 'tart', 'taro']\n",
+ "['cart', 'wart', 'tart', 'tarp']\n",
+ "['cart', 'wart', 'tart', 'tars']\n",
+ "['cart', 'wart', 'waft', 'daft']\n",
+ "['cart', 'wart', 'waft', 'haft']\n",
+ "['cart', 'wart', 'waft', 'raft']\n",
+ "['cart', 'wart', 'waft', 'weft']\n",
+ "['cart', 'wart', 'waft', 'wait']\n",
+ "['cart', 'wart', 'waft', 'want']\n",
+ "['cart', 'wart', 'waft', 'watt']\n",
+ "['cart', 'wart', 'wait', 'bait']\n",
+ "['cart', 'wart', 'wait', 'gait']\n",
+ "['cart', 'wart', 'wait', 'whit']\n",
+ "['cart', 'wart', 'wait', 'writ']\n",
+ "['cart', 'wart', 'wait', 'waft']\n",
+ "['cart', 'wart', 'wait', 'want']\n",
+ "['cart', 'wart', 'wait', 'watt']\n",
+ "['cart', 'wart', 'wait', 'waif']\n",
+ "['cart', 'wart', 'wait', 'wail']\n",
+ "['cart', 'wart', 'want', 'cant']\n",
+ "['cart', 'wart', 'want', 'pant']\n",
+ "['cart', 'wart', 'want', 'rant']\n",
+ "['cart', 'wart', 'want', 'went']\n",
+ "['cart', 'wart', 'want', 'wont']\n",
+ "['cart', 'wart', 'want', 'waft']\n",
+ "['cart', 'wart', 'want', 'wait']\n",
+ "['cart', 'wart', 'want', 'watt']\n",
+ "['cart', 'wart', 'want', 'wand']\n",
+ "['cart', 'wart', 'want', 'wane']\n",
+ "['cart', 'wart', 'watt', 'matt']\n",
+ "['cart', 'wart', 'watt', 'waft']\n",
+ "['cart', 'wart', 'watt', 'wait']\n",
+ "['cart', 'wart', 'watt', 'want']\n",
+ "['cart', 'wart', 'ward', 'bard']\n",
+ "['cart', 'wart', 'ward', 'card']\n",
+ "['cart', 'wart', 'ward', 'hard']\n",
+ "['cart', 'wart', 'ward', 'lard']\n",
+ "['cart', 'wart', 'ward', 'yard']\n",
+ "['cart', 'wart', 'ward', 'word']\n",
+ "['cart', 'wart', 'ward', 'wand']\n",
+ "['cart', 'wart', 'ward', 'ware']\n",
+ "['cart', 'wart', 'ward', 'warm']\n",
+ "['cart', 'wart', 'ward', 'warn']\n",
+ "['cart', 'wart', 'ward', 'warp']\n",
+ "['cart', 'wart', 'ward', 'wars']\n",
+ "['cart', 'wart', 'ward', 'wary']\n",
+ "['cart', 'wart', 'ware', 'bare']\n",
+ "['cart', 'wart', 'ware', 'care']\n",
+ "['cart', 'wart', 'ware', 'dare']\n",
+ "['cart', 'wart', 'ware', 'fare']\n",
+ "['cart', 'wart', 'ware', 'hare']\n",
+ "['cart', 'wart', 'ware', 'mare']\n",
+ "['cart', 'wart', 'ware', 'pare']\n",
+ "['cart', 'wart', 'ware', 'rare']\n",
+ "['cart', 'wart', 'ware', 'tare']\n",
+ "['cart', 'wart', 'ware', 'were']\n",
+ "['cart', 'wart', 'ware', 'wire']\n",
+ "['cart', 'wart', 'ware', 'wore']\n",
+ "['cart', 'wart', 'ware', 'wade']\n",
+ "['cart', 'wart', 'ware', 'wage']\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['cart', 'wart', 'ware', 'wake']\n",
+ "['cart', 'wart', 'ware', 'wale']\n",
+ "['cart', 'wart', 'ware', 'wane']\n",
+ "['cart', 'wart', 'ware', 'wave']\n",
+ "['cart', 'wart', 'ware', 'ward']\n",
+ "['cart', 'wart', 'ware', 'warm']\n",
+ "['cart', 'wart', 'ware', 'warn']\n",
+ "['cart', 'wart', 'ware', 'warp']\n",
+ "['cart', 'wart', 'ware', 'wars']\n",
+ "['cart', 'wart', 'ware', 'wary']\n",
+ "['cart', 'wart', 'warm', 'farm']\n",
+ "['cart', 'wart', 'warm', 'harm']\n",
+ "['cart', 'wart', 'warm', 'worm']\n",
+ "['cart', 'wart', 'warm', 'ward']\n",
+ "['cart', 'wart', 'warm', 'ware']\n",
+ "['cart', 'wart', 'warm', 'warn']\n",
+ "['cart', 'wart', 'warm', 'warp']\n",
+ "['cart', 'wart', 'warm', 'wars']\n",
+ "['cart', 'wart', 'warm', 'wary']\n",
+ "['cart', 'wart', 'warn', 'barn']\n",
+ "['cart', 'wart', 'warn', 'darn']\n",
+ "['cart', 'wart', 'warn', 'earn']\n",
+ "['cart', 'wart', 'warn', 'yarn']\n",
+ "['cart', 'wart', 'warn', 'worn']\n",
+ "['cart', 'wart', 'warn', 'ward']\n",
+ "['cart', 'wart', 'warn', 'ware']\n",
+ "['cart', 'wart', 'warn', 'warm']\n",
+ "['cart', 'wart', 'warn', 'warp']\n",
+ "['cart', 'wart', 'warn', 'wars']\n",
+ "['cart', 'wart', 'warn', 'wary']\n",
+ "['cart', 'wart', 'warp', 'carp']\n",
+ "['cart', 'wart', 'warp', 'harp']\n",
+ "['cart', 'wart', 'warp', 'tarp']\n",
+ "['cart', 'wart', 'warp', 'wasp']\n",
+ "['cart', 'wart', 'warp', 'ward']\n",
+ "['cart', 'wart', 'warp', 'ware']\n",
+ "['cart', 'wart', 'warp', 'warm']\n",
+ "['cart', 'wart', 'warp', 'warn']\n",
+ "['cart', 'wart', 'warp', 'wars']\n",
+ "['cart', 'wart', 'warp', 'wary']\n",
+ "['cart', 'wart', 'wars', 'bars']\n",
+ "['cart', 'wart', 'wars', 'cars']\n",
+ "['cart', 'wart', 'wars', 'ears']\n",
+ "['cart', 'wart', 'wars', 'jars']\n",
+ "['cart', 'wart', 'wars', 'mars']\n",
+ "['cart', 'wart', 'wars', 'oars']\n",
+ "['cart', 'wart', 'wars', 'pars']\n",
+ "['cart', 'wart', 'wars', 'tars']\n",
+ "['cart', 'wart', 'wars', 'wads']\n",
+ "['cart', 'wart', 'wars', 'wags']\n",
+ "['cart', 'wart', 'wars', 'ways']\n",
+ "['cart', 'wart', 'wars', 'ward']\n",
+ "['cart', 'wart', 'wars', 'ware']\n",
+ "['cart', 'wart', 'wars', 'warm']\n",
+ "['cart', 'wart', 'wars', 'warn']\n",
+ "['cart', 'wart', 'wars', 'warp']\n",
+ "['cart', 'wart', 'wars', 'wary']\n",
+ "['cart', 'wart', 'wary', 'nary']\n",
+ "['cart', 'wart', 'wary', 'vary']\n",
+ "['cart', 'wart', 'wary', 'wiry']\n",
+ "['cart', 'wart', 'wary', 'wavy']\n",
+ "['cart', 'wart', 'wary', 'waxy']\n",
+ "['cart', 'wart', 'wary', 'ward']\n",
+ "['cart', 'wart', 'wary', 'ware']\n",
+ "['cart', 'wart', 'wary', 'warm']\n",
+ "['cart', 'wart', 'wary', 'warn']\n",
+ "['cart', 'wart', 'wary', 'warp']\n",
+ "['cart', 'wart', 'wary', 'wars']\n",
+ "['cart', 'curt', 'hurt', 'hart']\n",
+ "['cart', 'curt', 'hurt', 'hunt']\n",
+ "['cart', 'curt', 'hurt', 'hurl']\n",
+ "['cart', 'curt', 'cult', 'colt']\n",
+ "['cart', 'curt', 'cult', 'cull']\n",
+ "['cart', 'curt', 'curb', 'curd']\n",
+ "['cart', 'curt', 'curb', 'cure']\n",
+ "['cart', 'curt', 'curb', 'curl']\n",
+ "['cart', 'curt', 'curb', 'curs']\n",
+ "['cart', 'curt', 'curd', 'turd']\n",
+ "['cart', 'curt', 'curd', 'card']\n",
+ "['cart', 'curt', 'curd', 'cord']\n",
+ "['cart', 'curt', 'curd', 'cued']\n",
+ "['cart', 'curt', 'curd', 'curb']\n",
+ "['cart', 'curt', 'curd', 'cure']\n",
+ "['cart', 'curt', 'curd', 'curl']\n",
+ "['cart', 'curt', 'curd', 'curs']\n",
+ "['cart', 'curt', 'cure', 'lure']\n",
+ "['cart', 'curt', 'cure', 'pure']\n",
+ "['cart', 'curt', 'cure', 'sure']\n",
+ "['cart', 'curt', 'cure', 'care']\n",
+ "['cart', 'curt', 'cure', 'core']\n",
+ "['cart', 'curt', 'cure', 'cube']\n",
+ "['cart', 'curt', 'cure', 'cute']\n",
+ "['cart', 'curt', 'cure', 'curb']\n",
+ "['cart', 'curt', 'cure', 'curd']\n",
+ "['cart', 'curt', 'cure', 'curl']\n",
+ "['cart', 'curt', 'cure', 'curs']\n",
+ "['cart', 'curt', 'curl', 'furl']\n",
+ "['cart', 'curt', 'curl', 'hurl']\n",
+ "['cart', 'curt', 'curl', 'purl']\n",
+ "['cart', 'curt', 'curl', 'cull']\n",
+ "['cart', 'curt', 'curl', 'curb']\n",
+ "['cart', 'curt', 'curl', 'curd']\n",
+ "['cart', 'curt', 'curl', 'cure']\n",
+ "['cart', 'curt', 'curl', 'curs']\n",
+ "['cart', 'curt', 'curs', 'burs']\n",
+ "['cart', 'curt', 'curs', 'furs']\n",
+ "['cart', 'curt', 'curs', 'ours']\n",
+ "['cart', 'curt', 'curs', 'cars']\n",
+ "['cart', 'curt', 'curs', 'cubs']\n",
+ "['cart', 'curt', 'curs', 'cuds']\n",
+ "['cart', 'curt', 'curs', 'cues']\n",
+ "['cart', 'curt', 'curs', 'cums']\n",
+ "['cart', 'curt', 'curs', 'cups']\n",
+ "['cart', 'curt', 'curs', 'cuss']\n",
+ "['cart', 'curt', 'curs', 'cuts']\n",
+ "['cart', 'curt', 'curs', 'curb']\n",
+ "['cart', 'curt', 'curs', 'curd']\n",
+ "['cart', 'curt', 'curs', 'cure']\n",
+ "['cart', 'curt', 'curs', 'curl']\n",
+ "['cart', 'cant', 'pant', 'rant']\n",
+ "['cart', 'cant', 'pant', 'want']\n",
+ "['cart', 'cant', 'pant', 'pent']\n",
+ "['cart', 'cant', 'pant', 'pint']\n",
+ "['cart', 'cant', 'pant', 'punt']\n",
+ "['cart', 'cant', 'pant', 'pact']\n",
+ "['cart', 'cant', 'pant', 'part']\n",
+ "['cart', 'cant', 'pant', 'past']\n",
+ "['cart', 'cant', 'pant', 'pane']\n",
+ "['cart', 'cant', 'pant', 'pang']\n",
+ "['cart', 'cant', 'pant', 'pans']\n",
+ "['cart', 'cant', 'rant', 'pant']\n",
+ "['cart', 'cant', 'rant', 'want']\n",
+ "['cart', 'cant', 'rant', 'rent']\n",
+ "['cart', 'cant', 'rant', 'runt']\n",
+ "['cart', 'cant', 'rant', 'raft']\n",
+ "['cart', 'cant', 'rant', 'rapt']\n",
+ "['cart', 'cant', 'rant', 'rang']\n",
+ "['cart', 'cant', 'rant', 'rank']\n",
+ "['cart', 'cant', 'want', 'pant']\n",
+ "['cart', 'cant', 'want', 'rant']\n",
+ "['cart', 'cant', 'want', 'went']\n",
+ "['cart', 'cant', 'want', 'wont']\n",
+ "['cart', 'cant', 'want', 'waft']\n",
+ "['cart', 'cant', 'want', 'wait']\n",
+ "['cart', 'cant', 'want', 'wart']\n",
+ "['cart', 'cant', 'want', 'watt']\n",
+ "['cart', 'cant', 'want', 'wand']\n",
+ "['cart', 'cant', 'want', 'wane']\n",
+ "['cart', 'cant', 'cent', 'bent']\n",
+ "['cart', 'cant', 'cent', 'dent']\n",
+ "['cart', 'cant', 'cent', 'gent']\n",
+ "['cart', 'cant', 'cent', 'lent']\n",
+ "['cart', 'cant', 'cent', 'pent']\n",
+ "['cart', 'cant', 'cent', 'rent']\n",
+ "['cart', 'cant', 'cent', 'sent']\n",
+ "['cart', 'cant', 'cent', 'tent']\n",
+ "['cart', 'cant', 'cent', 'vent']\n",
+ "['cart', 'cant', 'cent', 'went']\n",
+ "['cart', 'cant', 'cast', 'bast']\n",
+ "['cart', 'cant', 'cast', 'east']\n",
+ "['cart', 'cant', 'cast', 'fast']\n",
+ "['cart', 'cant', 'cast', 'last']\n",
+ "['cart', 'cant', 'cast', 'mast']\n",
+ "['cart', 'cant', 'cast', 'past']\n",
+ "['cart', 'cant', 'cast', 'vast']\n",
+ "['cart', 'cant', 'cast', 'cost']\n",
+ "['cart', 'cant', 'cast', 'cyst']\n",
+ "['cart', 'cant', 'cast', 'case']\n",
+ "['cart', 'cant', 'cast', 'cash']\n",
+ "['cart', 'cant', 'cast', 'cask']\n",
+ "['cart', 'cant', 'cane', 'bane']\n",
+ "['cart', 'cant', 'cane', 'lane']\n",
+ "['cart', 'cant', 'cane', 'mane']\n",
+ "['cart', 'cant', 'cane', 'pane']\n",
+ "['cart', 'cant', 'cane', 'sane']\n",
+ "['cart', 'cant', 'cane', 'vane']\n",
+ "['cart', 'cant', 'cane', 'wane']\n",
+ "['cart', 'cant', 'cane', 'cone']\n",
+ "['cart', 'cant', 'cane', 'cafe']\n",
+ "['cart', 'cant', 'cane', 'cage']\n",
+ "['cart', 'cant', 'cane', 'cake']\n",
+ "['cart', 'cant', 'cane', 'came']\n",
+ "['cart', 'cant', 'cane', 'cape']\n",
+ "['cart', 'cant', 'cane', 'care']\n",
+ "['cart', 'cant', 'cane', 'case']\n",
+ "['cart', 'cant', 'cane', 'cave']\n",
+ "['cart', 'cant', 'cane', 'cans']\n",
+ "['cart', 'cant', 'cans', 'bans']\n",
+ "['cart', 'cant', 'cans', 'fans']\n",
+ "['cart', 'cant', 'cans', 'mans']\n",
+ "['cart', 'cant', 'cans', 'pans']\n",
+ "['cart', 'cant', 'cans', 'sans']\n",
+ "['cart', 'cant', 'cans', 'tans']\n",
+ "['cart', 'cant', 'cans', 'vans']\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "['cart', 'cant', 'cans', 'vans']"
+ ]
+ },
+ "execution_count": 20,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bfs_search('cart', 'vans', debug=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['cart', 'cant', 'cane', 'vane']"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "bfs_search('cart', 'vane')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['cart',\n",
+ " 'dart',\n",
+ " 'hart',\n",
+ " 'mart',\n",
+ " 'part',\n",
+ " 'tart',\n",
+ " 'wart',\n",
+ " 'waft',\n",
+ " 'daft',\n",
+ " 'haft',\n",
+ " 'raft',\n",
+ " 'rift',\n",
+ " 'gift',\n",
+ " 'lift',\n",
+ " 'sift',\n",
+ " 'soft',\n",
+ " 'loft',\n",
+ " 'left',\n",
+ " 'deft',\n",
+ " 'heft',\n",
+ " 'weft',\n",
+ " 'welt',\n",
+ " 'belt',\n",
+ " 'felt',\n",
+ " 'gelt',\n",
+ " 'melt',\n",
+ " 'pelt',\n",
+ " 'peat',\n",
+ " 'beat',\n",
+ " 'feat',\n",
+ " 'heat',\n",
+ " 'meat',\n",
+ " 'neat',\n",
+ " 'seat',\n",
+ " 'teat',\n",
+ " 'that',\n",
+ " 'chat',\n",
+ " 'shat',\n",
+ " 'what',\n",
+ " 'whet',\n",
+ " 'whit',\n",
+ " 'chit',\n",
+ " 'chic',\n",
+ " 'chid',\n",
+ " 'chin',\n",
+ " 'shin',\n",
+ " 'thin',\n",
+ " 'twin',\n",
+ " 'twig',\n",
+ " 'swig',\n",
+ " 'swag',\n",
+ " 'shag',\n",
+ " 'slag',\n",
+ " 'flag',\n",
+ " 'flog',\n",
+ " 'blog',\n",
+ " 'clog',\n",
+ " 'slog',\n",
+ " 'smog',\n",
+ " 'smug',\n",
+ " 'slug',\n",
+ " 'plug',\n",
+ " 'plum',\n",
+ " 'alum',\n",
+ " 'glum',\n",
+ " 'slum',\n",
+ " 'scum',\n",
+ " 'swum',\n",
+ " 'swam',\n",
+ " 'scam',\n",
+ " 'seam',\n",
+ " 'beam',\n",
+ " 'ream',\n",
+ " 'team',\n",
+ " 'tram',\n",
+ " 'cram',\n",
+ " 'dram',\n",
+ " 'gram',\n",
+ " 'pram',\n",
+ " 'prim',\n",
+ " 'brim',\n",
+ " 'grim',\n",
+ " 'trim',\n",
+ " 'trig',\n",
+ " 'brig',\n",
+ " 'brag',\n",
+ " 'crag',\n",
+ " 'drag',\n",
+ " 'drug',\n",
+ " 'drub',\n",
+ " 'grub',\n",
+ " 'grab',\n",
+ " 'crab',\n",
+ " 'drab',\n",
+ " 'draw',\n",
+ " 'craw',\n",
+ " 'claw',\n",
+ " 'flaw',\n",
+ " 'slaw',\n",
+ " 'slew',\n",
+ " 'blew',\n",
+ " 'clew',\n",
+ " 'flew',\n",
+ " 'flow',\n",
+ " 'blow',\n",
+ " 'glow',\n",
+ " 'slow',\n",
+ " 'scow',\n",
+ " 'show',\n",
+ " 'chow',\n",
+ " 'crow',\n",
+ " 'brow',\n",
+ " 'grow',\n",
+ " 'prow',\n",
+ " 'prod',\n",
+ " 'trod',\n",
+ " 'trot',\n",
+ " 'toot',\n",
+ " 'boot',\n",
+ " 'coot',\n",
+ " 'foot',\n",
+ " 'hoot',\n",
+ " 'loot',\n",
+ " 'moot',\n",
+ " 'root',\n",
+ " 'soot',\n",
+ " 'shot',\n",
+ " 'slot',\n",
+ " 'blot',\n",
+ " 'clot',\n",
+ " 'plot',\n",
+ " 'plod',\n",
+ " 'clod',\n",
+ " 'clad',\n",
+ " 'glad',\n",
+ " 'goad',\n",
+ " 'load',\n",
+ " 'road',\n",
+ " 'toad',\n",
+ " 'toed',\n",
+ " 'coed',\n",
+ " 'hoed',\n",
+ " 'heed',\n",
+ " 'deed',\n",
+ " 'feed',\n",
+ " 'geed',\n",
+ " 'need',\n",
+ " 'peed',\n",
+ " 'reed',\n",
+ " 'seed',\n",
+ " 'teed',\n",
+ " 'weed',\n",
+ " 'weld',\n",
+ " 'geld',\n",
+ " 'held',\n",
+ " 'meld',\n",
+ " 'veld',\n",
+ " 'vend',\n",
+ " 'bend',\n",
+ " 'fend',\n",
+ " 'lend',\n",
+ " 'mend',\n",
+ " 'rend',\n",
+ " 'send',\n",
+ " 'tend',\n",
+ " 'wend',\n",
+ " 'wand',\n",
+ " 'band',\n",
+ " 'hand',\n",
+ " 'land',\n",
+ " 'sand',\n",
+ " 'said',\n",
+ " 'laid',\n",
+ " 'maid',\n",
+ " 'paid',\n",
+ " 'raid',\n",
+ " 'rail',\n",
+ " 'bail',\n",
+ " 'fail',\n",
+ " 'hail',\n",
+ " 'jail',\n",
+ " 'mail',\n",
+ " 'nail',\n",
+ " 'pail',\n",
+ " 'sail',\n",
+ " 'tail',\n",
+ " 'wail',\n",
+ " 'wall',\n",
+ " 'ball',\n",
+ " 'call',\n",
+ " 'fall',\n",
+ " 'gall',\n",
+ " 'hall',\n",
+ " 'mall',\n",
+ " 'pall',\n",
+ " 'tall',\n",
+ " 'tell',\n",
+ " 'bell',\n",
+ " 'cell',\n",
+ " 'dell',\n",
+ " 'fell',\n",
+ " 'hell',\n",
+ " 'jell',\n",
+ " 'sell',\n",
+ " 'well',\n",
+ " 'yell',\n",
+ " 'yelp',\n",
+ " 'help',\n",
+ " 'kelp',\n",
+ " 'keep',\n",
+ " 'beep',\n",
+ " 'deep',\n",
+ " 'jeep',\n",
+ " 'peep',\n",
+ " 'seep',\n",
+ " 'veep',\n",
+ " 'weep',\n",
+ " 'week',\n",
+ " 'geek',\n",
+ " 'leek',\n",
+ " 'meek',\n",
+ " 'peek',\n",
+ " 'reek',\n",
+ " 'seek',\n",
+ " 'seem',\n",
+ " 'deem',\n",
+ " 'teem',\n",
+ " 'them',\n",
+ " 'thee',\n",
+ " 'tree',\n",
+ " 'free',\n",
+ " 'flee',\n",
+ " 'glee',\n",
+ " 'glue',\n",
+ " 'blue',\n",
+ " 'clue',\n",
+ " 'flue',\n",
+ " 'slue',\n",
+ " 'sloe',\n",
+ " 'aloe',\n",
+ " 'floe',\n",
+ " 'flop',\n",
+ " 'clop',\n",
+ " 'glop',\n",
+ " 'plop',\n",
+ " 'slop',\n",
+ " 'shop',\n",
+ " 'chop',\n",
+ " 'coop',\n",
+ " 'goop',\n",
+ " 'hoop',\n",
+ " 'loop',\n",
+ " 'poop',\n",
+ " 'prop',\n",
+ " 'crop',\n",
+ " 'drop',\n",
+ " 'drip',\n",
+ " 'grip',\n",
+ " 'trip',\n",
+ " 'trap',\n",
+ " 'tray',\n",
+ " 'bray',\n",
+ " 'dray',\n",
+ " 'fray',\n",
+ " 'gray',\n",
+ " 'pray',\n",
+ " 'play',\n",
+ " 'clay',\n",
+ " 'flay',\n",
+ " 'slay',\n",
+ " 'spay',\n",
+ " 'stay',\n",
+ " 'sway',\n",
+ " 'away',\n",
+ " 'awry',\n",
+ " 'aery',\n",
+ " 'eery',\n",
+ " 'very',\n",
+ " 'vary',\n",
+ " 'nary',\n",
+ " 'wary',\n",
+ " 'wiry',\n",
+ " 'airy',\n",
+ " 'airs',\n",
+ " 'firs',\n",
+ " 'sirs',\n",
+ " 'sics',\n",
+ " 'tics',\n",
+ " 'ties',\n",
+ " 'dies',\n",
+ " 'hies',\n",
+ " 'lies',\n",
+ " 'pies',\n",
+ " 'vies',\n",
+ " 'vied',\n",
+ " 'died',\n",
+ " 'hied',\n",
+ " 'lied',\n",
+ " 'pied',\n",
+ " 'tied',\n",
+ " 'tier',\n",
+ " 'bier',\n",
+ " 'pier',\n",
+ " 'peer',\n",
+ " 'beer',\n",
+ " 'deer',\n",
+ " 'jeer',\n",
+ " 'leer',\n",
+ " 'seer',\n",
+ " 'veer',\n",
+ " 'weer',\n",
+ " 'wear',\n",
+ " 'bear',\n",
+ " 'dear',\n",
+ " 'fear',\n",
+ " 'gear',\n",
+ " 'hear',\n",
+ " 'near',\n",
+ " 'pear',\n",
+ " 'rear',\n",
+ " 'sear',\n",
+ " 'tear',\n",
+ " 'year',\n",
+ " 'yeah',\n",
+ " 'yeas',\n",
+ " 'leas',\n",
+ " 'peas',\n",
+ " 'seas',\n",
+ " 'teas',\n",
+ " 'tees',\n",
+ " 'bees',\n",
+ " 'fees',\n",
+ " 'gees',\n",
+ " 'lees',\n",
+ " 'pees',\n",
+ " 'sees',\n",
+ " 'wees',\n",
+ " 'woes',\n",
+ " 'does',\n",
+ " 'foes',\n",
+ " 'goes',\n",
+ " 'hoes',\n",
+ " 'noes',\n",
+ " 'roes',\n",
+ " 'toes',\n",
+ " 'togs',\n",
+ " 'bogs',\n",
+ " 'cogs',\n",
+ " 'dogs',\n",
+ " 'fogs',\n",
+ " 'hogs',\n",
+ " 'jogs',\n",
+ " 'logs',\n",
+ " 'lags',\n",
+ " 'bags',\n",
+ " 'fags',\n",
+ " 'gags',\n",
+ " 'hags',\n",
+ " 'jags',\n",
+ " 'nags',\n",
+ " 'rags',\n",
+ " 'sags',\n",
+ " 'tags',\n",
+ " 'wags',\n",
+ " 'wigs',\n",
+ " 'digs',\n",
+ " 'figs',\n",
+ " 'gigs',\n",
+ " 'jigs',\n",
+ " 'pigs',\n",
+ " 'rigs',\n",
+ " 'rugs',\n",
+ " 'bugs',\n",
+ " 'hugs',\n",
+ " 'jugs',\n",
+ " 'lugs',\n",
+ " 'mugs',\n",
+ " 'pugs',\n",
+ " 'tugs',\n",
+ " 'tubs',\n",
+ " 'cubs',\n",
+ " 'dubs',\n",
+ " 'hubs',\n",
+ " 'nubs',\n",
+ " 'pubs',\n",
+ " 'rubs',\n",
+ " 'subs',\n",
+ " 'sobs',\n",
+ " 'bobs',\n",
+ " 'cobs',\n",
+ " 'fobs',\n",
+ " 'gobs',\n",
+ " 'hobs',\n",
+ " 'jobs',\n",
+ " 'lobs',\n",
+ " 'mobs',\n",
+ " 'robs',\n",
+ " 'ribs',\n",
+ " 'bibs',\n",
+ " 'fibs',\n",
+ " 'jibs',\n",
+ " 'nibs',\n",
+ " 'nabs',\n",
+ " 'cabs',\n",
+ " 'dabs',\n",
+ " 'gabs',\n",
+ " 'jabs',\n",
+ " 'labs',\n",
+ " 'tabs',\n",
+ " 'tads',\n",
+ " 'cads',\n",
+ " 'dads',\n",
+ " 'fads',\n",
+ " 'gads',\n",
+ " 'lads',\n",
+ " 'mads',\n",
+ " 'pads',\n",
+ " 'wads',\n",
+ " 'weds',\n",
+ " 'beds',\n",
+ " 'feds',\n",
+ " 'reds',\n",
+ " 'rids',\n",
+ " 'aids',\n",
+ " 'bids',\n",
+ " 'kids',\n",
+ " 'lids',\n",
+ " 'lips',\n",
+ " 'dips',\n",
+ " 'hips',\n",
+ " 'nips',\n",
+ " 'pips',\n",
+ " 'rips',\n",
+ " 'sips',\n",
+ " 'tips',\n",
+ " 'yips',\n",
+ " 'zips',\n",
+ " 'zaps',\n",
+ " 'caps',\n",
+ " 'gaps',\n",
+ " 'laps',\n",
+ " 'maps',\n",
+ " 'naps',\n",
+ " 'paps',\n",
+ " 'raps',\n",
+ " 'saps',\n",
+ " 'taps',\n",
+ " 'yaps',\n",
+ " 'yeps',\n",
+ " 'peps',\n",
+ " 'reps',\n",
+ " 'refs',\n",
+ " 'reis',\n",
+ " 'leis',\n",
+ " 'legs',\n",
+ " 'begs',\n",
+ " 'kegs',\n",
+ " 'megs',\n",
+ " 'pegs',\n",
+ " 'pens',\n",
+ " 'dens',\n",
+ " 'fens',\n",
+ " 'hens',\n",
+ " 'kens',\n",
+ " 'lens',\n",
+ " 'tens',\n",
+ " 'wens',\n",
+ " 'yens',\n",
+ " 'yews',\n",
+ " 'hews',\n",
+ " 'mews',\n",
+ " 'news',\n",
+ " 'pews',\n",
+ " 'sews',\n",
+ " 'saws',\n",
+ " 'caws',\n",
+ " 'haws',\n",
+ " 'jaws',\n",
+ " 'laws',\n",
+ " 'maws',\n",
+ " 'paws',\n",
+ " 'yaws',\n",
+ " 'yaks',\n",
+ " 'oaks',\n",
+ " 'oafs',\n",
+ " 'oars',\n",
+ " 'bars',\n",
+ " 'cars',\n",
+ " 'ears',\n",
+ " 'jars',\n",
+ " 'mars',\n",
+ " 'pars',\n",
+ " 'tars',\n",
+ " 'wars',\n",
+ " 'ways',\n",
+ " 'bays',\n",
+ " 'days',\n",
+ " 'gays',\n",
+ " 'hays',\n",
+ " 'jays',\n",
+ " 'lays',\n",
+ " 'nays',\n",
+ " 'pays',\n",
+ " 'rays',\n",
+ " 'says',\n",
+ " 'sacs',\n",
+ " 'secs',\n",
+ " 'sets',\n",
+ " 'bets',\n",
+ " 'gets',\n",
+ " 'jets',\n",
+ " 'lets',\n",
+ " 'nets',\n",
+ " 'pets',\n",
+ " 'vets',\n",
+ " 'wets',\n",
+ " 'wits',\n",
+ " 'bits',\n",
+ " 'fits',\n",
+ " 'hits',\n",
+ " 'kits',\n",
+ " 'nits',\n",
+ " 'pits',\n",
+ " 'sits',\n",
+ " 'tits',\n",
+ " 'tats',\n",
+ " 'bats',\n",
+ " 'cats',\n",
+ " 'eats',\n",
+ " 'fats',\n",
+ " 'hats',\n",
+ " 'lats',\n",
+ " 'mats',\n",
+ " 'oats',\n",
+ " 'pats',\n",
+ " 'rats',\n",
+ " 'vats',\n",
+ " 'vans',\n",
+ " 'bans',\n",
+ " 'cans',\n",
+ " 'fans',\n",
+ " 'mans',\n",
+ " 'pans',\n",
+ " 'sans',\n",
+ " 'tans',\n",
+ " 'tins',\n",
+ " 'bins',\n",
+ " 'dins',\n",
+ " 'fins',\n",
+ " 'gins',\n",
+ " 'pins',\n",
+ " 'sins',\n",
+ " 'wins',\n",
+ " 'wind',\n",
+ " 'bind',\n",
+ " 'find',\n",
+ " 'hind',\n",
+ " 'kind',\n",
+ " 'mind',\n",
+ " 'rind',\n",
+ " 'ring',\n",
+ " 'ding',\n",
+ " 'king',\n",
+ " 'ping',\n",
+ " 'sing',\n",
+ " 'ting',\n",
+ " 'wing',\n",
+ " 'wine',\n",
+ " 'dine',\n",
+ " 'fine',\n",
+ " 'line',\n",
+ " 'mine',\n",
+ " 'nine',\n",
+ " 'pine',\n",
+ " 'sine',\n",
+ " 'tine',\n",
+ " 'vine',\n",
+ " 'vane']"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dfs_search('cart', 'vane')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def astar_search(start, goal, debug=False):\n",
+ " agenda = [(distance(start, goal), [start])]\n",
+ " heapq.heapify(agenda)\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " _, current = heapq.heappop(agenda)\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " successors = extend(current)\n",
+ " for s in successors:\n",
+ " heapq.heappush(agenda, (len(current) + distance(s[-1], goal) - 1, s))\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['cart']\n",
+ "['cart', 'cant']\n",
+ "['cart', 'cant', 'cane']\n",
+ "['cart', 'cant', 'cane', 'vane']\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "['cart', 'cant', 'cane', 'vane']"
+ ]
+ },
+ "execution_count": 24,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search('cart', 'vane', debug=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def astar_search_closed(start, goal, debug=False):\n",
+ " agenda = [(distance(start, goal), [start])]\n",
+ " heapq.heapify(agenda)\n",
+ " closed = set()\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " _, current = heapq.heappop(agenda)\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " closed.add(current[-1])\n",
+ " successors = extend(current, closed)\n",
+ " for s in successors:\n",
+ " heapq.heappush(agenda, (len(current) + distance(s[-1], goal) - 1, s))\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['cart']\n",
+ "['cart', 'cant']\n",
+ "['cart', 'cant', 'cane']\n",
+ "['cart', 'cant', 'cane', 'vane']\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "['cart', 'cant', 'cane', 'vane']"
+ ]
+ },
+ "execution_count": 26,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search_closed('cart', 'vane', debug=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Mutually-reachable sets\n",
+ "\n",
+ "Find the transitive closure of the `neighbours` relation, so we can see which words can be transformed into which other words."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 77,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "94"
+ ]
+ },
+ "execution_count": 77,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "candidates = [set([k] + neighbours[k]) for k in neighbours]\n",
+ "reachables = []\n",
+ "while candidates:\n",
+ " current = set(candidates.pop())\n",
+ " altered = False\n",
+ " for other in candidates:\n",
+ " if current.intersection(other):\n",
+ " altered = True\n",
+ " current.update(other)\n",
+ " candidates.remove(other)\n",
+ " if altered:\n",
+ " candidates.append(current)\n",
+ " else:\n",
+ " reachables.append(current)\n",
+ "\n",
+ "len(reachables)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 78,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2204"
+ ]
+ },
+ "execution_count": 78,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(max(reachables, key=len))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 79,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1"
+ ]
+ },
+ "execution_count": 79,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(min(reachables, key=len))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 80,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Counter({1: 75, 2: 6, 3: 7, 4: 2, 5: 2, 6: 1, 2204: 1})"
+ ]
+ },
+ "execution_count": 80,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "collections.Counter(len(r) for r in reachables)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 81,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[5]"
+ ]
+ },
+ "execution_count": 81,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[len(r) for r in reachables if 'abbe' in r]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 82,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[{'abbe', 'able', 'ably', 'ally', 'axle'}]"
+ ]
+ },
+ "execution_count": 82,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[r for r in reachables if 'abbe' in r]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 83,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['buns', 'bunk', 'punk']"
+ ]
+ },
+ "execution_count": 83,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search('buns', 'punk')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 84,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "for a in reachables:\n",
+ " for b in reachables:\n",
+ " if a != b:\n",
+ " if not a.isdisjoint(b):\n",
+ " print(a, b)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 85,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "# longest_chain = []\n",
+ "# with open('all-chains-4.txt', 'w', 1) as f:\n",
+ "# for ws in reachables:\n",
+ "# for s in ws:\n",
+ "# for t in ws:\n",
+ "# if s < t:\n",
+ "# chain = astar_search(s, t)\n",
+ "# if chain:\n",
+ "# f.write('{}\\n'.format(chain))\n",
+ "# if len(chain) > len(longest_chain):\n",
+ "# longest_chain = chain\n",
+ "\n",
+ "# longest_chain"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 86,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "bigset = max(reachables, key=len)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 87,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['late', 'lats', 'lets', 'leas', 'seas', 'seam', 'swam', 'sway']\n",
+ "['leap', 'heap', 'hear', 'dear', 'deer']\n",
+ "['peel', 'peek', 'perk', 'park', 'nark']\n",
+ "['sing', 'sang', 'sand', 'said', 'sail', 'hail', 'haul']\n",
+ "['vats', 'bats', 'bets', 'bees', 'been', 'teen', 'then', 'thin', 'this', 'thus', 'thud']\n",
+ "['sues', 'sees', 'seen', 'sewn', 'hewn']\n",
+ "['rash', 'bash', 'bast', 'bait', 'bail', 'hail', 'hair', 'heir']\n",
+ "['apex', 'aped', 'sped', 'seed', 'deed', 'dead', 'deal', 'veal']\n",
+ "['gulf', 'golf', 'gold', 'bold', 'bond', 'bony', 'tony']\n",
+ "['snag', 'shag', 'shat', 'seat', 'peat', 'pent', 'pint', 'mint']\n",
+ "['rife', 'rime', 'rims', 'rums', 'cums', 'cuss']\n",
+ "['diss', 'kiss', 'kits']\n",
+ "['gyps', 'gaps', 'gads', 'wads', 'wade', 'wide', 'tide']\n",
+ "['bilk', 'bill', 'bell', 'tell', 'teal', 'tear', 'tzar']\n",
+ "['logo', 'loge', 'lode', 'lade', 'jade', 'jape']\n",
+ "['hunt', 'bunt', 'buns', 'nuns', 'nubs']\n",
+ "['glow', 'glop', 'plop', 'prop', 'prep', 'peep', 'keep']\n",
+ "['iamb', 'lamb', 'lams', 'laps', 'lips', 'pips']\n",
+ "['pain', 'lain', 'laid', 'land', 'lend', 'vend', 'veld']\n",
+ "['fake', 'bake', 'bare', 'bars', 'ears', 'errs', 'ergs', 'eggs', 'egos']\n"
+ ]
+ }
+ ],
+ "source": [
+ "for _ in range(20):\n",
+ " start, goal = random.sample(bigset, 2)\n",
+ " print(astar_search_closed(start, goal))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['cops', 'coos', 'coon', 'coin', 'chin', 'thin', 'this', 'thus', 'thug']"
+ ]
+ },
+ "execution_count": 38,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search('cops', 'thug')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 39,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[2204]"
+ ]
+ },
+ "execution_count": 39,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[len(r) for r in reachables if 'love' in r if 'hate' in r]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['hate', 'have', 'hove', 'love']"
+ ]
+ },
+ "execution_count": 40,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search('hate', 'love')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 41,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['wars', 'ware', 'wave', 'wove', 'love']"
+ ]
+ },
+ "execution_count": 41,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search('wars', 'love')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 61,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 0 ns, sys: 0 ns, total: 0 ns\n",
+ "Wall time: 210 µs\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "5"
+ ]
+ },
+ "execution_count": 61,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(astar_search('wars', 'love'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 62,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 0 ns, sys: 0 ns, total: 0 ns\n",
+ "Wall time: 252 µs\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "5"
+ ]
+ },
+ "execution_count": 62,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(astar_search_closed('wars', 'love'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 63,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 24 ms, sys: 0 ns, total: 24 ms\n",
+ "Wall time: 24.2 ms\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "404"
+ ]
+ },
+ "execution_count": 63,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(dfs_search('wars', 'love'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 64,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 5min 20s, sys: 76 ms, total: 5min 20s\n",
+ "Wall time: 5min 20s\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "5"
+ ]
+ },
+ "execution_count": 64,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(bfs_search('wars', 'love'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 65,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 1.44 s, sys: 0 ns, total: 1.44 s\n",
+ "Wall time: 1.43 s\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "5"
+ ]
+ },
+ "execution_count": 65,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(bfs_search_closed('wars', 'love'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['fear', 'feat', 'fest', 'lest', 'lost', 'lose', 'love']"
+ ]
+ },
+ "execution_count": 42,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search('fear', 'love')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 43,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['fail', 'fall', 'pall', 'pals', 'pass']"
+ ]
+ },
+ "execution_count": 43,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search('fail', 'pass')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 44,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['star', 'soar', 'boar', 'boor', 'boon', 'born']"
+ ]
+ },
+ "execution_count": 44,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search('star', 'born')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 45,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['open',\n",
+ " 'oven',\n",
+ " 'even',\n",
+ " 'eves',\n",
+ " 'eyes',\n",
+ " 'byes',\n",
+ " 'bees',\n",
+ " 'begs',\n",
+ " 'bags',\n",
+ " 'bass',\n",
+ " 'pass']"
+ ]
+ },
+ "execution_count": 45,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search('open', 'pass')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 46,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['bass',\n",
+ " 'lass',\n",
+ " 'mass',\n",
+ " 'sass',\n",
+ " 'puss',\n",
+ " 'pads',\n",
+ " 'pals',\n",
+ " 'pans',\n",
+ " 'paps',\n",
+ " 'pars',\n",
+ " 'pats',\n",
+ " 'paws',\n",
+ " 'pays',\n",
+ " 'past']"
+ ]
+ },
+ "execution_count": 46,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "neighbours['pass']"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 47,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[1]"
+ ]
+ },
+ "execution_count": 47,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[len(r) for r in reachables if 'exam' in r]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 48,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[2204]"
+ ]
+ },
+ "execution_count": 48,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[len(r) for r in reachables if 'star' in r if 'born' in r]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 49,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 loop, best of 3: 7.9 s per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "astar_search('bats', 'exit')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 50,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "10 loops, best of 3: 141 ms per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "astar_search_closed('bats', 'exit')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 51,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['bats',\n",
+ " 'bans',\n",
+ " 'band',\n",
+ " 'sand',\n",
+ " 'said',\n",
+ " 'skid',\n",
+ " 'skit',\n",
+ " 'smit',\n",
+ " 'emit',\n",
+ " 'exit']"
+ ]
+ },
+ "execution_count": 51,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search_closed('bats', 'exit')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 88,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{2: [['heel', 'keel'], ['wane', 'wave'], ['cell', 'sell'], ['cons', 'cobs']],\n",
+ " 3: [['hank', 'haws'], ['bars', 'bets'], ['rats', 'paws'], ['lock', 'hack']],\n",
+ " 4: [['rule', 'sore'], ['wavy', 'rape'], ['peas', 'ping'], ['bond', 'toll']],\n",
+ " 5: [['cope', 'yowl'], ['lose', 'loci'], ['rump', 'dash'], ['four', 'dyes']],\n",
+ " 6: [['boon', 'sell'], ['lots', 'pomp'], ['cola', 'turn'], ['boos', 'laid']],\n",
+ " 7: [['eave', 'inns'], ['meek', 'mere'], ['keys', 'wily'], ['slam', 'yore']],\n",
+ " 8: [['hack', 'flip'], ['crag', 'huge'], ['flux', 'gill'], ['play', 'busy']],\n",
+ " 9: [['lacy', 'whey'], ['wren', 'rook'], ['lire', 'drip'], ['grab', 'lame']],\n",
+ " 10: [['over', 'turn'], ['worn', 'anew'], ['stow', 'elks'], ['ergo', 'rich']],\n",
+ " 11: [['bask', 'idea'], ['gabs', 'thud'], ['idea', 'clod'], ['mark', 'ibis']],\n",
+ " 12: [['umps', 'torn'], ['futz', 'shun'], ['abut', 'face'], ['slug', 'open']],\n",
+ " 13: [['umps', 'skin'], ['chum', 'rats'], ['fury', 'chum'], ['omen', 'zany']],\n",
+ " 14: [['chug', 'gaff'], ['atom', 'fizz']],\n",
+ " 15: [['chug', 'oxen']]}"
+ ]
+ },
+ "execution_count": 88,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "solutions = {}\n",
+ "for _ in range(10000):\n",
+ " start, goal = random.sample(bigset, 2)\n",
+ " solution = astar_search_closed(start, goal)\n",
+ " sl = len(solution)\n",
+ " if sl not in solutions:\n",
+ " solutions[sl] = []\n",
+ " if len(solutions[sl]) < 4:\n",
+ " solutions[sl].append([start, goal])\n",
+ " \n",
+ "# if len(solution) >= 10:\n",
+ "# solutions += [solution]\n",
+ " \n",
+ "solutions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 91,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "solutions = {2: [['heel', 'keel'], ['wane', 'wave'], ['cell', 'sell'], ['cons', 'cobs']],\n",
+ " 3: [['hank', 'haws'], ['bars', 'bets'], ['rats', 'paws'], ['lock', 'hack']],\n",
+ " 4: [['rule', 'sore'], ['wavy', 'rape'], ['peas', 'ping'], ['bond', 'toll']],\n",
+ " 5: [['cope', 'yowl'], ['lose', 'loci'], ['rump', 'dash'], ['four', 'dyes']],\n",
+ " 6: [['boon', 'sell'], ['lots', 'pomp'], ['cola', 'turn'], ['boos', 'laid']],\n",
+ " 7: [['eave', 'inns'], ['meek', 'mere'], ['keys', 'wily'], ['slam', 'yore']],\n",
+ " 8: [['hack', 'flip'], ['crag', 'huge'], ['flux', 'gill'], ['play', 'busy']],\n",
+ " 9: [['lacy', 'whey'], ['wren', 'rook'], ['lire', 'drip'], ['grab', 'lame']],\n",
+ " 10: [['over', 'turn'], ['worn', 'anew'], ['stow', 'elks'], ['ergo', 'rich']],\n",
+ " 11: [['bask', 'idea'], ['gabs', 'thud'], ['idea', 'clod'], ['mark', 'ibis']],\n",
+ " 12: [['umps', 'torn'], ['futz', 'shun'], ['abut', 'face'], ['slug', 'open']],\n",
+ " 13: [['umps', 'skin'], ['chum', 'rats'], ['fury', 'chum'], ['omen', 'zany']],\n",
+ " 14: [['chug', 'gaff'], ['atom', 'fizz'], ['chug', 'jinn'], ['amen', 'flog'],\n",
+ " ['buzz', 'grog'], ['imps', 'pros']],\n",
+ " 15: [['chug', 'oxen'], ['amen', 'doff']]}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 54,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[('amen', 'doff', 15), ('chug', 'jinn', 14), ('amen', 'flog', 14)]"
+ ]
+ },
+ "execution_count": 54,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "[(s[0], s[-1], len(s)) for s in solutions if len(s) >= 14]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 55,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 loop, best of 3: 360 ms per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "astar_search_closed('blab', 'amen')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 56,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 384 ms, sys: 0 ns, total: 384 ms\n",
+ "Wall time: 385 ms\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "14"
+ ]
+ },
+ "execution_count": 56,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(astar_search_closed('blab', 'amen'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 57,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 124 ms, sys: 0 ns, total: 124 ms\n",
+ "Wall time: 121 ms\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "15"
+ ]
+ },
+ "execution_count": 57,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(astar_search_closed('amen', 'doff'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 58,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 32 ms, sys: 0 ns, total: 32 ms\n",
+ "Wall time: 32.4 ms\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "14"
+ ]
+ },
+ "execution_count": 58,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(astar_search_closed('chug', 'jinn'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 59,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 16 ms, sys: 0 ns, total: 16 ms\n",
+ "Wall time: 17.1 ms\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "14"
+ ]
+ },
+ "execution_count": 59,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(astar_search_closed('amen', 'flog'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 73,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 268 ms, sys: 4 ms, total: 272 ms\n",
+ "Wall time: 272 ms\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "14"
+ ]
+ },
+ "execution_count": 73,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(astar_search_closed('buzz', 'grog'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 74,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "CPU times: user 64 ms, sys: 0 ns, total: 64 ms\n",
+ "Wall time: 64.1 ms\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "14"
+ ]
+ },
+ "execution_count": 74,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "%time len(astar_search_closed('imps', 'pros'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "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.5.2+"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
--- /dev/null
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Word chains\n",
+ "\n",
+ "\"Word chain\" puzzles are where you transform one word into another, by changing one letter at a time, with all the intermediate steps being valid words. \n",
+ "\n",
+ "For instance, you can transform 'rash' to 'jags' like this:\n",
+ "\n",
+ "```\n",
+ "rash\n",
+ "Bash\n",
+ "basS\n",
+ "baGs\n",
+ "Jags\n",
+ "```\n",
+ "\n",
+ "(the capital letter is the one changed in each step).\n",
+ "\n",
+ "## Part 1\n",
+ "\n",
+ "Given this [list of words](words4.txt), what is the minimum number of steps to go from `vice` to `wars`?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "import string\n",
+ "import heapq"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2336"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "words = [w.strip() for w in open('09-words.txt').readlines()]\n",
+ "len(words)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def adjacents(word):\n",
+ " return [word[0:i] + l + word[i+1:]\n",
+ " for i in range(len(word))\n",
+ " for l in string.ascii_lowercase\n",
+ " if l != word[i]]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "neighbours = {w: [n for n in adjacents(w) if n in words]\n",
+ " for w in words}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def distance(w1, w2):\n",
+ " return sum(1 for i in range(len(w1))\n",
+ " if w1[i] != w2[i])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "# def extend(chain):\n",
+ "# return [chain + [s] for s in neighbours[chain[-1]]\n",
+ "# if s not in chain]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def extend(chain, closed=None):\n",
+ " if closed:\n",
+ " nbrs = set(neighbours[chain[-1]]) - closed\n",
+ " else:\n",
+ " nbrs = neighbours[chain[-1]]\n",
+ " return [chain + [s] for s in nbrs\n",
+ " if s not in chain]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def extend_raw(chain):\n",
+ " nbrs = [w for w in adjacents(chain[-1]) if w in words]\n",
+ " return [chain + [s] for s in nbrs\n",
+ " if s not in chain]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def bfs_search(start, goal, debug=False):\n",
+ " agenda = [[start]]\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " current = agenda[0]\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " successors = extend(current)\n",
+ " agenda = agenda[1:] + successors\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def bfs_search_closed(start, goal, debug=False):\n",
+ " agenda = [[start]]\n",
+ " closed = set()\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " current = agenda[0]\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " closed.add(current[-1])\n",
+ " successors = extend(current, closed)\n",
+ " agenda = agenda[1:] + successors\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def dfs_search(start, goal, debug=False):\n",
+ " agenda = [[start]]\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " current = agenda[0]\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " successors = extend(current)\n",
+ " agenda = successors + agenda[1:]\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def astar_search(start, goal, debug=False):\n",
+ " agenda = [(distance(start, goal), [start])]\n",
+ " heapq.heapify(agenda)\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " _, current = heapq.heappop(agenda)\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " successors = extend(current)\n",
+ " for s in successors:\n",
+ " heapq.heappush(agenda, (len(current) + distance(s[-1], goal) - 1, s))\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "# Uses direct lookup of successors, rather than using cached neighbours in the dict\n",
+ "def astar_search_raw(start, goal, debug=False):\n",
+ " agenda = [(distance(start, goal), [start])]\n",
+ " heapq.heapify(agenda)\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " _, current = heapq.heappop(agenda)\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " successors = extend_raw(current) # Difference here\n",
+ " for s in successors:\n",
+ " heapq.heappush(agenda, (len(current) + distance(s[-1], goal) - 1, s))\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def astar_search_closed(start, goal, debug=False):\n",
+ " agenda = [(distance(start, goal), [start])]\n",
+ " heapq.heapify(agenda)\n",
+ " closed = set()\n",
+ " finished = False\n",
+ " while not finished and agenda:\n",
+ " _, current = heapq.heappop(agenda)\n",
+ " if debug:\n",
+ " print(current)\n",
+ " if current[-1] == goal:\n",
+ " finished = True\n",
+ " else:\n",
+ " closed.add(current[-1])\n",
+ " successors = extend(current, closed)\n",
+ " for s in successors:\n",
+ " heapq.heappush(agenda, (len(current) + distance(s[-1], goal) - 1, s))\n",
+ " if agenda:\n",
+ " return current\n",
+ " else:\n",
+ " return None "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['vice', 'dice', 'dire', 'dare', 'ware', 'wars']"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search('vice', 'wars')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "['vice', 'dice', 'dire', 'dare', 'ware', 'wars']"
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "astar_search_raw('vice', 'wars')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "6"
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(astar_search('vice', 'wars'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "6"
+ ]
+ },
+ "execution_count": 20,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(bfs_search('vice', 'wars'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "6"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(bfs_search_closed('vice', 'wars'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "793"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(dfs_search('vice', 'wars'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "10000 loops, best of 3: 157 µs per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "astar_search('vice', 'wars')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "100 loops, best of 3: 15.8 ms per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "astar_search_raw('vice', 'wars')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "10000 loops, best of 3: 170 µs per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "astar_search_closed('vice', 'wars')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 loop, best of 3: 1min 42s per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "bfs_search('vice', 'wars')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 loop, best of 3: 557 ms per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "bfs_search_closed('vice', 'wars')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "10 loops, best of 3: 87.9 ms per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "dfs_search('vice', 'wars')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Part 2\n",
+ "\n",
+ "The example shows that `jags` is reachable in four steps from `rash`. There are 11 words one step away from `rash`: \n",
+ "`bash`, `cash`, `dash`, `gash`, `hash`, `lash`, `mash`, `rasp`, `rush`, `sash`, and `wash`. \n",
+ "\n",
+ "There are 47 words reachable in one or two steps from `rash`. They are `base`, `bash`, `bask`, `bass`, `bast`, `bath`, `bosh`, `bush`, `case`, `cash`, `cask`, `cast`, `dash`, `dish`, `gash`, `gasp`, `gosh`, `gush`, `hash`, `hasp`, `hath`, `hush`, `lash`, `lass`, `last`, `lath`, `lush`, `mash`, `mask`, `mass`, `mast`, `math`, `mesh`, `mush`, `push`, `ramp`, `rasp`, `ruse`, `rush`, `rusk`, `rust`, `sash`, `sass`, `tush`, `wash`, `wasp`, and `wish`.\n",
+ "\n",
+ "There are 180 words reachable in up to three steps from `rash`.\n",
+ "\n",
+ "How many words are reachable in up to ten steps from `vice`?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def reachable_in(word, n, trim_extras=False):\n",
+ " reachable = set()\n",
+ " boundary = set([word])\n",
+ " for i in range(n):\n",
+ " extras = set()\n",
+ " for w in boundary:\n",
+ " extras.update(neighbours[w])\n",
+ " if trim_extras:\n",
+ " extras.difference_update(reachable)\n",
+ " reachable.update(boundary)\n",
+ " boundary = extras.copy()\n",
+ " return reachable.union(extras).difference(set([word]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(11,\n",
+ " '`bash`, `cash`, `dash`, `gash`, `hash`, `lash`, `mash`, `rasp`, `rush`, `sash`, `wash`')"
+ ]
+ },
+ "execution_count": 30,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(reachable_in('rash', 1)), ', '.join(sorted('`{}`'.format(r) for r in reachable_in('rash', 1)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(47,\n",
+ " '`base`, `bash`, `bask`, `bass`, `bast`, `bath`, `bosh`, `bush`, `case`, `cash`, `cask`, `cast`, `dash`, `dish`, `gash`, `gasp`, `gosh`, `gush`, `hash`, `hasp`, `hath`, `hush`, `lash`, `lass`, `last`, `lath`, `lush`, `mash`, `mask`, `mass`, `mast`, `math`, `mesh`, `mush`, `push`, `ramp`, `rasp`, `ruse`, `rush`, `rusk`, `rust`, `sash`, `sass`, `tush`, `wash`, `wasp`, `wish`')"
+ ]
+ },
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(reachable_in('rash', 2)), ', '.join(sorted('`{}`'.format(r) for r in reachable_in('rash', 2)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "180"
+ ]
+ },
+ "execution_count": 32,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(reachable_in('rash', 3))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2195"
+ ]
+ },
+ "execution_count": 33,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(reachable_in('rash', 10))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "2192"
+ ]
+ },
+ "execution_count": 34,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(reachable_in('vice', 10))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "100 loops, best of 3: 6.01 ms per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "len(reachable_in('rash', 10))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "100 loops, best of 3: 2.92 ms per loop\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%timeit\n",
+ "len(reachable_in('rash', 10, trim_extras=True))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "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.5.2+"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
"3. [Door codes](03-door-codes)\n",
"4. [Word search](04-word-search)\n",
"5. [Display board](05-display-board)\n",
- "6. [Activity network](06-activity-network)\n",
- "7. [Word chains](07-word-chains)\n",
- "8. [Suitcase packing](08-suitacase-packing)\n",
- "9. ?\n",
- "10. ?\n"
+ "6. [Tour shapes](06-tour-shapes) [Problem B](https://www.cs.uoregon.edu/Activities/Luks_Programming_Contest/problems/Problems2017.pdf): A is check if string is a closed loop, B is find the area\n",
+ "7. [Activity network](07-activity-network)\n",
+ "8. [Filling the days](08-filling-days) [Problem C](https://www.cs.uoregon.edu/Activities/Luks_Programming_Contest/problems/Problems2017.pdf): A per the problem, B when there are multiple rooms available\n",
+ "9. [Word chains](09-word-chains)\n",
+ "10. [Suitcase packing](10-suitacase-packing)\n"
]
},
{