Added questions to all problem pages, solution workings for days 1 and 2
authorNeil Smith <neil.git@njae.me.uk>
Wed, 2 Aug 2017 11:25:34 +0000 (12:25 +0100)
committerNeil Smith <neil.git@njae.me.uk>
Wed, 2 Aug 2017 11:25:34 +0000 (12:25 +0100)
29 files changed:
01-ticket-prices/ticket-pricing-solution.ipynb
02-lifts/lifts-solution.ipynb
03-door-codes/door-codes-solution.ipynb
04-amidakuji/amidakuji-solution-1.ipynb
06-tour-shapes/question-example-tour-000-s0010-m000-trim.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-000-s0010-m000.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-001-s0012-m000-trim.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-001-s0012-m000.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-002-s0012-m001-trim.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-002-s0012-m001.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-003-s0014-m001-trim.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-003-s0014-m001.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-004-s0051-m001-trim.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-004-s0051-m001.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-005-s0043-m001-trim.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-005-s0043-m001.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-006-s0094-m000-trim.png [new file with mode: 0644]
06-tour-shapes/question-example-tour-006-s0094-m000.png [new file with mode: 0644]
06-tour-shapes/question-examples.txt [new file with mode: 0644]
06-tour-shapes/tour-creation-for-background.ipynb
06-tour-shapes/tour-shapes-build-problem-set.ipynb
06-tour-shapes/tour-shapes-build-raw-tours.ipynb
06-tour-shapes/tour-shapes-sample-tours.ipynb
06-tour-shapes/tour-shapes-solution.ipynb
07-interpreter/interpreter-solution.ipynb [new file with mode: 0644]
07-interpreter/machine-code-4-reg.ipynb
08-word-chains/visa-woes-solution.ipynb [new file with mode: 0644]
08-word-chains/word-chain-solution.ipynb [deleted file]
10-word-search/wordsearch-solution.ipynb

index 8ba20442b6dae95c16ff439de4d42a0c242d26c1..eb0cd2e42ca43889fad8b1644bb9e14cf16ef50c 100644 (file)
     "The 21 day trip to Morgantown and the trips to  Giessenmestia and Nordkapp are all too expensive."
    ]
   },
     "The 21 day trip to Morgantown and the trips to  Giessenmestia and Nordkapp are all too expensive."
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Part 2\n",
+    "You don't just want _a_ holiday. You want the _best_ holiday. What is the code of the holiday which would give you the best value?\n",
+    "\n",
+    "The \"value\" of a holiday is the duration per pound. Because some destinations are better than others, you'll want to scale the value for some locations. For instance, a night in Timbuktu is worth three times as much as a holiday in Bletchley.\n",
+    "\n",
+    "Assume all holidays have a relative value of 1, apart from these destinations.\n",
+    "\n",
+    "| Destination | Score |\n",
+    "|-------------|-------|\n",
+    "| Almaty | 2.0 |\n",
+    "| Brorfelde | 0.9 |\n",
+    "| Estacada | 0.4 |\n",
+    "| Jayuya | 0.6 |\n",
+    "| Karlukovo | 2.2 |\n",
+    "| Morgantown | 2.9 |\n",
+    "| Nordkapp | 1.5 |\n",
+    "| Nullarbor | 2.2 |\n",
+    "| Puente-Laguna-Garzonkuala-Penyu | 0.4 |\n",
+    "| Uzupis | 0.9 |\n",
+    "\n",
+    "## Example\n",
+    "\n",
+    "Given the holiday list above, the holiday to Geoje-Si (with the standard weighting of 1) has a value of $\\frac{14}{782} = 0.0179$ nights per pound. \n",
+    "\n",
+    "The trip to Estacada looks promising, at $\\frac{21}{1052} = 0.0200$ nights per pound. Unfortunately, the weighting for Estacada is low, to the adjusted cost is $0.4 \\times \\frac{21}{1052} = 0.00798$ nights per pound.\n",
+    "\n",
+    "The best value holiday is the 21 day trip to Morgantown, with a value of $2.9 \\times \\frac{21}{1284} = 0.0474$ nights per pound. Unfortunately, it's unaffordable. \n",
+    "\n",
+    "The best value affordable holiday is the trip to Stonnington Island, with $\\frac{14}{1284} = 0.0193$ nights per pound."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Worked example of solving\n",
+    "\n",
+    "For those still getting to grips with things, I thought I'd show how I'd work through solving the day 1 task.\n",
+    "\n",
+    "My first step when looking at this kind of thing is to think about data structures and operations. What data do we have, and what do we need to do with it?\n",
+    "\n",
+    "We're given a list of holidays. In the first part of the task, we have to filter that list against some condition and count how many meet the condition. In the second part, we have to find the holiday with some maximal value. \n",
+    "\n",
+    "How to store holidays? We just need something we can walk over (iterate over). There are many choices. We could just use a list, or a set (if we assume each holiday is distinct), or a dict/map/hashmap, using the holiday ID as a key. They're all much of a sameness, so let's take the path of least resistance and use a list.\n",
+    "\n",
+    "How to represent each holiday? Each holiday is a record of four parts (ID, destination, price, duration). I could use a dict or (in Python) a namedtuple to store the parts. That has the advantage that it gives a name to each of the parts. The alternative is to use a list to store each holiday and refer to the parts by number. Either is good, but as this task is small, I'll be able to get away with just remembering four numbers and what they mean.\n",
+    "\n",
+    "So, my chosen representation is a list of lists. That's not the best representation, but it's good enough for this task."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Next step: reading the list of holidays. Let's just start by trying to read in the data file and split it into a list, one element for each holiday. Let's not try to sort out each holiday in that list at the moment.\n",
+    "\n",
+    "I could look through the Python documentation for how to do this, or I could hit a search engine. \n",
+    "\n",
+    "I'm not the first to have done that. Typing \"python read file lines\" suggests and autocomplete of \"python read file lines into a list\", which is spot on, and leads to a [StackOverflow post](https://stackoverflow.com/questions/3925614/how-do-you-read-a-file-into-a-list-in-python). Result!\n",
+    "\n",
+    "Let's try the top-rated answer, with some print statements to check what's going on:\n",
+    "```\n",
+    "with open('01-holidays.txt') as f:\n",
+    "    lines = f.read().splitlines()\n",
+    "print(len(lines), lines[0])\n",
+    "```\n",
+    "That gives output\n",
+    "```\n",
+    "124 dda7d369 1546 Uzupis 21\n",
+    "```\n",
+    "which looks right: 124 lines, and that's the first line in the file.\n",
+    "\n",
+    "Another quick search for splitting a string into a list points me in the direction of .split().\n",
+    "\n",
+    "I can combine those ideas like this:\n",
+    "\n",
+    "```\n",
+    "holidays = []\n",
+    "with open('01-holidays.txt') as f:\n",
+    "    for line in f.read().splitlines():\n",
+    "        holidays += [line.split()]\n",
+    "        \n",
+    "print(len(lines), holidays[0])\n",
+    "```\n",
+    "\n",
+    "But I actually like the second answer of that Stack Overflow post better, and prefer to use the list comprehension:\n",
+    "\n",
+    "```\n",
+    "holidays = [line.strip().split() for line in open('01-holidays.txt')]\n",
+    "\n",
+    "print(len(lines), holidays[0])\n",
+    "```\n",
+    "\n",
+    "The basic format is `[<do something to item> for <item> in <bunch of items>]`\n",
+    "\n",
+    "I think it's cleaner, and it's certainly more compact."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now we have the holidays, time to find the affordable ones. \n",
+    "\n",
+    "The basic idea is to keep a count of the number of affordable holidays as we walk along the list of holidays. Every time we get to an affordable one, increase the count by one. The price is in the second element of the holiday record, which is number 1 in Python's count-from-zero world.\n",
+    "\n",
+    "That turns quite simply into code:\n",
+    "\n",
+    "```\n",
+    "affordable_count = 0\n",
+    "for holiday in holidays:\n",
+    "    if holiday[1] <= 1200:\n",
+    "        affordable_count += 1\n",
+    "\n",
+    "print(affordable_count)\n",
+    "```\n",
+    "\n",
+    "…which gives an error about unorderable types, comparing `str()` with `int()`.\n",
+    "\n",
+    "That makes sense. Strings and numbers are different, and what we've got is a list of strings. A quick search online tells us that `int(something)` will convert `something` into a number, if possible. Let's make that change and try again.\n",
+    "\n",
+    "```\n",
+    "affordable_count = 0\n",
+    "for holiday in holidays:\n",
+    "    if int(holiday[1]) <= 1200:\n",
+    "        affordable_count += 1\n",
+    "\n",
+    "print(affordable_count)\n",
+    "```\n",
+    "\n",
+    "And that gives the right answer!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now for part 2. \n",
+    "\n",
+    "At first sight, its intimidating. Complex calculation, lots of data to move around. But, let's just start with what we can do easily and see where we end up.\n",
+    "\n",
+    "Each destination has a weight for how much it's liked. If a weight's not given, we use 1.\n",
+    "\n",
+    "We can store the given weights in a `dict`: it's what they were made for. Associate some value with a key; in this case, the key is the destination name and the value is the weight.\n",
+    "\n",
+    "```\n",
+    "destination_values = {'Almaty': 2.0, 'Brorfelde': 0.9, 'Estacada': 0.4, 'Jayuya': 0.6, 'Karlukovo': 2.2, \n",
+    "                      'Morgantown': 2.9,'Nordkapp': 1.5, 'Nullarbor': 2.2, \n",
+    "                      'Puente-Laguna-Garzonkuala-Penyu': 0.4, 'Uzupis': 0.9}\n",
+    "```\n",
+    "\n",
+    "We can get the values from the dict quite easily:\n",
+    "\n",
+    "```\n",
+    "print(destination_values['Jayaya'])\n",
+    "```\n",
+    "\n",
+    "How to get the value when the destination isn't in the table? We could use the defaultdict from the Python library, or we could use the `get()` method which accepts a default value, or we could just wrap some control in a function.\n",
+    "\n",
+    "```\n",
+    "def value_of_destination(name):\n",
+    "    if name in destination_values:\n",
+    "        return destination_values[name]\n",
+    "    else:\n",
+    "        return 1\n",
+    "```\n",
+    "\n",
+    "And try it:\n",
+    "\n",
+    "```\n",
+    "print(destination_values['Mamula'])\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now we can find the destination weight for each destination, how to find the value of a holiday? Again, wrap that in a function so we can call it without getting bogged down in the details. \n",
+    "\n",
+    "The tricky part here is to keep track of data types. We have to convert strings to numbers again, but division involving integers will often give an integer as the answer. The standard trick in these situation is to make sure that at least one number in each calculation is a floating-point number, and Python will ensure that the whole calculation is done a floating point numbers.\n",
+    "\n",
+    "```\n",
+    "def value_of_holiday(holiday):\n",
+    "    hid, cost, destination, duration = tuple(holiday)\n",
+    "    value = value_of_destination(destination) * float(duration) / int(cost)\n",
+    "    return value\n",
+    "```\n",
+    "\n",
+    "Again, we can test it\n",
+    "\n",
+    "```\n",
+    "print(value_of_holiday(holidays[0]))\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now we have the parts for solving the task. Just like part 1, we'll walk over the list of holidays, keeping track of the best value one so far. We have remember two items now, though: the best value, and the code of the holiday with that value. We'll just use two separate variables to keep track of them.\n",
+    "\n",
+    "```\n",
+    "best_holiday = ''\n",
+    "best_value = 0\n",
+    "\n",
+    "for holiday in holidays:\n",
+    "    if int(holiday[1]) <= 1200:\n",
+    "        if value_of_holiday(holiday) > best_value:\n",
+    "            best_value = value_of_holiday(holiday)\n",
+    "            best_holiday = holiday[0]        \n",
+    "\n",
+    "print(best_holiday)\n",
+    "```\n",
+    "\n",
+    "Rather than having two `if` statements, we could say \n",
+    "\n",
+    "```\n",
+    "if int(holiday[1]) <= 1200 and value_of_holiday(holiday) > best_value:\n",
+    "```\n",
+    "\n",
+    "but I'm not sure it's much better in this context.\n",
+    "\n",
+    "And there you have it!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "I hope you found the exposition useful.\n",
+    "\n",
+    "Yes, I use the internet a lot to look up bits of syntax. It's much the same as looking in a textbook and finding snippets of code to reuse and repurpose. The skill of programming isn't so much the mastery of syntax as it is about understanding the problem and how to put together a solution. By all means look stuff up; a good programmer knows what to look up (or ask) and how to use the answer."
+   ]
+  },
   {
    "cell_type": "markdown",
    "metadata": {},
   {
    "cell_type": "markdown",
    "metadata": {},
     "sum(1 for h in open('01-holidays.txt') if int(h.split()[1]) <= 1200)"
    ]
   },
     "sum(1 for h in open('01-holidays.txt') if int(h.split()[1]) <= 1200)"
    ]
   },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# Part 2\n",
-    "You don't just want _a_ holiday. You want the _best_ holiday. What is the code of the holiday which would give you the best value?\n",
-    "\n",
-    "The \"value\" of a holiday is the duration per pound. Because some destinations are better than others, you'll want to scale the value for some locations. For instance, a night in Timbuktu is worth three times as much as a holiday in Bletchley.\n",
-    "\n",
-    "Assume all holidays have a relative value of 1, apart from these destinations.\n",
-    "\n",
-    "| Destination | Score |\n",
-    "|-------------|-------|\n",
-    "| Almaty | 2.0 |\n",
-    "| Brorfelde | 0.9 |\n",
-    "| Estacada | 0.4 |\n",
-    "| Jayuya | 0.6 |\n",
-    "| Karlukovo | 2.2 |\n",
-    "| Morgantown | 2.9 |\n",
-    "| Nordkapp | 1.5 |\n",
-    "| Nullarbor | 2.2 |\n",
-    "| Puente-Laguna-Garzonkuala-Penyu | 0.4 |\n",
-    "| Uzupis | 0.9 |\n",
-    "\n",
-    "## Example\n",
-    "\n",
-    "Given the holiday list above, the holiday to Geoje-Si (with the standard weighting of 1) has a value of $\\frac{14}{782} = 0.0179$ nights per pound. \n",
-    "\n",
-    "The trip to Estacada looks promising, at $\\frac{21}{1052} = 0.0200$ nights per pound. Unfortunately, the weighting for Estacada is low, to the adjusted cost is $0.4 \\times \\frac{21}{1052} = 0.00798$ nights per pound.\n",
-    "\n",
-    "The best value holiday is the 21 day trip to Morgantown, with a value of $2.9 \\times \\frac{21}{1284} = 0.0474$ nights per pound. Unfortunately, it's unaffordable. \n",
-    "\n",
-    "The best value affordable holiday is the trip to Stonnington Island, with $\\frac{14}{1284} = 0.0193$ nights per pound."
-   ]
-  },
   {
    "cell_type": "code",
    "execution_count": 16,
   {
    "cell_type": "code",
    "execution_count": 16,
index dc7724f964ee36d13ca7945c622a46fee7167aea..c52facc07695c869642bb63c65e9cfabc6d76f1c 100644 (file)
     "Given the input in [02-lifts.txt](02-lifts.txt), where would you get out?"
    ]
   },
     "Given the input in [02-lifts.txt](02-lifts.txt), where would you get out?"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Worked example of solution: Part 1\n",
+    "\n",
+    "This is an example of a very common pattern: walking along a list, finding some total or final value. As such, there are a great many ways of doing it.\n",
+    "\n",
+    "The most obvious way is to have a variable that holds the current floor, and update it with every instruction that's read from the list of instructions. As the current floor is just a number, we can have a simple variable.\n",
+    "\n",
+    "The list of instructions will be read as a string, and we can iterate through a string easily, so we'll leave the instructions as a string. Happily, each instruction is one character, so no need to count characters and instructions separately.\n",
+    "\n",
+    "The only complication is that there's no obvious trick for converting the instruction characters. Given that, let's just do a simple `if`-`elisf`-`else` structure (or a `case` statement of your language of choice has it) to convert an instruction into a floor change. \n",
+    "\n",
+    "(I could also have used a `dict` like \n",
+    "\n",
+    "```\n",
+    "value = {'^': 1, 'v': -1, '=': 0}\n",
+    "```\n",
+    "\n",
+    "and it would behave in the same way.)\n",
+    "\n",
+    "(Another common solution was to count the number of `^` characters and the number of `v` characters, subtract one from the other, and give the result. That works for part 1 but doesn't work for part 2!)"
+   ]
+  },
   {
    "cell_type": "code",
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": 2,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
     "        return 0"
    ]
   },
     "        return 0"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now we can find the floor-change of each instruction, we set the initial floor to 0 and run down the list, updating the current floor at each step."
+   ]
+  },
   {
    "cell_type": "code",
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 3,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
     "    return current"
    ]
   },
     "    return current"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Finally, open the file of instructions and find the final floor."
+   ]
+  },
   {
    "cell_type": "code",
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 4,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "209"
       ]
      },
        "209"
       ]
      },
-     "execution_count": 3,
+     "execution_count": 4,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
     "exit"
    ]
   },
     "exit"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "(For my testing purposes, find all the floors visited so I can give sensible hints for wrong answers.)"
+   ]
+  },
   {
    "cell_type": "code",
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 5,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "(10002, 216, -6)"
       ]
      },
        "(10002, 216, -6)"
       ]
      },
-     "execution_count": 5,
+     "execution_count": 6,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 7,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "209"
       ]
      },
        "209"
       ]
      },
-     "execution_count": 6,
+     "execution_count": 7,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
     "The sequence `v^^^^^v=v=` would allow you to exit on floors 3 and 2, so the highest floor you could leave from would be floor 3 (even though the lift reaches floor 4)."
    ]
   },
     "The sequence `v^^^^^v=v=` would allow you to exit on floors 3 and 2, so the highest floor you could leave from would be floor 3 (even though the lift reaches floor 4)."
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Worked example of solution: part 2\n",
+    "This is another common pattern: walking down a list, keeping some extreme value (the largest, the smallest, or something like that.)\n",
+    "\n",
+    "The basic idea is to keep a variable holding the highest exit seen so far, and update it if we see a higher exit. We start with some initial value, such as zero. \n",
+    "\n",
+    "The `highest_exit` function is very similar to the `final` function, but with the `if` statement in the loop. This just checks if we're at an exit and it's higher than what we've seen so far; if so, it updates the `highest_exit` variable.\n",
+    "\n",
+    "It was pointed out in the forums that by starting with the `highest_exit` at 0, we're assuming that the highest exit is above ground. That's true in this case, but its a valid concern. In this case, I should set the initial value to be smaller than the smallest valid value we can find, so that the first exit we find is correctly recorded. In this case, the smallest value for the exit is if all the instructions are down, or -1 × (number of instructions)."
+   ]
+  },
   {
    "cell_type": "code",
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 22,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def highest_exit(sequence):\n",
+    "    highest_exit = -1 - len(sequence) # or 0\n",
+    "    current = 0\n",
+    "    for i in sequence:\n",
+    "        if value(i) == 0 and current > highest_exit:\n",
+    "            highest_exit = current\n",
+    "        else:\n",
+    "            current += value(i)\n",
+    "    return highest_exit"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "215"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "highest_exit(instructions)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "A variation that returns a list of all the exits, so I can generate hints for obvious wrong answers (the last exit, the lowest exit, the first exit, the number of exits)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 11,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "215"
       ]
      },
        "215"
       ]
      },
-     "execution_count": 8,
+     "execution_count": 11,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 12,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "-5"
       ]
      },
        "-5"
       ]
      },
-     "execution_count": 9,
+     "execution_count": 12,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 13,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "209"
       ]
      },
        "209"
       ]
      },
-     "execution_count": 10,
+     "execution_count": 13,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 14,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "-2"
       ]
      },
        "-2"
       ]
      },
-     "execution_count": 11,
+     "execution_count": 14,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 15,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "1259"
       ]
      },
        "1259"
       ]
      },
-     "execution_count": 12,
+     "execution_count": 15,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 16,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "         215: 2})"
       ]
      },
        "         215: 2})"
       ]
      },
-     "execution_count": 13,
+     "execution_count": 16,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 17,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "-2"
       ]
      },
        "-2"
       ]
      },
-     "execution_count": 14,
+     "execution_count": 17,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 18,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "(209, 215)"
       ]
      },
        "(209, 215)"
       ]
      },
-     "execution_count": 12,
+     "execution_count": 18,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 19,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "(209, 215)"
       ]
      },
        "(209, 215)"
       ]
      },
-     "execution_count": 13,
+     "execution_count": 19,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
index 7c5867f02f39e81d5b49d1a8d59699bba786f78d..b1fd1051589e9f2d4df18b83e280c0d3776ee42e 100644 (file)
@@ -45,7 +45,7 @@
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 3,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
@@ -56,7 +56,7 @@
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 4,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
@@ -71,7 +71,7 @@
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 5,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
@@ -80,7 +80,7 @@
        "('a', 'z', 'z', 'a')"
       ]
      },
        "('a', 'z', 'z', 'a')"
       ]
      },
-     "execution_count": 4,
+     "execution_count": 5,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 6,
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
     "def sanitise(phrase):\n",
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
     "def sanitise(phrase):\n",
-    "    return ''.join(l for l in phrase if l in string.ascii_lowercase)"
+    "    return ''.join(l.lower() for l in phrase if l in string.ascii_letters)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'helloworld'"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sanitise('Hello World')"
    ]
   },
   {
    ]
   },
   {
index 15a816add45d15161e4fa63f28547c67de0db43c..0a9b424494a4b744dac91b453edd63c2ac9360df 100644 (file)
@@ -40,7 +40,7 @@
     "\n",
     "# Part 1\n",
     "\n",
     "\n",
     "# Part 1\n",
     "\n",
-    "The full labyrinth description is given in (04-lines.txt). The labyrinth has 26 lines, labelled 0 to 25 inclusive. If you and 25 friends, labelled `a` to `z` in order, entered the labyrinth, in what order would you come out?\n",
+    "The full labyrinth description is given in [04-lines.txt](04-lines.txt). The labyrinth has 26 lines, labelled 0 to 25 inclusive. If you and 25 friends, labelled `a` to `z` in order, entered the labyrinth, in what order would you come out?\n",
     "\n",
     "(Your answer should be one string of 26 letters, without spaces or punctuation, like `acfbed` .)"
    ]
     "\n",
     "(Your answer should be one string of 26 letters, without spaces or punctuation, like `acfbed` .)"
    ]
diff --git a/06-tour-shapes/question-example-tour-000-s0010-m000-trim.png b/06-tour-shapes/question-example-tour-000-s0010-m000-trim.png
new file mode 100644 (file)
index 0000000..bab9f89
Binary files /dev/null and b/06-tour-shapes/question-example-tour-000-s0010-m000-trim.png differ
diff --git a/06-tour-shapes/question-example-tour-000-s0010-m000.png b/06-tour-shapes/question-example-tour-000-s0010-m000.png
new file mode 100644 (file)
index 0000000..0d222fe
Binary files /dev/null and b/06-tour-shapes/question-example-tour-000-s0010-m000.png differ
diff --git a/06-tour-shapes/question-example-tour-001-s0012-m000-trim.png b/06-tour-shapes/question-example-tour-001-s0012-m000-trim.png
new file mode 100644 (file)
index 0000000..ccfd7da
Binary files /dev/null and b/06-tour-shapes/question-example-tour-001-s0012-m000-trim.png differ
diff --git a/06-tour-shapes/question-example-tour-001-s0012-m000.png b/06-tour-shapes/question-example-tour-001-s0012-m000.png
new file mode 100644 (file)
index 0000000..04eb536
Binary files /dev/null and b/06-tour-shapes/question-example-tour-001-s0012-m000.png differ
diff --git a/06-tour-shapes/question-example-tour-002-s0012-m001-trim.png b/06-tour-shapes/question-example-tour-002-s0012-m001-trim.png
new file mode 100644 (file)
index 0000000..3181a5c
Binary files /dev/null and b/06-tour-shapes/question-example-tour-002-s0012-m001-trim.png differ
diff --git a/06-tour-shapes/question-example-tour-002-s0012-m001.png b/06-tour-shapes/question-example-tour-002-s0012-m001.png
new file mode 100644 (file)
index 0000000..1493861
Binary files /dev/null and b/06-tour-shapes/question-example-tour-002-s0012-m001.png differ
diff --git a/06-tour-shapes/question-example-tour-003-s0014-m001-trim.png b/06-tour-shapes/question-example-tour-003-s0014-m001-trim.png
new file mode 100644 (file)
index 0000000..c31b005
Binary files /dev/null and b/06-tour-shapes/question-example-tour-003-s0014-m001-trim.png differ
diff --git a/06-tour-shapes/question-example-tour-003-s0014-m001.png b/06-tour-shapes/question-example-tour-003-s0014-m001.png
new file mode 100644 (file)
index 0000000..132bef0
Binary files /dev/null and b/06-tour-shapes/question-example-tour-003-s0014-m001.png differ
diff --git a/06-tour-shapes/question-example-tour-004-s0051-m001-trim.png b/06-tour-shapes/question-example-tour-004-s0051-m001-trim.png
new file mode 100644 (file)
index 0000000..848d13f
Binary files /dev/null and b/06-tour-shapes/question-example-tour-004-s0051-m001-trim.png differ
diff --git a/06-tour-shapes/question-example-tour-004-s0051-m001.png b/06-tour-shapes/question-example-tour-004-s0051-m001.png
new file mode 100644 (file)
index 0000000..1f0cedd
Binary files /dev/null and b/06-tour-shapes/question-example-tour-004-s0051-m001.png differ
diff --git a/06-tour-shapes/question-example-tour-005-s0043-m001-trim.png b/06-tour-shapes/question-example-tour-005-s0043-m001-trim.png
new file mode 100644 (file)
index 0000000..058b95e
Binary files /dev/null and b/06-tour-shapes/question-example-tour-005-s0043-m001-trim.png differ
diff --git a/06-tour-shapes/question-example-tour-005-s0043-m001.png b/06-tour-shapes/question-example-tour-005-s0043-m001.png
new file mode 100644 (file)
index 0000000..2a0d8f0
Binary files /dev/null and b/06-tour-shapes/question-example-tour-005-s0043-m001.png differ
diff --git a/06-tour-shapes/question-example-tour-006-s0094-m000-trim.png b/06-tour-shapes/question-example-tour-006-s0094-m000-trim.png
new file mode 100644 (file)
index 0000000..ec245e7
Binary files /dev/null and b/06-tour-shapes/question-example-tour-006-s0094-m000-trim.png differ
diff --git a/06-tour-shapes/question-example-tour-006-s0094-m000.png b/06-tour-shapes/question-example-tour-006-s0094-m000.png
new file mode 100644 (file)
index 0000000..a1853e4
Binary files /dev/null and b/06-tour-shapes/question-example-tour-006-s0094-m000.png differ
diff --git a/06-tour-shapes/question-examples.txt b/06-tour-shapes/question-examples.txt
new file mode 100644 (file)
index 0000000..0eaa964
--- /dev/null
@@ -0,0 +1,7 @@
+FFRRFLRRFR
+FFLLRLRLLFLR
+RRFFLLFFFFLF
+RRLLRRFFRFRFLR
+FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFF
+FLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL
+FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFFFLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL
index 74716dfbb4714f99fe0c0ce7a92b0f29319298cd..e9848a5be14cc87742c55a7185ab4a446cc3505b 100644 (file)
    },
    "outputs": [],
    "source": [
    },
    "outputs": [],
    "source": [
-    "def plot_trace(trace, colour='k', xybounds=None, fig=None, subplot_details=None, filename=None):\n",
+    "def plot_trace(trace, colour='k', highlight_start=True,\n",
+    "               xybounds=None, fig=None, subplot_details=None, filename=None):\n",
     "    plt.axis('on')\n",
     "    plt.axes().set_aspect('equal')\n",
     "    plt.axis('on')\n",
     "    plt.axes().set_aspect('equal')\n",
+    "        \n",
+    "    if highlight_start:\n",
+    "        plt.axes().add_patch(plt.Circle((trace[0].x, trace[0].y), 0.2, color=colour))\n",
+    "        \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=colour, ec=colour, length_includes_head=True)\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=colour, ec=colour, length_includes_head=True)\n",
index 05df3100e5e578478bbb4fa4a1b6cf51670f6d81..5d9c57dd6396809f6d02e2f2d4cc83f3f481cb71 100644 (file)
    },
    "outputs": [],
    "source": [
    },
    "outputs": [],
    "source": [
-    "def plot_trace(trace, colour='k', xybounds=None, fig=None, subplot_details=None, filename=None):\n",
+    "def plot_trace(trace, colour='k', highlight_start=True,\n",
+    "               xybounds=None, fig=None, subplot_details=None, filename=None):\n",
     "    plt.axis('on')\n",
     "    plt.axes().set_aspect('equal')\n",
     "    plt.axis('on')\n",
     "    plt.axes().set_aspect('equal')\n",
+    "        \n",
+    "    if highlight_start:\n",
+    "        plt.axes().add_patch(plt.Circle((trace[0].x, trace[0].y), 0.2, color=colour))\n",
+    "        \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=colour, ec=colour, length_includes_head=True)\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=colour, ec=colour, length_includes_head=True)\n",
index 79030704fc2185b126ee6e997df8ba9c649eda90..7731efa0d2ba79a3bcba4b6cc74f3afafed2507e 100644 (file)
    },
    "outputs": [],
    "source": [
    },
    "outputs": [],
    "source": [
-    "def plot_trace(trace, colour='k', xybounds=None, fig=None, subplot_details=None, filename=None):\n",
+    "def plot_trace(trace, colour='k', highlight_start=True,\n",
+    "               xybounds=None, fig=None, subplot_details=None, filename=None):\n",
     "    plt.axis('on')\n",
     "    plt.axes().set_aspect('equal')\n",
     "    plt.axis('on')\n",
     "    plt.axes().set_aspect('equal')\n",
+    "        \n",
+    "    if highlight_start:\n",
+    "        plt.axes().add_patch(plt.Circle((trace[0].x, trace[0].y), 0.2, color=colour))\n",
+    "        \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=colour, ec=colour, length_includes_head=True)\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=colour, ec=colour, length_includes_head=True)\n",
   {
    "cell_type": "code",
    "execution_count": 119,
   {
    "cell_type": "code",
    "execution_count": 119,
-   "metadata": {},
+   "metadata": {
+    "collapsed": true
+   },
    "outputs": [],
    "source": [
     "tours_filename = 'tours-random-walk.txt'\n",
    "outputs": [],
    "source": [
     "tours_filename = 'tours-random-walk.txt'\n",
index e438aedaf30b2183d861d6a700b8069766c10407..59f7720f2f2368acf9aff9b42a4dd976b4851538 100644 (file)
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 58,
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
-    "def plot_trace(trace, colour='k', xybounds=None, fig=None, subplot_details=None, filename=None, show_axis=False):\n",
+    "def plot_trace(trace, colour='k', highlight_start=True,\n",
+    "               xybounds=None, fig=None, subplot_details=None, filename=None, show_axis=False):\n",
     "    if show_axis:\n",
     "        plt.axis('on')\n",
     "    else:\n",
     "        plt.axis('off')\n",
     "    plt.axes().set_aspect('equal')\n",
     "    if show_axis:\n",
     "        plt.axis('on')\n",
     "    else:\n",
     "        plt.axis('off')\n",
     "    plt.axes().set_aspect('equal')\n",
+    "    \n",
+    "    if highlight_start:\n",
+    "        plt.axes().add_patch(plt.Circle((trace[0].x, trace[0].y), 0.2, color=colour))\n",
+    "        \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=colour, ec=colour, length_includes_head=True)\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=colour, ec=colour, length_includes_head=True)\n",
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 23,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 53,
    "metadata": {},
    "outputs": [
     {
      "data": {
    "metadata": {},
    "outputs": [
     {
      "data": {
-      "image/png": "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\n",
+      "image/png": "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\n",
       "text/plain": [
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fcb73ad0978>"
+       "<matplotlib.figure.Figure at 0x7f2cfbc25ac8>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 54,
    "metadata": {},
    "outputs": [
     {
      "data": {
    "metadata": {},
    "outputs": [
     {
      "data": {
-      "image/png": "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\nhMqGoYtNhANGByBP3bLhxWPIPI4M8pSuE9AJQL7SdQJzGCAcgDybqBOQGIQ8dUcHJAahC3UCMLi6\nQ4TKhqGLTYQDyoYhz6rE4KpxxWMt6gT+uNvt7kXEXyLio4i4GRHPIuL9iPgiIn4ZEXfb8l9FxO2I\n+Doi7kXENxHxoP3sb2353Yj4Z/v5fyPivYi4FRF/j4iHbb1PI+JncdlLXrT1P23r34+Ix22/1yPi\neWvL56199yPiUUR83Lb9tO3zq4j4eXvvX9u23o+IJ60tT9u+b7W2PmzrfR4RH0TED21/tyPik7b+\nvdbuX8TlyTyLiDuLtj5obfkoLs/bs8Xv/2Fb/9Hecbvfvn/QtvV4r633I+L79v61x+1aRLxo2/+s\nHav94/Zt2+eX7fdbnuM77Xje3zvHjw8ctxdx+Tez39ZP2vmIuLzt9vK43W/n6MNXnOP57/Hjtt3/\n7J3j5XG7036HBxHxXdvO3Jb57/GzdtxetvN4q7Vvbuuhc/yPxXGb23qz7eNu/P9n41Hb1qHPxsNY\nY5qm9K+4/EP5U1z+QU3tQE97X98tXv/rwPKLxesnB5ZPr1h+fmD5l4vX3x9Y/s3i9b8PLH++eP3V\nEW059PXF4vUPB5Yvt//tgeVPrzhuZyvbcuhredyeH1j+9RXn+NkRx+2qtiyXv7yirc8OLL/qHL94\nxbbWnOMnr9juofP29MDyYz4bfzj287kz1R/GZnQABqcTgMHpBGBwOgEYnE4ABqcTgMHpBGBwOgEY\nnE4ABqcTgMHpBGBwOgEYnE4ABqcTgMHpBGBwOgEYnE4ABqcTgMHpBGBwOgEYnE4ABqcTgMH9D868\nJ7EMO+IfAAAAAElFTkSuQmCC\n",
+      "image/png": "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\n",
       "text/plain": [
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea71b8cc0>"
+       "<matplotlib.figure.Figure at 0x7f2cfbca67b8>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 26,
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f2cfbcdf748>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot_trace(trace_tour(square_tour(a=5)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
    "metadata": {},
    "outputs": [
     {
      "data": {
    "metadata": {},
    "outputs": [
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQQAAAD7CAYAAACMu+pyAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADr5JREFUeJzt3UuPHNd1wPF/cR4cvilyhjIdSZb1iDjcJICXXiRIjHyC\nbLIwkH2W+QpZB/kMWdmfIVkkqwCxYcCBQpGKZSeybJHicPjScDjPyuJW97QosaevfFn3VM//BxAj\n1VRXH3Z1Hd46dR9N27ZIEsCp2gFIisOEIGnMhCBpzIQgacyEIGnMhCBpbLF2ADrSNM1fAj8E9oAl\noAV2gBVgn5TATwHbwBngsNtnEXgGnAUOuu1L3X5nu9fud8d59g3btrufB917rwDPgdPdsfa6/94F\nll+Ia697/2YiroMuztG20fvR7Tu57aA75ui1o20rwNbE32m/i+H5N8S6MxHrZFwHwD+1bbs7+1k4\n2Rr7IcTRNM03nYzRRThpdAEct98+ZZJ+S7q4jzv2HxLrIWVarAfAwsT//1fbtn9S4Lgngi2EeP6q\nbdt/qR3EPGia5h4pmWlGJoR4lmoHMEeukVoempEJIR7vd8u5BdyvHcSQmBDisYVQzk3gbu0ghsTH\njvHsH7+LZrQFPK0dxJCYEDTPHmNCyOItQzzeMpTzXfw8s5gQ4rGoWM5HWFTMYkKIx3NSzjpwsXYQ\nQ2INIR6fm5ezTerqrBmZEOKxZ10594GHtYMYEpun8XhOynkLOFc7iCHxyxfPXu0A5sht4IvaQQyJ\nCSGeheN30YxukIZPa0bWEOJ5cZixvr1d0nBozcgWQjw+ZSjnM7xlyGJCiMdWWznvAFdqBzEkJoR4\nHNxUzsfYQshiQojHFkI57/H1qdo0hV++eHzKUI6dvDLZQojHqng5v8bBTVlMCPHYaivnfWCtdhBD\nYkKIxxZCOZ9gUTGLCSEe73vLebN2AENj8zSeFxc10be3jP/oZfHDisfBTeXcATZqBzEkJoR4fOxY\nzgdYVMxiQojHnorl/Bb4vHYQQ2JC0Dy7QlrtWjOyqBiPRcVyzpGWmNeMbCHEs1M7gDlyG4uKWUwI\n8XhOyrkBPKgdxJD45YvHx47lfI6LvWaxhhCPPRXLOQOs1A5iSGwhxGMRrJzLpBWgNSMTQjwWFctx\nbcdMJoR4PCflrAOrtYMYEmsI8VhULOcBFhWzmBA0z1pc5yKLzdN47KlYziq2uLKYEOKxqFjOLSwq\nZjEhxLNUO4A5chO4VzuIIbGGEI/Dn8t5AjysHcSQmBA0z7bxFiyLtwzxeMtQzuu1AxgaE0I8u7UD\nmCO3cPhzFhNCPLYQyrmJU6hlsYYQjwu1lPMM+LJ2EENiQojH4c/lbJKeNGhG3jLE4y1DOW/gfAhZ\nTAjxWFQsx+HPmUwI8XhOylkHLtYOYkisIcRjDaGcHeyYlMWEEM9h7QDmyF2cdTmLzdN4XNuxnO8B\nF2oHMSQmhHgc3FTObeCL2kEMiQkhHlsI5dwAztYOYkisIcTjOSlnD3t+ZrGFEI9FxXI+xX4IWUwI\n8TgpaDnv4jTsWUwI8VhULOdXOIVaFhNCPLYQynkbi7RZLGDF4+Cmck5hgs1iCyEe1xEo5xMsKmYx\nIcTjOSnnfSwqZvHLF49FxXJ+g0XFLFUTQtM0Pwb+kTQZ5rvAc9IsN+8C/03qi35AOqnrwIfAd0n3\nhb/vtt0BrpKWQPuUNI/eJ6Q+7OdJX4p14DPS/fnl7vfr3XFbYA34GPgAeAxsAX9E6vr6Hmkqrkek\nItUt4B3SvAUbpH+FPgTeIvUhuNsd+xbwHVJR67Muro+BK6RJO/6v2+9/gXNdrCrrOvBm0zT/Tszz\nPfpu/q573RXSk5Eb3XvtkWaOvtPF+rT78yZprofRNfMQ+D7pmvk+6R+Ve91xPiRNFAPwa+Cv27Z9\n6VoVtVsI/9z9XCOdkB1STFe6bW+RPpRD4BJwjfRhnOq2v0b6wK6TPvTt7rVbpAv/AukDXCUlluXu\nNY+74y9029dIieh10sl62r3XBikBPSMlnNVu3ze6WE91x7tGSl77XayXJ2Jd7PYdxXqN1J12i5TI\ndkhfjovAfwL/8e0/Tr3gb4GfcHTeop3v0Xez5SghPOpes0xKQte6WL9D+j6PvrsbpGvmOekfuqsT\nMex2xxzF9Vb3/28Dfwf8w8s+sNoJAeAnbdv+Te0gNH/atv0p8NPacUTRNE3LMUXrCI8dndFG6s/U\nOSZrJ4RNXEhD6tPUGaRqJ4QrpHstSf04Pe2XtRMC+JhN6tPU0bS1E8IhqaIr6dU7IPgtwynSbYOk\nV2+B4EXFR1hUlPoU+rHjZVKHI0n9mNr3qHZCAKcMk8KonRCe43LdUl/2CF5UXCH1wZb06i0RvKj4\nFJfakvoUuqh4AccySH0KX1R0tWOpP1PnmKydEJ6QxndLevV2SIX8l6qdEC6SJnCQ9OqdJnhRcRuL\nilKfpq51WTshnCEVFiUFUDshgAtpSH2aupJV7YSwibcMUl92SbfpL1U7IVwhzUwr6dVbJs0A/VK1\nE8I+aU55Sf0IXVRcJM2LL6kfoadQgxgxSCfF1NXFa1+MG1hUlPqyR/Ci4mipLEmv3hKp789L1U4I\nkIZAS+pH6KIiHLNwhKSipq6DEiEhTC1ySCoq9MpNGzgNu9SXlgEUFVcrxyCdFA0DKCpOzViSigpf\nQ4gQg3RShE8IU2dwkVRU6FuG+90fSf2Yutp67YSwhkVFqU+hWwhwzCywkooKP9rRxV6l/uxO+2WE\nhHC+dgDSCRJ6GvYNLCpKfQq9UMsqaV5FSf0IPZYBjlmNVlJRU9dSjZAQdmoHIJ0g4YuKl2oHIJ0g\noYuKD3FORalPoYuKr2ELQepT+KLi1DneJBUVuqi4zzGDLSQVc8AxRfzaCWER+yFIfVkgeFHxMc6p\nKPVpar+f2gnhEhYVpT6FXsoNjilySCoqdFFxC3hSOQbppNgleFHxHK7tKPVlmeBFxS0sKkp9Cj3r\n8jngYuUYpJNk6jVfOyFI6lcz7Ze1E8Jj4FHlGKSTYofgg5suAdcqxyCdFKcJPg37cxz+LPUp9DTs\nKzjrstSn0B2TIEYM0kmxOO2XtS/GB8Bm5Rikk2KX4Gs7XsWiotSXZeDstB1qJ4RD0qNHSf2YOkNZ\n7YRwimP6VksqKvRTBjimyCGpqNDzIWzg4CapL/vA9rQdaieEVSwqSn1ZJHhPRYCntQOQTpDQRUVI\nj0Ik9SP0fAhwTJFDUlGhZ0y6j0VFqU+heyqukQqLkvoRuqciHPMYRFJR4WsIU6d0klRU+IQw9bmo\npKJCLwdvT0WpX6HnVFzF1Z+lPoV+7Ahp0gZJ/QjfU3FqkUNSUVOXg48w9Pidpml+RIqlJY3XXiAl\nigVS0jokPY3Y734ukf5iixwllKWJ1+x3xzrd7bfA0QexQrqPGh2jIXWf3ul+7nWvXSa1XpY4yqqj\n44xibbv49rufC92+o22jWPf5agyTcR10f7/TwL22bX/+bT5EfV3TNEvAX5A+44jne7c79iiGM6Tv\n5iiW0fF2J47LxLbJa2Zx4j2abtuLscIxtwxN29Zbjb1pmn8D/qxaADH9adu2v6wdxDxomuZ/gPdq\nxxHMD9q2/cXLflm1hdC27Z/XfP9omqZpcTh4SdeBO23b3qgdyFBEqCHoq6Y+J1aWc9jPJUuEGoK+\naqd2AHPkNvZzyWJCiMdzUs4NXCowi1++eKY+FlKWz4G7tYMYEmsI8dR77DN/zuA0/1lsIcRjEayc\ny8BW7SCGxIQQj0XFcj4izcqlGZkQ4vGclLOOM3JlsYYQj0XFch5gUTGLCUHzrMUZubLYPI3Hnorl\nrGKLK4sJIR6LiuXcwqJiFhNCPC5cU85N4F7tIIbEGkI8ThhTzhPgYe0ghsSEoHm2jbdgWbxliMdb\nhnJerx3A0JgQ4nHS2XJu4fDnLCaEeGwhlHOTNOJRM7KGEM/UabKV5RnwZe0ghsSEEI/Dn8vZJD1p\n0Iy8ZYjHW4Zy3sD5ELKYEOKxqFiOw58zmRDi8ZyUsw5crB3EkFhDiMcaQjk72DEpiwkhnsPaAcyR\nuzjrchabp/EsHL+LZvQ94ELtIIbEhBCPg5vKuQ18UTuIITEhxGMLoZwbwNnaQQyJNYR4PCfl7GHP\nzyy2EOKxqFjOp9gPIYsJIR4nBS3nXZyGPYsJIR6LiuX8CqdQy2JCiMcWQjlvY5E2iwWseBzcVM4p\nTLBZbCHE4zoC5XyCRcUsJoR4PCflvI9FxSx++eKxqFjOb7ComMWEoHl2HRNsFouK8VhULGcF18rM\nYgshHv9FK+cOFhWzmBDi8bl5OR8Aa7WDGBITQjw+diznM1yXIYsJQfPsEq7LkMWiYjwWwcq5AJyv\nHcSQ2EKIx1uGcj7CtR2zmBDisahYzjomhCwmhHhsIZRzD4uKWawhxOO6DOUsY0evLLYQ4jlTO4A5\n8hppBWjNyIQQz/PaAcyRW1hDyGJCiMcmbjk3cV2GLNYQ4rGoWM4mJoQsJoR4nPKrnAMs0mbxliGe\n5doBzJE1XKgliwkhHpcvL8eiYiYTQjy2EMq5SVoSXjOyhhCPRcVyvgSe1A5iSEwI8VgEK+cpsFU7\niCHxliEebxnKuY6DxbKYEOLZrR3AHPkI51TMYkKIx56K5ayTZk3SjKwhxONz83Ke4eCmLCYEzbMH\nwKPaQQyJtwzxWAQr500cTp7FhBCP/RDKsaiYqWlbH3tH0TRNC/wMuA1cBg5JHWvWSF1wL5AGPz0C\nrpGaxOdJt36b3bbHpCXMFrvXXCM9jx/NHrTRHe9Zd6yzpIvmCukJx373PveBq6QEtU2abGSji+uA\n1OnnarftEqn/xCjWUVyTsW5277XQ/fdat//KxLZVUr+BpS7e+91+291ncX4irt3uz8Uuhte62Cdj\n/THwu7Zt38g6ESeYLYRY/hX4EfDHHFXHt4BzEz8hXWSXSZOprHTbHpAulEOOakMbfH059NFFNumb\n9hsdb9JD0sUG6WJcJl3UF7ttT0nJ5Bnp4p98zWj/yfdrORrd+YfEuklKaHD09x/VDv4ezcwWgqQx\nnzJIGjMhSBozIUgaMyFIGjMhSBozIUgaMyFIGjMhSBozIUgaMyFIGjMhSBozIUgaMyFIGjMhSBoz\nIUgaMyFIGjMhSBozIUgaMyFIGjMhSBozIUga+39B5c93LYMfSQAAAABJRU5ErkJggg==\n",
+      "image/png": "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\n",
       "text/plain": [
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea71dde10>"
+       "<matplotlib.figure.Figure at 0x7f2cfbab1400>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": 56,
    "metadata": {},
    "outputs": [
     {
      "data": {
    "metadata": {},
    "outputs": [
     {
      "data": {
-      "image/png": "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\ndwO41XcnEvOQAd2izoOgzsuuu3sOPO27E4k5xfLxGrmnwHbfnUjM49gCjhi07DaBT/vuRGKuYfn4\nQUtp+wzVVZz5WBUtH5/SjuepRJ3rpLsDwrRoTVg+fuBcJ90dYfKxKlo+PqURg7UH6lwn3T3A0m5V\nt4C7bQukFBhS6ksqXCfdXcPp9lUbhDxDo5ROJfx0rDPH0J3l4+teYfn4QTPH0N0bLB9fZfn4gTMw\ndPch5hiqLB8/cAbL7lLax1NxA8vHa+S2McdQdUgo79YopWjqsLnOEUN3K6T1AZiCQyL3lUgpMDhi\nqPNrtu7uA5/03YnE3GdAU6ItH19nsOzuHa7HqkGVj/c7+zpPr7rbxlvUVe0xoKsrPZ/WRbiG5eOr\njgnXkDRKKTCozu3T3V0sH181qPLxKZ3WpMLy8d0dE7nEeIQyIsdbSgejB0FdSoF7qCwfX7dD5NhP\naccz0aaLsEEYOmsiJ5LTSykwqM5g2d0NTD5WPSJy/UhKpxKbWZatEL62LCPaKuE76Kz498uEU47y\ngMmmll3h/UhYtlW+9tLU801tvy2ey6b+nQtoe2Xq+ayhbfAr3Hk4Ap5lWfaQ5vXdtm1XeX+fnN4H\nc8K2L5+fbqtt2/6xbTP1+mzq75z395v8jLan98mcyKl7SoHhD313IEHec7G73wJ/CvzUd0cS829t\nT2Z57vQBSe8zxyCpxsAgqcbAIKnGwCCpxsAgqcbAIKnGwCCpxsAgqcbAIKnGwCCpxsAgqcbAIKnG\nwCCpxsAgqcbAIKnGwCCpxsAgqcbAIKnGwCCpxsAgqcbAIKnm/wGyPjyrfbBoQAAAAABJRU5ErkJg\ngg==\n",
+      "image/png": "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\nAABJRU5ErkJggg==\n",
       "text/plain": [
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea6f8a160>"
+       "<matplotlib.figure.Figure at 0x7f2cfb990d30>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
      "data": {
       "image/png": "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\n1sd/Aw+RJa+eq45oAAAAAElFTkSuQmCC\n",
       "text/plain": [
      "data": {
       "image/png": "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\n1sd/Aw+RJa+eq45oAAAAAElFTkSuQmCC\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea6d354e0>"
+       "<matplotlib.figure.Figure at 0x7f2cfb8b1dd8>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 68,
+   "execution_count": 30,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "10"
       ]
      },
        "10"
       ]
      },
-     "execution_count": 68,
+     "execution_count": 30,
      "metadata": {},
      "output_type": "execute_result"
     },
      "metadata": {},
      "output_type": "execute_result"
     },
      "data": {
       "image/png": "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\nJogA7b/FLob4OhrHyQAAAABJRU5ErkJggg==\n",
       "text/plain": [
      "data": {
       "image/png": "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\nJogA7b/FLob4OhrHyQAAAABJRU5ErkJggg==\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea6b5b1d0>"
+       "<matplotlib.figure.Figure at 0x7f2cfb83d3c8>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
      "data": {
       "image/png": "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\nAElFTkSuQmCC\n",
       "text/plain": [
      "data": {
       "image/png": "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\nAElFTkSuQmCC\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea6ff01d0>"
+       "<matplotlib.figure.Figure at 0x7f2cfb9748d0>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
      "data": {
       "image/png": "iVBORw0KGgoAAAANSUhEUgAAASMAAAEACAYAAAD4GBC1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAACyxJREFUeJzt3W2spHdZx/Hvr552d8v2KV2FtkELGGwgkKLUB4Lb8sKm\nGB8SFXVfaGJB1FKrCUrarRVNoUDTghqr2GAjwRgxohKDDzFRUw3gAxXUhCUNqAlSoK1uS93ubrvn\n8sV9L6jJdncbz/2/zsz3k0w607S5rplz5nv+M2/uVBWSNNoZoxeQJDBGkpowRpJaMEaSWjBGklow\nRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBG\nklowRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaS\nWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBGC0qyO8nrklw0ehepm43RC6yDJLuBG4AbgV3AlyW5\ne8EVjlXVEwvOk05bqmr0DisvyYPAnvlhARmwxtdW1T8MmCudEj+mLWMP8H7gILAJXFdVWeIG7J9n\n3jbw+UsnZYyWcy9wMfBa4H1LDJw/Ht7E9HO+MsmLl5grPR3GaEFV9XhV3VNVn19o5JXAM+b7O4B9\nC82VTpsxWm1/DFw+378WePPAXaSnZIxWWFVtVtU/zQ8PVNVjQxeSnoIxktSCMZLUgjGS1IIxktSC\nMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS1IIx\nktSCMZLUgjGS1IIxktSCMdpCSc5I8h3zw71Jnjt0IamxjdELrLgXAe+f738bcAT4vnHrSH2t1cko\nyZ4ktyW5YqGR/wgcv4jiEeAdC82Vtp21OBkleSbwU8B1wE7g8iR3LDT+PcBbgfuq6sMLzZS2nbWI\nEXAfcPH/ePzK+bak/QvPAyDJhcAhYM+I+dKpWpePaRcD9wIfAwp4W1Vl4dtfDXrub2A6Df7MoPnS\nKVmXGAE8CLwEuAq4fewqy5hPRdcz/ZxfnOTlg1eSTmidYkRN7q2q/xi9y0K+Dtg13z8b+JaBu0hP\naV2+M1pXfwZcABwErgb+Yuw60omt1clo3cwnwUfmh49W1ZNDF5KegjGS1IIxktSCMZLUgjGS1IIx\nktSCMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS\n1IIxktSCMZLUgjGS1MJKxyiTV88Pr0myd+hCkk5opWMEXAjcDWwyXVn1bWPXkXQiKx2jqnoI+C2m\nGD0OvHGp2UneneR1SXYsNfNkklyV5A+SPGfA7CT5ziS/n+TCAfM3kvxAkt8Z8TNJsjPJDUnuWXr2\ndpGqGr3DlprfePcDDwJ3LTj6VuAQcBi4raruXHD2/5KkgAPAs4GdwJ8CH1pwhcPAa4GLgN3AbwCf\nXHD+E8ANwLnz/NuBLyw4/0zgx4EdwNnALQvOBri7qj6/8MzTtvIxAkjyLuDVJ/0Pt8ZR4Czg+6vq\nvSMWSPIR4HLGnYT/EzgH2Bg0/2GmEJ05aP5jTL8DZw2a/1ngkqraHDT/lKz0x7Tjquo1VZUlb8AR\npjfhG+Y1Lhn3CvBS4Grgo/PjVy78WuwBvhf41Dz/hQvPfxbwI0xvygLOX3j+VwA3AgeBQwvPPQSc\nB3zXMr9qT19qDU5GIyR5LvCZqjo8f0x6fVW9ffBOAS4DDtSAH3ySM4DnV9WBpWfP8zeA51TV/YPm\n7wKeVVX/stC8twPXMX08/FfgedX4dDTq2LzyqupTJ/+vljUH6OMD528yfXc1av6TTN8fjpr/OLBI\niGYvYAoRTB+Tz2U6nbW0Fh/TpHVUVdcAH5jv76mqtiECYySpCWMkqQVjJKkFYySpBWMkqQVjJKkF\nYySpBWMkqQVjJKkFYySpBWMkqQVjJKkFYySpBWMkqQVjJKkFYySpBWMkqQVjJKkFYySpBWMkqQVj\nJKkFYySpBWMkqQVjtIWSnD1f1RPg+iRXD11IaswYba1nAz85378U2DduFam3tYpRkquSfDjJq5aY\nV1WfYLqi5yZwBPj5JeZqvSXZl+SDSfaO3uV0ZLr8+mpL8grgDuBrgGfM//pPFhq/G3g58J6q+sGF\nZqqJJGcBtzP97i3lmvmf/wU8AZxfVVlw/tOyLjEq4BjwJLBjwAoHga+vqvsHzNZASd4E3Dxo/BEg\nwJuq6tZBO5yydfqY9kfArwBHgZurKgveLjBE6yfJucBPMP3O3bbU7xvT1wFHgV8GLtkOIYL1Ohm9\nr6q+J8l5wKO1Dk9cQyW5helUtAM4DFxUVQcXmHsGcE5VPbLVs/4/rdPJCICqesQQaSG7+NLXAp/h\nS99Xbqmq2txuIQLYGL2AtKqqan+SR4G3VNXzRu/T3dqdjCT1ZIwktWCMJLVgjCS1YIwktWCMJLVg\njCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCM\nJLVgjCS1YIwktbDSMUqyI8l754ffneSnhy4k6YRWOkbATuDb5/sFfPNSg5NkqVkdjX7+o+fr9K10\njOZL/N7BdJ3zw8BNC47/eJLfS3LZgjNbSHIp8ECSO5PsGTD/CuCzSW5Ocs7S8/X0ZNUvO5/kfOAB\nIMDRBUefAxybZ34Q+NaqWnL+FyV5I/D6BUceD8BhYBP4a+CbBsw/xPQz+IWq+tkF539Rkv3Am6vK\nk9pJrHyMAJJcC/z6gNHF9IbcBVxfVXctvUCSlwD3LT13dpQpRh8DvmHA/MNMf4R2jIpBkl8Cfgz4\nyqp6YMQO28VKf0w7rqruqaoseQM+DfwlsHdeY8egp387UxQfYn5TLvDcvxr4AvCbwPOr6hsXfu1f\nBjwG3AW8atDrTpIvB17D9PrfMmqP7WJj9AIr7NKqOgYw6rvU+VT0CqbTwbnAtcA7t3puVX0yyQXH\nn//SqupDSc6vqmNJ9p78/9gyNwFnMr3PfjjJrZ6OTmwtTkYjjHoj/h+HgL+d7/870+loEaOf/+j5\ns39j+kMA0/eGQ74z3C48Ga2wqvoE8LIkBeyrqr8ZvdM6qapfTLILeEtVXTl6n+48GUlqwRhJasEY\nSWrBGElqwRhJasEYSWrBGElqwRhJasEYSWrBGElqwRhJasEYSWrBGElqwRhJasEYSWrBGElqwRhJ\nasEYSWrBGElqwRhJasEYSWrBGElqwRhJasEYbaEkFyf56PzwziQ3Dl1ozST5IeB35/v/nOSFg1fS\nUzBGW+sY8IL5/lFg51KDkyw2q7ENpst6A1zG9PNYhK//6TNGW6iqPsd0bfsn5ts7lpib5Dzg4SR/\nnuSlS8xs6t3AI0ABf1hVB5YYmmQfcDDJncDZS8xcBamq0TustCTPBD7NmEuJF3CE6UR2RVX9/YAd\nhkryo8CvDhi9yXQa3gA2qioDdthWRrxB1kpVfW7+S/lzC47dDXwVU4g2gV8DPrLg/E7eBbwIWPJa\n98e/m3oSeBjYv+DsbcuT0QpKshv4O+ADwFur6qHBK62VJFcDdzH9Afrtqlrsu6rtzBhJasEvsCW1\nYIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVg\njCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCM\nJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwk\ntWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktfDfe+gKnnXxV4YAAAAASUVORK5CYII=\n",
       "text/plain": [
      "data": {
       "image/png": "iVBORw0KGgoAAAANSUhEUgAAASMAAAEACAYAAAD4GBC1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAACyxJREFUeJzt3W2spHdZx/Hvr552d8v2KV2FtkELGGwgkKLUB4Lb8sKm\nGB8SFXVfaGJB1FKrCUrarRVNoUDTghqr2GAjwRgxohKDDzFRUw3gAxXUhCUNqAlSoK1uS93ubrvn\n8sV9L6jJdncbz/2/zsz3k0w607S5rplz5nv+M2/uVBWSNNoZoxeQJDBGkpowRpJaMEaSWjBGklow\nRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBG\nklowRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBGklowRpJaMEaS\nWjBGklowRpJaMEaSWjBGklowRpJaMEaSWjBGC0qyO8nrklw0ehepm43RC6yDJLuBG4AbgV3AlyW5\ne8EVjlXVEwvOk05bqmr0DisvyYPAnvlhARmwxtdW1T8MmCudEj+mLWMP8H7gILAJXFdVWeIG7J9n\n3jbw+UsnZYyWcy9wMfBa4H1LDJw/Ht7E9HO+MsmLl5grPR3GaEFV9XhV3VNVn19o5JXAM+b7O4B9\nC82VTpsxWm1/DFw+378WePPAXaSnZIxWWFVtVtU/zQ8PVNVjQxeSnoIxktSCMZLUgjGS1IIxktSC\nMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS1IIx\nktSCMZLUgjGS1IIxktSCMdpCSc5I8h3zw71Jnjt0IamxjdELrLgXAe+f738bcAT4vnHrSH2t1cko\nyZ4ktyW5YqGR/wgcv4jiEeAdC82Vtp21OBkleSbwU8B1wE7g8iR3LDT+PcBbgfuq6sMLzZS2nbWI\nEXAfcPH/ePzK+bak/QvPAyDJhcAhYM+I+dKpWpePaRcD9wIfAwp4W1Vl4dtfDXrub2A6Df7MoPnS\nKVmXGAE8CLwEuAq4fewqy5hPRdcz/ZxfnOTlg1eSTmidYkRN7q2q/xi9y0K+Dtg13z8b+JaBu0hP\naV2+M1pXfwZcABwErgb+Yuw60omt1clo3cwnwUfmh49W1ZNDF5KegjGS1IIxktSCMZLUgjGS1IIx\nktSCMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS1IIxktSCMZLUgjGS\n1IIxktSCMZLUgjGS1MJKxyiTV88Pr0myd+hCkk5opWMEXAjcDWwyXVn1bWPXkXQiKx2jqnoI+C2m\nGD0OvHGp2UneneR1SXYsNfNkklyV5A+SPGfA7CT5ziS/n+TCAfM3kvxAkt8Z8TNJsjPJDUnuWXr2\ndpGqGr3DlprfePcDDwJ3LTj6VuAQcBi4raruXHD2/5KkgAPAs4GdwJ8CH1pwhcPAa4GLgN3AbwCf\nXHD+E8ANwLnz/NuBLyw4/0zgx4EdwNnALQvOBri7qj6/8MzTtvIxAkjyLuDVJ/0Pt8ZR4Czg+6vq\nvSMWSPIR4HLGnYT/EzgH2Bg0/2GmEJ05aP5jTL8DZw2a/1ngkqraHDT/lKz0x7Tjquo1VZUlb8AR\npjfhG+Y1Lhn3CvBS4Grgo/PjVy78WuwBvhf41Dz/hQvPfxbwI0xvygLOX3j+VwA3AgeBQwvPPQSc\nB3zXMr9qT19qDU5GIyR5LvCZqjo8f0x6fVW9ffBOAS4DDtSAH3ySM4DnV9WBpWfP8zeA51TV/YPm\n7wKeVVX/stC8twPXMX08/FfgedX4dDTq2LzyqupTJ/+vljUH6OMD528yfXc1av6TTN8fjpr/OLBI\niGYvYAoRTB+Tz2U6nbW0Fh/TpHVUVdcAH5jv76mqtiECYySpCWMkqQVjJKkFYySpBWMkqQVjJKkF\nYySpBWMkqQVjJKkFYySpBWMkqQVjJKkFYySpBWMkqQVjJKkFYySpBWMkqQVjJKkFYySpBWMkqQVj\nJKkFYySpBWMkqQVjtIWSnD1f1RPg+iRXD11IaswYba1nAz85378U2DduFam3tYpRkquSfDjJq5aY\nV1WfYLqi5yZwBPj5JeZqvSXZl+SDSfaO3uV0ZLr8+mpL8grgDuBrgGfM//pPFhq/G3g58J6q+sGF\nZqqJJGcBtzP97i3lmvmf/wU8AZxfVVlw/tOyLjEq4BjwJLBjwAoHga+vqvsHzNZASd4E3Dxo/BEg\nwJuq6tZBO5yydfqY9kfArwBHgZurKgveLjBE6yfJucBPMP3O3bbU7xvT1wFHgV8GLtkOIYL1Ohm9\nr6q+J8l5wKO1Dk9cQyW5helUtAM4DFxUVQcXmHsGcE5VPbLVs/4/rdPJCICqesQQaSG7+NLXAp/h\nS99Xbqmq2txuIQLYGL2AtKqqan+SR4G3VNXzRu/T3dqdjCT1ZIwktWCMJLVgjCS1YIwktWCMJLVg\njCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCM\nJLVgjCS1YIwktbDSMUqyI8l754ffneSnhy4k6YRWOkbATuDb5/sFfPNSg5NkqVkdjX7+o+fr9K10\njOZL/N7BdJ3zw8BNC47/eJLfS3LZgjNbSHIp8ECSO5PsGTD/CuCzSW5Ocs7S8/X0ZNUvO5/kfOAB\nIMDRBUefAxybZ34Q+NaqWnL+FyV5I/D6BUceD8BhYBP4a+CbBsw/xPQz+IWq+tkF539Rkv3Am6vK\nk9pJrHyMAJJcC/z6gNHF9IbcBVxfVXctvUCSlwD3LT13dpQpRh8DvmHA/MNMf4R2jIpBkl8Cfgz4\nyqp6YMQO28VKf0w7rqruqaoseQM+DfwlsHdeY8egp387UxQfYn5TLvDcvxr4AvCbwPOr6hsXfu1f\nBjwG3AW8atDrTpIvB17D9PrfMmqP7WJj9AIr7NKqOgYw6rvU+VT0CqbTwbnAtcA7t3puVX0yyQXH\nn//SqupDSc6vqmNJ9p78/9gyNwFnMr3PfjjJrZ6OTmwtTkYjjHoj/h+HgL+d7/870+loEaOf/+j5\ns39j+kMA0/eGQ74z3C48Ga2wqvoE8LIkBeyrqr8ZvdM6qapfTLILeEtVXTl6n+48GUlqwRhJasEY\nSWrBGElqwRhJasEYSWrBGElqwRhJasEYSWrBGElqwRhJasEYSWrBGElqwRhJasEYSWrBGElqwRhJ\nasEYSWrBGElqwRhJasEYSWrBGElqwRhJasEYbaEkFyf56PzwziQ3Dl1ozST5IeB35/v/nOSFg1fS\nUzBGW+sY8IL5/lFg51KDkyw2q7ENpst6A1zG9PNYhK//6TNGW6iqPsd0bfsn5ts7lpib5Dzg4SR/\nnuSlS8xs6t3AI0ABf1hVB5YYmmQfcDDJncDZS8xcBamq0TustCTPBD7NmEuJF3CE6UR2RVX9/YAd\nhkryo8CvDhi9yXQa3gA2qioDdthWRrxB1kpVfW7+S/lzC47dDXwVU4g2gV8DPrLg/E7eBbwIWPJa\n98e/m3oSeBjYv+DsbcuT0QpKshv4O+ADwFur6qHBK62VJFcDdzH9Afrtqlrsu6rtzBhJasEvsCW1\nYIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVg\njCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCM\nJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktWCMJLVgjCS1YIwk\ntWCMJLVgjCS1YIwktWCMJLVgjCS1YIwktfDfe+gKnnXxV4YAAAAASUVORK5CYII=\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea700c4e0>"
+       "<matplotlib.figure.Figure at 0x7f2cfbd8d5c0>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 40,
+   "execution_count": 33,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "['FLRFRFFFRFFFRFFR',\n",
-       " 'FFFRFRFRLR',\n",
-       " 'FFFFRFRFRLFR',\n",
-       " 'FFFLFFLFFLFF',\n",
-       " 'FFRRFLRRFR',\n",
-       " 'RLRFFRFRFFFR',\n",
-       " 'LFRFLLFFFLFFLF',\n",
-       " 'RLFFLFLFLR',\n",
-       " 'RFFFLLRFFFLLRRLLFFFF',\n",
-       " 'FLFFLFFLFLRL']"
+       "['FFFLLFFFFLLF',\n",
+       " 'LLFLFLRFLLFF',\n",
+       " 'FLRRLLFLFFLF',\n",
+       " 'FRLLFRRFLRFLRRFFFRLRFF',\n",
+       " 'LLRFLFFLFFFFLFFFFLFL',\n",
+       " 'LFRFFFRRFLRF',\n",
+       " 'LFRFFLRRFFRFLRFR',\n",
+       " 'LFFFLLFFFRFLLFFL',\n",
+       " 'RLFFLRLFLFFFLF',\n",
+       " 'RLRFFRFFFRRLRLFR']"
       ]
      },
       ]
      },
-     "execution_count": 40,
+     "execution_count": 33,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 43,
+   "execution_count": 34,
    "metadata": {},
    "outputs": [
     {
      "data": {
    "metadata": {},
    "outputs": [
     {
      "data": {
-      "image/png": "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\n",
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAUQAAAEACAYAAADLIw+8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAACPpJREFUeJzt21uI5nUdx/HPV912zRUp62KlA3RhdsIOdGUUInS0E5F1\nUwQdoKAoJMjKik5aCV50ERSR4E3Q4WYLO5mEdVFBkVQXQYIdNKGTurqaur8u/t9hp6Q8zPPMb3bm\n9YJh9nl2Lz6PM/Oe3/95HmuMEQCSk2YPANgpBBGgCSJAE0SAJogATRABmiACNEEEaIII0AQRoAki\nQBNEgCaIAE0QAZogAjRBBGiCCNAEEaAJIkATRIAmiABNEAGaIAI0QQRoggjQBBGgCSJAE0SAJogA\nTRABmiACNEEEaIII0AQRoAkiQBNEgCaIAE0QAZogAjRBBGiCCNAEEaAJIkATRIAmiABNEAGaIAI0\nQQRoggjQBBGgCSJAE0SAJogATRABmiACNEEEaIII0AQRoAkiQBNEgCaIAE0QAZogAjRBnKQWL6uq\n66rq6bP3rFpV7auqt1bV96vqjNl7Vq2qzqiqj1XVV2dvYXVOmT1gr6mqSvLSJFckeVKSfUmenuS3\nM3etSlXtS/LmJJ9O8ugkj0ry2CS3zdy1Kh339yW5OMvPz7G5i1glQdxGVXVhks9kCeHBvvuOJE+r\nqudNG7YaJyd5dpJPZAnhxuM7muTcqnrsrGErsi/LL7KLszzWU/v+Y7vga5ck/xxj/H72iNlqjDF7\nw55QVa9N8s0sJ4rd/FTFSFKzR/CIvGSM8b3ZI2bazT+YO825/fmqLKeme/v27UleP8aoE/0jyXOT\n/KAf38Zv2iNJnjJ72woe20lJXp7lqY0jm76ud83etoLH9sEk9ye5vJ/S2bMEcZuNMd6a5KlJrk5y\nd45fep3wxhi/HGO8OMl5OR7GA3NXrcZYXJPkmUkuyhLGu+au2rqqOpjkkixPA5yd5Py5i+YSxAnG\nGH/sMJ6d5LNJfjJ50kr9VxgvS3LL5Ekr819hfF2SD0+etFXvzhLDJDktyRV7+ZRYw3OI26KqPpbk\no32JAtP16fDmJKdvuvvOJK8aY/xwzqq5nBBh73p7lncEbLx16Fjf/tS0RZN52w3sXYezBDBJPpnk\n20l+muQX0xZN5pJ5m7hkZierqpHlUvnw7C0zuWQGaIII0AQRoAkiQBNEgCaIAE0QAZogAjRBBGiC\nCNAEEaAJIkATRIAmiABNEAGaIAI0QQRoggjQBBGgCSJAE0SAJogATRABmiACNEEEaIII0AQRoAki\nQBNEgCaIAE0QAZogAjRBBGiCCNAEEaAJIkATRIAmiABNEAGaIAI0QQRoggjQTpk9YLerqh8leUaS\nM/v2X/uv3jDGuHbaMOABBHH9bk/ymE23z0zyryR/mTMH+F9cMq/fJUnu2XT7WJLvjjF+M2kPD6Kq\navYG5hDENRtj/DrJtVlCmCxxvGTeIv6fqjonyV+r6sqqevzsPWwvQdweG6fEY0l+4HS4o52ZZH+S\ndya5SRj3lhpjzN6wJ1TV4SSvSPKs3RjEqjqY5ONJDs7eskXnJHl+kgN9e+MX2dVJ3jfGuGvWsHWq\nqpHkVWOMw7O3zORFle3zsyQX7sYYtm8neeHsEWuwP8ndSd6R5P4k75o7Z/Wq6lCWx3bW7C2zuWTe\nPifPHrAuVfXMLKeqO5NcMMaoE/UjyQuS3NYP7c4k/0zywb79xG3/j7s9Lt34XFV7+pAkiKzCZVlO\nUqcluWIXvEp7epYQXprkrDHGlZP3rE2fDt+S5Rf2GUneOHXQZILIlvTp8IIc/146O8n58xZt2U+T\nvCYdwjHG0dmD1uzSHL96OZjk8r18ShREtmrjdLjhhD4ljjHuG2Mc3gMh3Hw6fNSmu/f0KVEQecSq\n6jFZXjm/M8m9SUaW/zPnOVlOiuxsb0qyL8efM70jywut7522aLI9ezRm68YY/6iqF2a51Lqm735D\nljj+btowHqovJbmh/3xNki8kuS7JjdMWTSaIbMkY48dJUlW3JDk0xvjO5Ek8RGOMfyT5TpL0Mxw/\n3utfP5fMAE0QAZogAjRBBGiCCNAEEaAJIkATRIAmiABNEAGaIAI0QQRoggjQBBGgCSJAE0SAJogA\nTRABmiACNEEEaIII0AQRoAkiQBNEgCaIAE0QAZogAjRBBGiCCNAEEaAJIkATRIAmiABNEAGaIAI0\nQQRoggjQBBGgCSJAE0SAJogA7ZTZA3a7qjqY5ECSM/r24/qv/j7GODZtGA/Jpq9Xkpzet/81xrh9\n1ibWRxDX74YkT0iyr2//Mcn+JBcl+fqsUTy4qjovyfVJ7um7XpTkz0mOVtXjxhj3TRvHWrhkXr/v\nJtl8EjyQ5QfsJ3Pm8DD8KsmRLF+zDackuV4MdydBXL+PJxmbbt+T5CtjjFsm7dmyqjpUVbv+e2eM\ncSTJZUnu2nT3PUk+MGfR1tXirNk7dqpd/009W4fvqhy/7DqW5BPTBm1RVe1P8ockN1bVRXsgjJ9P\ncn//+ViSa8cYv5m4Z6veluRPVfW1qjp79pidZrd/M+8UG6fEe3OCnw6TVH88OcmX02GcO2l9Np0S\nj+YEPx22U7N8H742ya+E8T/VGOPB/xVbVlVfzPLbuWZvWYMjWV4oGmOM/bPHrFq/U+DWLI/x5Mlz\nVuG+HH9B9f4sgTyQ5JVjjG9NW7UDOCFun48k+fnsEWt0a5JXzx6xDn1KfFuSu2dvWaPvZXkBcE9z\nQuRhqaoDWU6EJ/fnvyV5f5JveF/lzldV70nyuSxfv3uTfCvJh8YYv5s6bIfwPkQertEfN0UIT0RH\ns7wn9hsRwgdwQuRhq6pDSW4VwhNPVVWSQ2OMm2dv2YkEEaB5UQWgCSJAE0SAJogATRABmiACNEEE\naIII0AQRoAkiQBNEgCaIAE0QAZogAjRBBGiCCNAEEaAJIkATRIAmiABNEAGaIAI0QQRoggjQBBGg\nCSJAE0SAJogATRABmiACNEEEaIII0AQRoAkiQBNEgCaIAE0QAZogAjRBBGiCCNAEEaAJIkATRIAm\niABNEAGaIAI0QQRoggjQBBGgCSJAE0SAJogATRABmiACNEEEaIII0AQRoAkiQBNEgCaIAE0QAZog\nAjRBBGiCCNAEEaAJIkATRIAmiABNEAGaIAI0QQRoggjQ/g3gZun80B+JZgAAAABJRU5ErkJggg==\n",
       "text/plain": [
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea6ba2c50>"
+       "<matplotlib.figure.Figure at 0x7f2cfb907630>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 44,
+   "execution_count": 35,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "1"
       ]
      },
        "1"
       ]
      },
-     "execution_count": 44,
+     "execution_count": 35,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 45,
+   "execution_count": 36,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQMAAAEACAYAAAC3RRNlAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAABydJREFUeJzt3U+o9XldwPH3x+axNEpwEBSdCO0PghCG6MI/S5HAoF0h\n1CJIIm2VtHCgbBPSQkGFESxQN6H1UC4E2wRFCv2hmCisQCnJzGxIcWaceXS+Le43Eheiz7nnnLnn\neb3gcM/Z3M/nHu593/P7bb6z1grgGedeAHh6EAOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNg\nEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOg\nEgNgEwOgEgNgEwOgEgNgEwOgEoMbY2aeOzM/eu49uFyz1jr3DjfezDyj44f1o9VPV7ert6+1/vnI\n87jHiME1mJn3Vr9yonFPVat62Vrr0yeayT3AZcL1+NXq1pEff9RVCG5X31O5ZOBa3XfuBS7BWuup\nrv5Qj2ZmfrG6f631LzPj4xzXTgxuiLXWI9Uj596Dy+UyAajEANjEAKjEANjEAKjEANjEAKjEANjE\nAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjE4EaZmefMzL/ulx+bmdefdSEu\nihhco5l53sy8fmbmSCMe7eoAlaonq38/0hzuQc5NuAYz8/zq16s3V8+qXjszjx9p3EPVO6pPrLX+\n4UgzuAc5a/EazMxXq+8/8difWGs9fOKZXDAxuAb7uLOPVq+sXlT9wFrrWJ8M4CjcM7g+/1i9uPoh\nIeAmcs/gGu0DWD9/7j3gbvhkAFRiAGxiAFRiAGxiAFRiAGxiAFRiAGxiAFRiAGxiAFRiAGxiAFRi\nAGxiAFRiAGxiAFRiAGxiAFRiAGxiAFRicJCZuTUzX9wvf2Nm3nLWheAAFx2DmXlgZt48M7eO8f3X\nWneqT1ereqz6y2PMgVO4yHMTZubF1YPVz1XfVz0wM5870ri/qF5T/fVaSwy4sS7yeLWZ+VJ1f1f/\nsY91IvK3evVa65MnmgXX7lJjsKo/q56oXle9ZK3l+HL4Ni7yMmH7ylrrjTPz7LXWY+deBp7uLvoG\nYpUQwHfm4mMAfGfEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjE\nANjEAKjEANjEAKguMAYz84P76XNm5nvPugzcIBcXg+rh/fW11TvPuQjcJJcYg49XT1aPVh871pCZ\necXMvP2bPonAjXZxJyrNzAuqf6v+p7p9xFG/UN3q6sDV91dvW5f2ZnJPubgYVM3M71S/dqJxX+vq\ncNdfXms9dKKZcO0u8TKhtdbb1lpzzEf11uo/q7fssc8/308Mh7vIGJzCWuu91QvWWr977l3gOojB\nAdwj4JKIAVCJAbCJAVCJAbCJAVCJAbCJAVCJAbCJAVCJAbCJAVCJAbCJAVCJAbCJAVCJAbCJAVCJ\nAbCJAVCJAbCJwYFm5iX76Y/MzLPPugwcQAwOMDO3+v+zHd/U1VkKcCOJwQHWWneqP66+3tXJSh85\n70Zw98TgcA929T7eXmt99tzLwN0SgwOttT7T1fv4T+feBQ4hBtfHe8mN5hcYqMQA2MQAqMQA2MQA\nqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MTgQDPz\nqv30VTPz3LMuAwcQgwPssxb/dL98Q/VLZ1wHDiIGB9hnLX6wulM9vp/DjSQGh/utaqoPr7X+49zL\nwN0SgwPtANxXCQE3mhgAlRgAmxgAlRgAmxgAlRgAmxgAlRgAmxgAlRgAmxgAlRgAmxgAlRgAmxgA\nlRgAmxgAlRgAmxgAlRgAmxgAlRgAmxgAlRgcbGbeuJ/+1My88KzLwAHE4AD7rMXf3y9fUb3pjOvA\nQcTgAPusxfdUT1aPVR841qyZeXBmPjUzrznWjG+Z976Z+ZOZefmJ5t2emT+YmR870bw/n5nfm5kH\nTjDrmTPz8My8a2aed+x5d2vWWufe4Ubbx7B/obp1opGPV5+rTvJHUz1RfaZ66QlmPVV9vfps9eMn\nmHenWtXnqx8+wbwn9tefX2t95ATzviv3nXuBm26t9cjM/Ez1jq4OYD2Wn6y+0dUv799VXz3irP+b\nd2c//rarCB173pPV16q/qR49wbw7Xb2Pf1U9csRZz6xetuf9d1cxf9rxyeCGmJmfrV5Z/fZa679O\nMO+t1f3Vu9ZaXz7BvN+svlw9tNY6dniamXdXf199aF/uHXPWfdVD1SeqP1xrPXXMeXdLDIDKDURg\nEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOg\nEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNg\nEwOgEgNgEwOgEgNgEwOgEgNgEwOgqv8F9Hl5y6i1C9AAAAAASUVORK5CYII=\n",
       "text/plain": [
    "metadata": {},
    "outputs": [
     {
      "data": {
       "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQMAAAEACAYAAAC3RRNlAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAABydJREFUeJzt3U+o9XldwPH3x+axNEpwEBSdCO0PghCG6MI/S5HAoF0h\n1CJIIm2VtHCgbBPSQkGFESxQN6H1UC4E2wRFCv2hmCisQCnJzGxIcWaceXS+Le43Eheiz7nnnLnn\neb3gcM/Z3M/nHu593/P7bb6z1grgGedeAHh6EAOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNg\nEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOg\nEgNgEwOgEgNgEwOgEgNgEwOgEoMbY2aeOzM/eu49uFyz1jr3DjfezDyj44f1o9VPV7ert6+1/vnI\n87jHiME1mJn3Vr9yonFPVat62Vrr0yeayT3AZcL1+NXq1pEff9RVCG5X31O5ZOBa3XfuBS7BWuup\nrv5Qj2ZmfrG6f631LzPj4xzXTgxuiLXWI9Uj596Dy+UyAajEANjEAKjEANjEAKjEANjEAKjEANjE\nAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjE4EaZmefMzL/ulx+bmdefdSEu\nihhco5l53sy8fmbmSCMe7eoAlaonq38/0hzuQc5NuAYz8/zq16s3V8+qXjszjx9p3EPVO6pPrLX+\n4UgzuAc5a/EazMxXq+8/8difWGs9fOKZXDAxuAb7uLOPVq+sXlT9wFrrWJ8M4CjcM7g+/1i9uPoh\nIeAmcs/gGu0DWD9/7j3gbvhkAFRiAGxiAFRiAGxiAFRiAGxiAFRiAGxiAFRiAGxiAFRiAGxiAFRi\nAGxiAFRiAGxiAFRiAGxiAFRiAGxiAFRicJCZuTUzX9wvf2Nm3nLWheAAFx2DmXlgZt48M7eO8f3X\nWneqT1ereqz6y2PMgVO4yHMTZubF1YPVz1XfVz0wM5870ri/qF5T/fVaSwy4sS7yeLWZ+VJ1f1f/\nsY91IvK3evVa65MnmgXX7lJjsKo/q56oXle9ZK3l+HL4Ni7yMmH7ylrrjTPz7LXWY+deBp7uLvoG\nYpUQwHfm4mMAfGfEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjEANjEAKjE\nANjEAKjEANjEAKguMAYz84P76XNm5nvPugzcIBcXg+rh/fW11TvPuQjcJJcYg49XT1aPVh871pCZ\necXMvP2bPonAjXZxJyrNzAuqf6v+p7p9xFG/UN3q6sDV91dvW5f2ZnJPubgYVM3M71S/dqJxX+vq\ncNdfXms9dKKZcO0u8TKhtdbb1lpzzEf11uo/q7fssc8/308Mh7vIGJzCWuu91QvWWr977l3gOojB\nAdwj4JKIAVCJAbCJAVCJAbCJAVCJAbCJAVCJAbCJAVCJAbCJAVCJAbCJAVCJAbCJAVCJAbCJAVCJ\nAbCJAVCJAbCJwYFm5iX76Y/MzLPPugwcQAwOMDO3+v+zHd/U1VkKcCOJwQHWWneqP66+3tXJSh85\n70Zw98TgcA929T7eXmt99tzLwN0SgwOttT7T1fv4T+feBQ4hBtfHe8mN5hcYqMQA2MQAqMQA2MQA\nqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MQAqMQA2MTgQDPz\nqv30VTPz3LMuAwcQgwPssxb/dL98Q/VLZ1wHDiIGB9hnLX6wulM9vp/DjSQGh/utaqoPr7X+49zL\nwN0SgwPtANxXCQE3mhgAlRgAmxgAlRgAmxgAlRgAmxgAlRgAmxgAlRgAmxgAlRgAmxgAlRgAmxgA\nlRgAmxgAlRgAmxgAlRgAmxgAlRgAmxgAlRgcbGbeuJ/+1My88KzLwAHE4AD7rMXf3y9fUb3pjOvA\nQcTgAPusxfdUT1aPVR841qyZeXBmPjUzrznWjG+Z976Z+ZOZefmJ5t2emT+YmR870bw/n5nfm5kH\nTjDrmTPz8My8a2aed+x5d2vWWufe4Ubbx7B/obp1opGPV5+rTvJHUz1RfaZ66QlmPVV9vfps9eMn\nmHenWtXnqx8+wbwn9tefX2t95ATzviv3nXuBm26t9cjM/Ez1jq4OYD2Wn6y+0dUv799VXz3irP+b\nd2c//rarCB173pPV16q/qR49wbw7Xb2Pf1U9csRZz6xetuf9d1cxf9rxyeCGmJmfrV5Z/fZa679O\nMO+t1f3Vu9ZaXz7BvN+svlw9tNY6dniamXdXf199aF/uHXPWfdVD1SeqP1xrPXXMeXdLDIDKDURg\nEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOg\nEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNgEwOgEgNg\nEwOgEgNgEwOgEgNgEwOgEgNgEwOgqv8F9Hl5y6i1C9AAAAAASUVORK5CYII=\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea7040b70>"
+       "<matplotlib.figure.Figure at 0x7f2cfb4bba58>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 48,
+   "execution_count": 37,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "(212,\n",
-       " 94,\n",
-       " 'FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFFFLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL')"
+       "(260, 64, 'RLFFFLRRFFLFFFFLLRRFLLRRLFRFLFLFFFFFRFFFFFLFRLLFFFRFLFFRFFLLRFFF')"
       ]
      },
       ]
      },
-     "execution_count": 48,
+     "execution_count": 37,
      "metadata": {},
      "output_type": "execute_result"
     },
     {
      "data": {
      "metadata": {},
      "output_type": "execute_result"
     },
     {
      "data": {
-      "image/png": "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\ngg==\n",
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAPkAAAD7CAYAAACohzKbAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAC2BJREFUeJzt3WmIZWeZwPH/Y3eTTkx3p9sliUnaGJcEghrTKjozMhEV\njAtxiRI/uOAaWwS3DPhBxBlFZsg4DEwMOgOKCiIxgoJKVEQiRtwNgkaNC4lrtE2i3TGmk37mwz1l\nGrG6zjl1677nPvX/QXFu4L7cp6r6X+dWOG+dyEwk1XWf1gNI2lhGLhVn5FJxRi4VZ+RScUYuFWfk\nUnFGLhVn5FJxRi4VZ+RScUYuFWfkUnFGLhVn5FJxRi4VZ+RScUa+BCJiX0Tsaj2HlpORT1xEfAb4\nJnBbROSAj+e0nl3TEP6Nt2mLiAR+BXwf+FyPJTuAtwFkZmzgaFoSRj5xXeSXZeblPZ+/FTgMRq4Z\n364Xk5l3dw8/23QQTYaRS8UZuVSckUvFGblUnJFLxRm5VJyRS8UZuVSckU9YRDyme/jOEcu3RcQJ\nA1/vxIjYPeK1NGFGPm03AQn814i1TwUODdnUAvwJ+MPAjTBvnucnrPnb2noArS4zD0REALcOXPrP\nwFXAA4Freq65A3gIcN6ANU8BLo+I/8vM2wfOqAUx8uVwZMiTM/Na4OQNmuWvurM/wJ0b/Voaz7fr\nWo/rADLzL60H0eqMXCrOyKXijFwqzsil4oxcKs7IpeKMXCrOyKXijHzCIuLs7uEbmw6ipWbk03ao\nO/a9lnzRDrYeQGsz8gnLzF90D29oOsjq9gJExPGtB9HqjHw5DNqgskDndMdtTafQMRm51mNlg8of\nWw+i1Rm5VJyRS8UZuVSckUvFGblUnJFLxRm5VJyRS8UZ+YRFxOndw5c0HURLzcin7cTueHPTKVZ3\nV+sBtDYjn7DMXNmY8sWmgxzbwYjwJh0TZuTLIVoPsIoLmL3b2NV4Dh2DkWs9VjaoHGg9iFZn5FJx\nRi4VZ+RScUYuFWfkUnFGLhVn5FJxRi4VZ+QTFhG7u4fPaDqIlprXHI8UEZcAHwSuBm7suewgcBnw\nLeDrPZ5/anfcMXS+BZnq34PXUSIzW8+wdCJiBzDmb40fAu47Yt15mXn9iHUbKiKuBh4P7E3/IU2W\nkY/QvY3+A/AE4BuZ2euMFhEB7AOuz8zDGzjiQkTEyj+ekzPzlqbDaFVGPsJK5Jk51d1hCxER3wYe\ns9m/DlPn/3jTevy59QBam5FLxRm5VJyRS8UZuVSckUvFGblUnJFLxRn5OA8HiIgzWg8ircXIx3l+\nd7y46RRSD0Y+znu74/82naK9nwI/aj2Ejs1r10fw2vUZN6gsB8/kWo+bAQx82oxc6zHVu63qKEYu\nFWfkUnFGLhVn5FJxRi4VZ+RScUYuFWfk45wMEBF7Wg8ircXIx3lNd3x50ymkHox8nCuZ3SLog43n\naO3HwA9bD6Fjc4PKCG5QmXGDynLwTK71uAPcoDJ1Rq71+G7rAbQ2I5eKM3KpOCOXijNyqTgjl4oz\ncqk4I5eKM/Jx7gsQEdtbDyKtZdKRR8TZEXHBwDWnRcSzIqL3JacRsTsinh8RW3oueXN3fN2Q2aqK\niKcMfP4pEXHRwO/Rroi4OCK2DlizPSJeEBEnDFizNSKeGxH3G7AmIuLpEbG375pF6v0FW7SIeDXw\nvu7xkKX3AFsGrjvEvWfnvmsOAx8fMlhB1wH/AHxh4PfoMLANBn29DwInDlxzJ7B94Jq/WsCaSzPz\nfYNfZKDJblCJiB8A5wDXAP85YOlpwKXA25ntFOtjN/CG7nX+2HPNjZn5swFzldOdVV8LXAT8+4Cl\npwL7gX9lFnwfJzH7Hv03cGvPNcd3az4K/Lznmq3dbF8GvtNzzRbgxcBNwBd7PH8XcBXAIjY5TT7y\nzb7TS/V0v6YcgcVEPunfyaWK8t4z69cW8XpGLhVn5FJxRi4VZ+RScUYuFWfkUnFGLhU35cjd/CHN\nwSQj764IOrN7fFLPNbsi4uyNnEtaRpOMvLsi6NPdf94aEbnWB3AbcENEfKDd5FJvB4BfLuKFpnzt\n+jbgLcDOnksuBvYAe7zeXVPW3SjzAGzyDSpjRMQVwH4j15R1u/cOgxtUpJIy8+7uoRtUJK2fkUvF\nGblUnJFLxRm5VJyRS8UZuVSckUvFVYt8P0BEnNV6EG0OEfGAIXeC6dbs2ah5/p5qkX+kO97SdAot\nrYj4UJ8NUUdtjLoFuHngmgPdy/16EZ/TZG+TNNLtAJl5sPUgWj4R8U/M7oTyW2Z3Q1nLduCRwDeB\nX9D/pPk44Frg1SPGHKxa5G5M0Xrc3h0/mZmvaTrJHFV7uy6Nlpnf6x5e1XSQOTNyqTgjl4ozcqk4\nI5eKM3KpOCOXijNyqTgjl4qrFvnKBpUHtR5EmopqkX+hO97VdAotu1KXe1eL/PsAmfn71oNo+UTE\nI7uH+5oOMmfVIi/1E1gLt3JLrvObTjFn1SKXRsvMr3QPr2w6yJwZuVSckUvFGblUnJFLxRm5VJyR\nS8UZuVSckUvFVYv8ZQARcVLjOaTJqHYZ6M+Ac5ldnnhb41nUWES8Cnh2z6c/iGLXrK+oFvk1wLmZ\n2efuFyosIp4EvH/E0h8BX53zOE1Ve7u+vfUAmoyVs/KbMjP6fABnAudk5qF2Y89fZGbrGeYmIq4A\n9nffMG1i3Z1GjwBbMvNI63laqnYml/Q3jFwqzsil4oxcKs7IpeKMXCrOyKXijFwqrlrkzwSICK98\nkzrVrl0/oTvuZXYN8tKLiDOBiwYseSfwHuDfMvPujZhpydwUEZ8Cftjz+Tdk5jUbOdCiVbus9d3A\nZZlZ4odXRJwA/AbYMWL55Zl52ZxHWhrdZa0/Z/YDf6jnZOYn5ztRO9Xeru8EtrQeYo4ezSzwuwZs\nsnhst/bcdmO3l7Oz11nAk4FtPb92z+uW/0uzwTdAiTNeVZn51dkJiXcNWPOtbs2ml5n3AF8asGTl\n7P3u+U/TTrUzeVV3tB5gMzhqt9qdTQeZMyOXijNyqTgjl4ozcqk4I5eKM3KpOCOXiqsW+RMAIqLS\nVW+DxL1Xwvxj00E0GdWueHt0d3x2RPykx/PPAy4ArgT+0vM1zgReBPwP8Keea/YArwfeC/yu55rj\ngLf2fO7RTuuOO0esnayIOAPoe/ur04GXMvse3d5zzU7gTSNGm7xqG1SeB1y9oJdLYOj1o3dw7065\nvu4GHp+Z3+m7ICJuAj6TmZcOfK1J6u6Gcu2IpYeBbQPX/Bk4OzNvHvF6k1Tq7XpmfqLvRo5uQ8Jp\nwEuA4was2Q28AtgxYM3x3Zq9A9Zs7WY7a0jgnTMYt/tqqt7RHS/p+bXbCbwSuN+Ar/dxwMuBB1cK\nHIqdyTUTEQl8NjOf0XqWeYiIFwIfY/bD+K7W8yybUmdylfU7AAMfx8il4oxcKs7IpeKMXCrOyKXi\njFwqzsil4oy8rnNaD6BpMPJiuo0cAA9pOsgGiIg3RsTxredYNl7WWlBE3Ah8PjNf23qWeYiIhzG7\n7dXQDUEJnJKZt8x/quXhmbymhwIPbj3EvGTmjcCjgCuYfW4P7PHxH8x+KOxvMPKkeCYvqNoGlTEi\n4lTgV8DpmfnL1vO05JlcVf2mO/666RQTYORScUYuFWfkUnFGLhVn5FJxRi4VZ+RScUZe1/1bD6Bp\nMPJijtqg8rgBa86PiEcMfJ2HR8S+gWtOiYgLjrqVU581OyPiwojo/W81Io4Dnjlktsq8rLWYLqAf\nM7vGW7AlM4+0HqKlavdC2/QyMyPifODCActeD1wHXM/stkx9XMLsPmOfA+7pueZpwKnAh5ntEOtj\nH/BEZvc16+ss4IXAGzZ74OCZXCrP38ml4oxcKs7IpeKMXCrOyKXijFwqzsil4oxcKs7IpeKMXCrO\nyKXijFwqzsil4oxcKs7IpeKMXCrOyKXijFwqzsil4oxcKs7IpeKMXCrOyKXijFwqzsil4oxcKs7I\npeKMXCrOyKXijFwqzsil4oxcKu7/AaoxcQ7Qyo17AAAAAElFTkSuQmCC\n",
       "text/plain": [
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea7095780>"
+       "<matplotlib.figure.Figure at 0x7f2cfb49e908>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 66,
+   "execution_count": 38,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "['LFLLFFFFLLLFFRFRFF',\n",
-       " 'LFFLLFFL',\n",
-       " 'FRFFRRFFFFFFLLRLRLRLLFFF',\n",
-       " 'RFFRRRFLFFFFLFLFRLLF',\n",
-       " 'LFFRFRFFFFFRFFRLRFRF',\n",
-       " 'LFFRFRFRFL',\n",
-       " 'FLFFLLFFRLLL',\n",
-       " 'FLLFFLLF',\n",
-       " 'FFLLRLRLLFLR',\n",
-       " 'FRRLLFLFFFFLFFFLLFFRRFLL',\n",
-       " 'FRFRRFFF',\n",
-       " 'FFFRFRRFFFFFFLFLFFFLRR',\n",
-       " 'FFRRRFFLRLFRLFLFLFRFLF',\n",
-       " 'RFFRRFFR',\n",
-       " 'LFFFFRRRFLFFFL',\n",
-       " 'FFLLLRRLLL',\n",
-       " 'FFRFFRFRFRLL',\n",
-       " 'RFLFFFFRRFFFFFRFFLLLLR',\n",
-       " 'RRLLRRFFRFRFLR',\n",
-       " 'FFRFRFFRFR']"
+       "['FRFRFFRFRF',\n",
+       " 'LLRFLLRLFFLFLR',\n",
+       " 'FFRFRFFFFFRFFRFFFR',\n",
+       " 'LLRLLLRL',\n",
+       " 'RLLLRFFFLFLLRFFL',\n",
+       " 'LLFFFLLFFF',\n",
+       " 'FLLRLFRFLFLFFFLLRFFR',\n",
+       " 'LLRFLRLFLLFRFFLF',\n",
+       " 'FFRFFFRFRFFF',\n",
+       " 'LRRLRFRFFFFRFRLRRL',\n",
+       " 'RFFRFFFRFFFFFRFRLFRF',\n",
+       " 'LFLLRLLF',\n",
+       " 'RFFRRFFRFFFLFFRRRFLRFL',\n",
+       " 'FFFRLLFFFLFLRFFFLFFFLFLF',\n",
+       " 'FFRFRRFFRLFFLLFRFFRRRFLR',\n",
+       " 'RRFRFFFRFFRFRL',\n",
+       " 'LFRFLLFFFFLLFRFL',\n",
+       " 'FLFRRRRLLF',\n",
+       " 'FRFFRRFFLLLL',\n",
+       " 'RFRRFFRLFRRFFR']"
       ]
      },
       ]
      },
-     "execution_count": 66,
+     "execution_count": 38,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 67,
+   "execution_count": 39,
    "metadata": {},
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "317"
-      ]
-     },
-     "execution_count": 67,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
+   "outputs": [],
    "source": [
    "source": [
-    "open('mistakes.txt', 'w').write('\\n'.join(mistakes))"
+    "open('mistakes.txt', 'w').write('\\n'.join(mistakes))"
    ]
   },
   {
    "cell_type": "code",
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 69,
+   "execution_count": 40,
    "metadata": {},
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "137"
-      ]
-     },
-     "execution_count": 69,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
+   "outputs": [],
    "source": [
    "source": [
-    "open('samples.txt', 'w').write('\\n'.join(samples))"
+    "open('samples.txt', 'w').write('\\n'.join(samples))"
    ]
   },
   {
    "cell_type": "code",
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 71,
+   "execution_count": 41,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "('FFRRFLRRFR', 10)"
+       "('LLRFLFFLFFFFLFFFFLFL', 20)"
       ]
      },
       ]
      },
-     "execution_count": 71,
+     "execution_count": 41,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 83,
+   "execution_count": 42,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "('RRLLRRFFRFRFLR', 14)"
+       "('FRFFRRFFLLLL', 12)"
       ]
      },
       ]
      },
-     "execution_count": 83,
+     "execution_count": 42,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 74,
+   "execution_count": 43,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "'RRFFLLFFFFLF'"
+       "'RLLFRFFFFFFFRFLF'"
       ]
      },
       ]
      },
-     "execution_count": 74,
+     "execution_count": 43,
      "metadata": {},
      "output_type": "execute_result"
     },
     {
      "data": {
      "metadata": {},
      "output_type": "execute_result"
     },
     {
      "data": {
-      "image/png": "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\n",
+      "image/png": "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\nrkJggg==\n",
       "text/plain": [
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea6e5cac8>"
+       "<matplotlib.figure.Figure at 0x7f2cfbc02a20>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 76,
+   "execution_count": 44,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 80,
+   "execution_count": 45,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "'FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFF'"
       ]
      },
        "'FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFF'"
       ]
      },
-     "execution_count": 80,
+     "execution_count": 45,
      "metadata": {},
      "output_type": "execute_result"
     },
      "metadata": {},
      "output_type": "execute_result"
     },
      "data": {
       "image/png": "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\nAElFTkSuQmCC\n",
       "text/plain": [
      "data": {
       "image/png": "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\nAElFTkSuQmCC\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea6fc12e8>"
+       "<matplotlib.figure.Figure at 0x7f2cfbae7ef0>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 81,
+   "execution_count": 46,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "'FLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL'"
       ]
      },
        "'FLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL'"
       ]
      },
-     "execution_count": 81,
+     "execution_count": 46,
      "metadata": {},
      "output_type": "execute_result"
     },
      "metadata": {},
      "output_type": "execute_result"
     },
      "data": {
       "image/png": "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\n",
       "text/plain": [
      "data": {
       "image/png": "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\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea6c4e550>"
+       "<matplotlib.figure.Figure at 0x7f2cfbb6f978>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 84,
+   "execution_count": 47,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " 'FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFFFLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL')"
       ]
      },
        " 'FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFFFLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL')"
       ]
      },
-     "execution_count": 84,
+     "execution_count": 47,
      "metadata": {},
      "output_type": "execute_result"
     },
      "metadata": {},
      "output_type": "execute_result"
     },
      "data": {
       "image/png": "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\ngg==\n",
       "text/plain": [
      "data": {
       "image/png": "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\ngg==\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7fdea6e6ca20>"
+       "<matplotlib.figure.Figure at 0x7f2cfbb69be0>"
       ]
      },
      "metadata": {},
       ]
      },
      "metadata": {},
index ceb641fbc83c48136aee813d611d91993c902f3b..c4949e8a5dcd3027e8325586021931d37ba7775a 100644 (file)
@@ -4,9 +4,77 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "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?"
+    "You've arrived at your destination and are looking forward to seeing the site. But it's a large site and you'll need a guide.\n",
+    "\n",
+    "Each guide posts the route they'll take on a board, described the by steps they'll take. The steps are either `F` (take a step forward), `L` (turn left 90⁰ then take a step forward) or `R` (turn right 90⁰ then take a step forward). For example, the route `FFRRFLRRFR` will look like this (assuming you start facing right; the blob shows the starting point):\n",
+    "\n",
+    "\n",
+    "![Sample valid tour](question-example-tour-000-s0010-m000-trim.png)\n",
+    "\n",
+    "A sample valid tour\n",
+    "\n",
+    "while the tour `FFLLRLRLLFLR` looks like this (again, assuming you start facing right):\n",
+    "\n",
+    "![Sample valid tour](question-example-tour-001-s0012-m000-trim.png) \n",
+    "\n",
+    "A sample valid tour\n",
+    "\n",
+    "However, some of the tour guides are charlatans. They have tour that either doesn't return you to your starting place, or loops around to visit the same place more than once. For example, the tour `RRFFLLFFFFLF` doesn't return to your starting place:\n",
+    "\n",
+    "![Sample invalid tour](question-example-tour-002-s0012-m001-trim.png)\n",
+    "\n",
+    "An invalid tour\n",
+    "\n",
+    "and the tour `RRLLRRFFRFRFLR` may get you back to where you started, but only after going around a small loop:\n",
+    "\n",
+    "![Sample invalid tour](question-example-tour-003-s0014-m001-trim.png)\n",
+    "\n",
+    "A sample invalid tour\n",
+    "\n",
+    "You're only interested in valid tours, the ones that return you to your starting place and don't visit any other spot more than once. (It doesn't matter what direction you're facing when you return to your starting place, just that you return there at the end of the tour.)\n",
+    "\n",
+    "In fact, you've got your daily fitness tracker widget to keep happy. Even on holiday, you need to keep up the number of steps you take. You're interested in the total length of all the valid tours. In the examples here, the total length of the two valid tours is 10 + 12 = 22 steps.\n",
+    "\n",
+    "# Part 1\n",
+    "\n",
+    "The tours are given in [06-tours.txt](06-tours.txt), one tour per line. \n",
+    "\n",
+    "What is the total length of all the valid tours?\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "It seems you've done your guides a disservice.\n",
+    "\n",
+    "Yes, there are some charlatans around. But some of the tours a split between two guides. Each posted tour alone looks like it would be incomplete, but when you finish the first leg of a tour, you pick up a new guide and continue, eventually returning you to your starting place.\n",
+    "\n",
+    "For instance, the tours `FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFF` and `FLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL` are both incomplete; on its own, each tour would leave you stranded. \n",
+    "\n",
+    "![A split tour](question-example-tour-004-s0051-m001-trim.png)\n",
+    "\n",
+    "A split tour \n",
+    "\n",
+    "![More of a split tour](question-example-tour-005-s0043-m001-trim.png)\n",
+    "\n",
+    "More of a split tour\n",
+    "\n",
+    "But if you do one then the other, the complete 94-step tour is valid:\n",
+    "\n",
+    "![Split tour combined](question-example-tour-006-s0094-m000-trim.png)\n",
+    "\n",
+    "The split tour combined\n",
+    "\n",
+    "(You start the second half of the tour heading left, so turn the second picture 180⁰ to visualise it.)\n",
+    "\n",
+    "Luckily for you, tour guides only act alone or in pairs, and never in teams of three or more. \n",
+    "\n",
+    "(Because of way the initial facing changes the way a tour unfolds, it's generally the case that tour A followed by tour B is different from B followed by A.)\n",
+    "\n",
+    "# Part 2\n",
+    "\n",
+    "The tours are still given in [06-tours.txt](06-tours.txt), one tour per line. Your definition of a valid tour now includes the combination of two partial tours, so long as the combined tour never crosses itself and returns you to your staring place. With this new definition of valid tours, what is the total length of all the valid tours?"
    ]
   },
   {
    ]
   },
   {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": 39,
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
-    "def plot_trace(trace, colour='k', xybounds=None, fig=None, subplot_details=None, filename=None):\n",
+    "def plot_trace(trace, colour='k', highlight_start=True,\n",
+    "               xybounds=None, fig=None, subplot_details=None, filename=None):\n",
     "    plt.axis('on')\n",
     "    plt.axes().set_aspect('equal')\n",
     "    plt.axis('on')\n",
     "    plt.axes().set_aspect('equal')\n",
+    "    \n",
+    "    if highlight_start:\n",
+    "        plt.axes().add_patch(plt.Circle((trace[0].x, trace[0].y), 0.2, color=colour))\n",
+    "\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=colour, ec=colour, length_includes_head=True)\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=colour, ec=colour, length_includes_head=True)\n",
     "        plt.savefig(filename)"
    ]
   },
     "        plt.savefig(filename)"
    ]
   },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\nnO0IPfrWAAAAAElFTkSuQmCC\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f365877fd30>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot_trace(trace_tour(sample_tours[0]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f36586f87b8>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot_trace(trace_tour(sample_tours[1]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAASMAAAEACAYAAAD4GBC1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAF09JREFUeJzt3Xt0lfWd7/H3d+eyE66pKKBSSq2OOKNUqYuCTns27XQE\nFZiWqR1mTk+9VFyWHkRQlF4MtHAEl4wtpfUPxrKWPSLL6upoVQJ20Q0yFktRCgVRVASngBqWQkIu\nhOR7/sgmK3qAJO4nz/Mj+/NaKyt7J7/8Pr/cPvnt/TzwmLsjIpK0VNILEBEBlZGIBEJlJCJBUBmJ\nSBBURiISBJWRiAShOIpJzOwt4BDQAjS5+6go5hWRwhFJGdFaQhl3fz+i+USkwET1MM0inEtEClBU\nBeLAajPbZGY3RzSniBSQqB6mXeHuB8zsLOA5M3vF3TdENLeIFIBIysjdD+Rev2dmvwFGAR8qIzPT\nP4ITKVDubh2Nyfthmpn1MrM+udu9gX8E/nKSBSX2UllZqfwCzFZ+8vmdFcXOaBDwm9zOpxh4xN3X\nRDCviBSQvMvI3XcDl0awFhEpYAVzOD6TySi/ALOVn3x+Z1lXHtPlFWTmcWWJSDjMDI/jCWwRkSio\njEQkCCojEQmCykhEgqAyEpEgqIxEJAgqIxEJgspIRIKgMhKRIKiMRCQIKiMRCYLKSESCoDISkSCo\njEQkCCojEQmCykhEgqAyEpEgqIxEJAgqIxEJgspIRIKgMhKRIERWRmaWMrOXzOypqOYUkcIR5c7o\nNmBHhPOJSAGJpIzMbAhwNfAfUczXU9XW1rJ06VL279+f9FJEgpP35a1zHgDuBPpHNF+PUlNTw5Il\nS1i0aBH19fW0tLQwderU2PKLioooKSmJLU/k48j7irJmdg0w3t2/a2YZYJa7TzjBOK+srGy7n8lk\nTpvL7ubrrLPOorq6Gmi7umbsa9i8eTMjR46MPVcKTzabJZvNtt2fN29ep64oi7vn9QL8H2Av8Caw\nH6gFHj7BOC9UgE+cONErKiq8qKjIf/GLX8SWvWDBAk+lUj5u3LjYMkXay/3ud9glee+M2jOz/0Hr\nzmjiCd7nUWadTsyMxYsXc+utt7JixQomTJjAwIEDuz23traWc845h5qaGsrLy9m4cSMjRozo9lyR\n9nKPBjrcGek8oxiVl5dz0003xVJEAOvWrePIkSMANDY2smLFilhyRT6OqJ7ABsDd1wHropxTPr7x\n48ezZcsWRowYwS9/+UsmT56c9JJETko7ox4slUpxySWXADB8+HD69OmT8IpETk5lJCJBUBmJSBBU\nRiISBJWRiARBZSQiQVAZiUgQVEYiEgSVkYgEQWUkIkFQGYlIEFRGIhIElZGIBEFlJCJBUBmJSBBU\nRiISBJWRiARBZSQiQVAZiUgQVEYiEgSVkYgEQWUkIkFQGYlIEPIuIzNLm9mLZvaymW0zs8ooFtYT\ntLS08NRTTwGwfv163nzzzYRXJBKuvC/i6O6NZjbW3evMrAj4LzNb5e5/jGB9p7Vt27YxadIkAJ5+\n+mlKS0t57LHHEl6VSJgieZjm7nW5m2laC86jmDdq1dXVzJkzhz/+MZ6eHDFiBBdffDEA6XSamTNn\nxpIrcjqK5PLWZpYCNgOfAX7u7puimDcqBw4c4P777+fBBx+koaGBLVu2cOedd8aS/c1vfpO7776b\nkSNHMnr06FgyRU5HkZSRu7cAl5lZP+A/zexv3X3HR8fNnTu37XYmkyGTyUQR36GRI0eyf//+tvtV\nVVVUVVXFkn3cggULYs077uDBg5SXl/Pee+8lki+FJ5vNks1mu/xx5h7tIyozuweodfd//8jbPeqs\nLqyJL3zhCxw+fJitW7dy5513smjRokTWErfZs2ezePFiRo0axR/+8IeklyMFyMxwd+toXBRH0840\ns/652+XAPwA78503agMHDuTll18mm81y1113Jb2cWBw8eJCf//zntLS0sHXrVjZs2JD0kkROKoon\nsM8Gfm9mW4AXgdXu/mwE80bOzPjiF7/IGWeckfRSYrF582bq6+sBqKurY82aNQmvSOTkoji0vw0Y\nGcFaJGJf+cpXeP/996moqGDNmjWMHTs26SWJnJTOwO7BzIz+/fsD0K9fP4qLIzleIdItVEYiEgSV\nkYgEQWUkIkFQGYlIEFRGIhIElZGIBEFlJCJBUBmJSBBURiISBJWRiARBZSQiQVAZiUgQVEYiEgSV\nkYgEQWUkIkFQGYlIEFRGIhIElZGIBEFlJCJBUBmJSBBURiISBJWRiAQhiivKDjGztWa2w8y2mdn0\nKBYWBXfnoYceAqCqqor169cnvCIRORlz9/wmMBsMDHb3LWbWB9gMTHL3nR8Z5/lmdVV1dTWDBg1q\nu1+o15s3MzZu3MjnP//5pJciBcjMcHfraFzeOyN3P+DuW3K3a4FXgHPznTcKZ555JlOmTCGVSlFe\nXs68efNiy/7Wt77F0qVLaWxsjC2zI9lslkmTJrF79+7Ys92dJ598kq9+9ascPHgw9vxjx47x8MMP\n8/Wvfz2R70lDQwM//elPufHGG2PPPl3kvTP60GRmw4AscHGumNq/L/adEcDu3bs5//zzOeuss5g2\nbRpmHRZ0JH74wx/Sq1cvysrKmDNnDnfccUcsuSdiZgwfPpy9e/fS2NjIVVddxZgxY2LLT6fTLFu2\njP3791NbW8v111/PZz7zmdjyi4qKWLp0KYcOHeLIkSPMnj2bvn37xpZ/9OjRtj9MdXV1/PjHP44t\nG2Dq1KkMHDgw1sz2OrsziqyMcg/RssCP3f3JE7zfKysr2+5nMhkymUwk2R258cYbWb58eSxZH1Va\nWsrRo0dZuXIl3/jGNxJZw2WXXcaf//xnkvhjAPCJT3yCmpoajh07lkj+GWecQU1NDU1NTYnk9+7d\nm6amJo4ePZpI/qBBg9i3bx+pVDzHq7LZLNlstu3+vHnzOlVGuHveL0AxUAXcdooxXkjS6bRXVFT4\nAw884IAvXrw4sbW0tLT47373O//sZz/rgK9atSrW/ObmZn/iiSf8vPPOc8C3b98ea35TU5M/9NBD\nPnjwYDcz/+CDD2LNr6ur88WLF3tFRYX36tUrttx3333Xy8vLvby83B977LHYcj8q97vfcY90ZlCH\nk8DDwL93MKa7P+egvPHGG15fX+/unngZHdfS0uI7duzwlpaWRPKbm5v9lVdeSSTbvbWUXnvttcTy\n6+rq/M0334wt7/bbb/fS0lIHfNiwYd7c3BxbdnudLaMoDu1fCfwb8CUze9nMXjKzcfnOe7o777zz\nKCsrS3oZH2JmXHTRRbE9b/ZRqVSK4cOHJ5INUFxczAUXXJBYfnl5OZ/+9Kdjy9u+fXvbQ8OamhoO\nHz4cW/bHUZzvBO7+X0BRBGsRkQitXr2aa6+9lmeeeYbq6uqkl9MhnYEtIkFQGYlIEFRGIhIElZGI\nBEFlJCJBUBmJSBBURiISBJWRiARBZSQiQVAZiUgQVEYiEgSVkYgEQWUkIkFQGYlIEFRGIhIElZGI\nBEFlJCJBUBmJSBBURiISBJWRiARBZSQiQVAZiUgQVEYiEoRIysjMHjKzd8xsaxTz9RR1dXXMnDkT\ngKVLl7J69eqEVyQSrqh2RsuBqyKaq8d4++23+clPfgLAW2+9xcqVKxNekUi4Iikjd98AvB/FXN0p\nm80yevRofv3rX8eSd+GFF3L11VdjZqTTaSorK2PJlcK2YsUKrrjiCtavX5/0Urok78tbnw7Wrl3L\nHXfcwauvvkpdXR3XXXcd48aNiyW7pqYGd2fy5MkMGzYslkwJR2NjI7Nnz+a1116LLbOqqgqA8ePH\nU1paGltuvmIto7lz57bdzmQyZDKZWHK//OUvk0qlKCkpaXvb8W9YHCoqKrjnnntiy5NwzJs3jyVL\nliSS3dzczJEjR2LfkWezWbLZbNc/0N0jeQE+BWw9xfs9KYBfe+21PmPGDC8tLfX58+cnthYpHIcO\nHfI+ffp4SUmJf+9734stt7Ky0ktLS33WrFn+3nvvxZZ7Mrnf/Q47xFrH5s/MhgG/dfdLTvJ+jyqr\nq8yMyZMn8/jjj3Po0CH69euHmSWyFikcP/rRj1iwYAFHjx6lrKyM/fv3U1FR0e25LS0t1NTU0L9/\n/27P6gwzw907/IWL6tD+CuAF4G/MbK+Z3RDFvN2hf//+KiKJRX19PUePHgXgnHPO4ciRI7HkplKp\nYIqoKyJ5zsjd/zWKeUR6knvvvZf+/fszZ84c3njjjaSXEzydgS0iQVAZiUgQVEYiEgSVkYgEQWUk\nIkFQGYlIEFRGIhIElZGIBEFlJCJBUBmJSBBURiISBJWRiARBZSQiQVAZiUgQVEYiEgSVkYgEQWUk\nIkFQGYlIEFRGIhIElZGIBEFl1ENVV1ezaNEiLrnkEoYMGcKFF17I9OnT9R/DS7AK4vLWhcTdmTt3\nLvfddx9mRn19fdv7du/ezbJlyxg/fjyPPPII5eXlCa5U5MO0M+phpk+fzv33309DQ8OHigigqamJ\nhoYGVq1axdixY9uu6SUSgqgu4jjOzHaa2WtmdlcUc0ahsbGR6667DoAnnniC++67L+EVda+qqiqW\nL19OXV3dKcc1NDSwdetW5s+fH9PKRDqWdxmZWQpYClwF/B0wxcyG5ztvFBoaGnj66aeB1kvsPv/8\n87FlJ3Ep74ULF3b6qqX19fX87Gc/o6mpqVvWktSlzEPJl66LYmc0Ctjl7nvcvQlYCUyKYN689e/f\nn1mzZlFWVkZZWRkLFy6MLfuiiy7ia1/7Gjt37owl769//Ssvvvhilz6mubmZZ599NvK1vPXWW5x9\n9tnMmjWL6urqyOfvyKZNmxg8eDDz58+npqYm9nz5eCzfvyBmNhm4yt2n5u7/T2CUu0//yDhP4q/V\nBx98wODBgwEoLS2NLbempoZUKkU6nWbMmDGsWrWqW/Off/55JkyYwKFDh7r0cel0OvJ1HS+AdDpN\nKpXiyiuv7HJRRpFfXl5OUVERt912W2IPSRcsWMAPfvCDgt6pmRnubh2Ni+Jo2olCTviVnzt3btvt\nTCZDJpOJIP7UKioqWLp0KTfffDONjY3dntfe8R/AtWvXsmzZMqZNm9btWV3V2NjYbV+XlpYWAA4f\nPpzIDqWlpYXm5mYWLFiQWBkdOHCAVCrF/v37OfvssxNZQ9yy2SzZbLbrH+jueb0Ao4GqdvfvBu46\nwTgvJEOGDPFMJuObNm1ywBcvXtyteXv27PGysjKn9Q9Bp1769u3rjz/+eORref31171v375+ww03\n+N69eyOfvyMvvPCC9+nTx2fOnOlPPvmkJ/Wz9+6773p5ebmXlJT4rbfemsgaQpD7+nfcJZ0ZdMoJ\noAh4HfgUUApsAS46wbg4Pu9gHDt2rO12HGXk7j569Ogul1FDQ0O3rKX955+E4/nr1q1LrIxuv/12\nLy4udsCLi4t93759iawjaZ0to7yfwHb3ZuC7wBpgO7DS3V/Jd97TXVFRUeyZd999N7179+7U2LKy\nMm655RbS6XS3rCWJzz+kfIChQ4e2PXweM2ZMrM9Zno4iOc/I3avc/UJ3v8Dd4ztkJR8yceJEJk+e\nTK9evU45Lp1Oc8EFFzBv3ryYVlaYZsyY0fZc1fr16xkwYEDCKwqbzsDuQcyM5cuXc9NNN5FOp/+/\nXU9RURG9evXiiiuuYMOGDR2WlkicVEY9TCqVYsmSJezatYsZM2YwdOhQAAYMGMCUKVPYsGEDa9eu\npV+/fgmvVOTDVEY91Cc/+UkWLlzInj17AHjmmWf41a9+xWWXXZbwykROTGUkIkFQGYlIEFRGIhIE\nlZGIBEFlJCJBUBmJSBBURiISBJWRiARBZSQiQVAZiUgQVEYiEgSVkYgEQWUkIkFQGYlIEFRGIhIE\nlZGIBEFlJCJBUBmJSBBURiISBJWRiAQhrzIys382s7+YWbOZjYxqUT3Fvn37uPTSSwGYNWsW9957\nb8IrKizLly9n8uTJAFx88cVs37494RXJqeS7M9oGfBVYF8FaepyioiJ27NgBQGlpKQ0NDbFlx5kV\nqqamJmpqagDYuXNnrFeZ1de/6/IqI3d/1d13ARbRenqUQYMGccstt1BSUkJJSQkzZ86MJffQoUMM\nGDCAsWPH8qc//SmWzBBdf/319OvXDzNjwoQJDB8+PJbcRx99lIqKCmbNmsWRI0diyewJ7Pi1wPOa\nxOz3wCx3f+kUYzyKrNPNO++8w7nnnktzc3Ps2WZGOp2moaGBTZs2cfnll8e+hqQ9+OCDfOc734k9\nN5VKUVJSQnNzM8eOHaMQf/aPMzPcvcMNS3EnJnoOGNT+TYAD33f333ZlUXPnzm27nclkyGQyXfnw\n09KgQYN49NFHY72ufW1tLXv27KG0tJRUKsXUqVP53Oc+F1t+SL797W+zbds21q9fH1vm8eemSkpK\nGDBgAAsWLIgtOwTZbJZsNtvlj9POqAeqra3l8ssv55prrmHOnDmceeaZSS+poKxZs4Zp06ZRWVnJ\nlClTYn2uKkSd3RlFWUZ3uPvmU4xRGYkUoM6WUb6H9v/JzN4GRgNPm9mqfOYTkcIVyc6oU0HaGYkU\npFh2RiIiUVEZiUgQVEYiEgSVkYgEQWUkIkFQGYlIEFRGIhIElZGIBEFlJCJBUBmJSBBURiISBJWR\niARBZSQiQVAZiUgQVEYiEgSVkYgEQWUkIkFQGYlIEFRGIhIElZGIBEFlJCJBUBmJSBDyvW7afWb2\nipltMbMnzKxfVAsTkcKS785oDfB37n4psAuYk/+SusfHufa38k//bOUnn99ZeZWRu//O3VtydzcC\nQ/JfUvdI+htSyPmF/Lkrv/OifM7oRkCXtxaRj6W4owFm9hwwqP2bAAe+7+6/zY35PtDk7iu6ZZUi\n0uOZu+c3gdm3gKnAl9y98RTj8gsSkdOWu1tHYzrcGZ2KmY0DZgNfPFURdXYxIlK48toZmdkuoBQ4\nmHvTRnf/ThQLE5HCkvfDNBGRKMR6BraZ/cjM/mxmL5tZlZkNjjk/sZM0zeyfzewvZtZsZiNjzB1n\nZjvN7DUzuyuu3Fz2Q2b2jpltjTO3Xf4QM1trZjvMbJuZTY85P21mL+Z+3reZWWWc+bk1pMzsJTN7\nKu7sXP5b7X7n/3jKwe4e2wvQp93t/w08GHP+PwCp3O2FwL0xZl8IXACsBUbGlJkCXgc+BZQAW4Dh\nMX7Ofw9cCmyN8/vcLn8wcGnudh/g1Tg//1xur9zrIlrPxRsVc/7twP8Fnkroe/Am8InOjI11Z+Tu\nte3u9gZaTja2m/ITO0nT3V919120nhoRl1HALnff4+5NwEpgUlzh7r4BeD+uvBPkH3D3LbnbtcAr\nwLkxr6EudzNN6wGj2J4XMbMhwNXAf8SVeaJl0MlHYLH/Q1kzm29me4F/Be6JO7+dQjhJ81zg7Xb3\n/5uYfxlDYWbDaN2lvRhzbsrMXgYOAM+5+6YY4x8A7iTGAjwBB1ab2SYzu/lUAyMvIzN7zsy2tnvZ\nlns9AcDdf+DuQ4FHaH2oFmt+bky3nKTZmeyYnWgXVnBHLMysD/A4cNtHdufdzt1b3P0yWnfhnzez\nv40j18yuAd7J7QyNeHfk7V3h7pfTukObZmZ/f7KBeZ1ndCLu/pVODn0UeAaYG2d+7iTNq4EvRZnb\nmewE/DcwtN39IcC+hNaSCDMrprWIfuXuTya1Dnc/bGZZYBywI4bIK4GJZnY1UA70NbOH3f1/xZDd\nxt0P5F6/Z2a/ofWpgw0nGhv30bTz292dROtj+Djzj5+kOdE7OEmzu5cSU84m4Hwz+5SZlQL/AsR9\nVCXJv8oAvwR2uPtP4w42szPNrH/udjmtB1B2xpHt7t9z96Hufh6t3/e1cReRmfXK7Uoxs97APwJ/\nOdn4uJ8zWph72LKF1m/MbTHn/4zWoyrP5Q53/iKuYDP7JzN7GxgNPG1m3f58lbs3A9+l9b962Q6s\ndPfY/gCY2QrgBeBvzGyvmd0QV3Yu/0rg34Av5Q4tv5T7gxSXs4Hf537eXwRWu/uzMeYnbRCwIfec\n2Ubgt+6+5mSDddKjiARB/+2siARBZSQiQVAZiUgQVEYiEgSVkYgEQWUkIkFQGYlIEFRGIhKE/wdL\nGE/mZ+od3gAAAABJRU5ErkJggg==\n",
+      "text/plain": [
+       "<matplotlib.figure.Figure at 0x7f3658758860>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "plot_trace(trace_tour(sample_tours[2]))"
+   ]
+  },
   {
    "cell_type": "markdown",
    "metadata": {},
   {
    "cell_type": "markdown",
    "metadata": {},
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 18,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "226"
       ]
      },
        "226"
       ]
      },
-     "execution_count": 17,
+     "execution_count": 18,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 19,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "61762"
       ]
      },
        "61762"
       ]
      },
-     "execution_count": 18,
+     "execution_count": 19,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 20,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "100"
       ]
      },
        "100"
       ]
      },
-     "execution_count": 19,
+     "execution_count": 20,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 21,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "123845"
       ]
      },
        "123845"
       ]
      },
-     "execution_count": 20,
+     "execution_count": 21,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 22,
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "1 loop, best of 3: 214 ms per loop\n"
+      "10 loops, best of 3: 196 ms per loop\n"
      ]
     }
    ],
      ]
     }
    ],
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 36,
+   "execution_count": 23,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "80622"
       ]
      },
        "80622"
       ]
      },
-     "execution_count": 36,
+     "execution_count": 23,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 24,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 25,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 26,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 27,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 26,
+   "execution_count": 28,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " (19, 1)]"
       ]
      },
        " (19, 1)]"
       ]
      },
-     "execution_count": 26,
+     "execution_count": 28,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": 29,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": 30,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": 31,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "80622"
       ]
      },
        "80622"
       ]
      },
-     "execution_count": 29,
+     "execution_count": 31,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 30,
+   "execution_count": 32,
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "1 loop, best of 3: 1.18 s per loop\n"
+      "1 loop, best of 3: 1.2 s per loop\n"
      ]
     }
    ],
      ]
     }
    ],
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 31,
+   "execution_count": 33,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "13"
       ]
      },
        "13"
       ]
      },
-     "execution_count": 31,
+     "execution_count": 33,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 34,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " (212, 113)]"
       ]
      },
        " (212, 113)]"
       ]
      },
-     "execution_count": 32,
+     "execution_count": 34,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
+   "execution_count": 35,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " (208, 204)]"
       ]
      },
        " (208, 204)]"
       ]
      },
-     "execution_count": 33,
+     "execution_count": 35,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
+   "execution_count": 36,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " (127, 1)]"
       ]
      },
        " (127, 1)]"
       ]
      },
-     "execution_count": 34,
+     "execution_count": 36,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
diff --git a/07-interpreter/interpreter-solution.ipynb b/07-interpreter/interpreter-solution.ipynb
new file mode 100644 (file)
index 0000000..78200d9
--- /dev/null
@@ -0,0 +1,390 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Machine interpreter\n",
+    "\n",
+    "## Instructions\n",
+    "\n",
+    "After a good day sightseeing, it's back to the hotel and time for some refreshment. Unfortunately, the minibar in your room refuses to open. It's been hacked, with some ransomware! You'll need to provide the correct unlock code so you can get a nice, cold drink.\n",
+    "\n",
+    "You could pay a large chunk of bitcoin, or you could defeat the ransomware some other way. \n",
+    "\n",
+    "You quickly find the schematics of the minibar lock. It's a fairly simple machine. It has four registers, `a`, `b`, `c`, `d`, and a special purpose `pc` register for the program counter. Each register can hold a 64-bit value (far bigger than any number in the programs you'll be running). You can assume all registers hold zero when the program starts.\n",
+    "\n",
+    "On each clock tick, the machine executes the instruction pointed to by the `pc`, then increments `pc`. The machine halts when the machine tries to read from a location beyond the end of the program.\n",
+    "\n",
+    "The machine has only a few instructions. They're listed by handy mnemonics:\n",
+    "\n",
+    "| Instruction | Description |\n",
+    "|:------------|:------------|\n",
+    "| `inc r`     | increment contents of register `r` |\n",
+    "| `dec r`     | decrement contents of register `r` |\n",
+    "| `set r i`   | set contents of register `r` to literal value `i` |\n",
+    "| `cpy r s`   | copy contents of register `r` into register `s` | \n",
+    "| `jmp i`     | jump to instruction `i` places forward |\n",
+    "| `jpz r i`   | jump to instruction `i` places forward if<br>register `r` contains zero, otherwise continue to next instruction |\n",
+    "\n",
+    "The `jmp` and `jpz` instructions jump relative to the current instruction, overriding the normal change in `pc`. `jmp -1` would jump back to the previous instruction; `jpz a 2` would skip the next instruction if register `a` contains zero.\n",
+    "\n",
+    "Before you start execution of a program, you can set the values of some registers.\n",
+    "\n",
+    "For example, this program multiplies the values in the a and b registers, leaving the result in the c register:\n",
+    "\n",
+    "```\n",
+    "set c 0\n",
+    "cpy a d\n",
+    "jpz b 8\n",
+    "dec b\n",
+    "cpy d a\n",
+    "jpz a 4\n",
+    "inc c\n",
+    "dec a\n",
+    "jmp -3\n",
+    "jmp -7\n",
+    "set d 0\n",
+    "```\n",
+    "\n",
+    "# Part 1\n",
+    "\n",
+    "You think you've worked out how to generate the code wanted by the ransomware. The program is given in [07-program](07-program.txt), one instruction per line. \n",
+    "\n",
+    "Starting with register `a` holding 7, and all other registers holding zero, what does register `a` contain when the program finishes?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "It seems your guess of 7 as the starting value was wrong.\n",
+    "\n",
+    "# Part 2\n",
+    "\n",
+    "The program is still given in [07-program.txt](07-program.txt), one instruction per line. \n",
+    "\n",
+    "Starting with register `a` holding 937, and all other registers and memory locations holding zero, what does register `a` contain when the program finishes?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def new_machine():\n",
+    "    return {'pc': 0, \n",
+    "            'a': 0,\n",
+    "            'b': 0, \n",
+    "            'c': 0,\n",
+    "            'd': 0,\n",
+    "            'instructions': []}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def show_machine(machine):\n",
+    "    return ', '.join('{}: {}'.format(sk, machine[int(sk) if sk.isnumeric() else sk]) \n",
+    "                     for sk in sorted(str(k) for k in machine)\n",
+    "                     if sk != 'instructions')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def inc(reg, machine):\n",
+    "    machine[reg] += 1\n",
+    "    machine['pc'] += 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def dec(reg, machine):\n",
+    "    machine[reg] -= 1\n",
+    "    machine['pc'] += 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def jmp(addr, machine):\n",
+    "    machine['pc'] += addr"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def jpz(reg, addr, machine):\n",
+    "    if machine[reg] == 0:\n",
+    "        machine['pc'] += addr\n",
+    "    else:\n",
+    "        machine['pc'] += 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def set_literal(reg, literal, machine):\n",
+    "    machine[reg] = literal\n",
+    "    machine['pc'] += 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def cpy(from_reg, to_reg, machine):\n",
+    "    machine[to_reg] = machine[from_reg]\n",
+    "    machine['pc'] += 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "instruction_table = {'inc': inc, 'dec': dec, 'jmp': jmp,\n",
+    "                    'jpz': jpz, 'set': set_literal, 'cpy': cpy}\n",
+    "numeric_args_table = {'jmp': [0], 'jpz': [1], 'set': [1], 'sto': [1], 'ld': [1]}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def parse(instruction):\n",
+    "    words = instruction.split()\n",
+    "    instr = words[0]\n",
+    "    args = words[1:]\n",
+    "    if instr in numeric_args_table:\n",
+    "        for p in numeric_args_table[instr]:\n",
+    "            args[p] = int(args[p])\n",
+    "    return instruction_table[instr], args"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def program_from_instructions(prog, machine):\n",
+    "    machine['instructions'] = [parse(instr) for instr in prog]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def unlabel_listing(listing):\n",
+    "    labelled_instructions = [i.strip() for i in listing.split('\\n') \n",
+    "                             if i.strip() \n",
+    "                             if not i.strip().startswith('#')]\n",
+    "    return replace_labels(labelled_instructions)    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def program_from_listing(listing, machine):\n",
+    "    instructions = unlabel_listing(listing)\n",
+    "    program_from_instructions(instructions, machine)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def replace_labels(listing):\n",
+    "    locations = {}\n",
+    "    for n, i in enumerate(listing):\n",
+    "        if ':' in i:\n",
+    "            locations[i.split(':')[0]] = n\n",
+    "\n",
+    "    unlabelled_listing = []\n",
+    "    for n, i in enumerate(listing):\n",
+    "        instr = i.split()\n",
+    "        if ':' in i:\n",
+    "            instr = i.split(':')[1].split()\n",
+    "        else:\n",
+    "            instr = i.split()\n",
+    "        terms = []\n",
+    "        for term in instr:\n",
+    "            if term in locations:\n",
+    "                terms += [str(locations[term] - n)]\n",
+    "            else:\n",
+    "                terms += [term]\n",
+    "        transformed_instr = ' '.join(terms)\n",
+    "        unlabelled_listing += [transformed_instr]\n",
+    "        \n",
+    "    return unlabelled_listing    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def run(machine, initial_state=None, trace=False):\n",
+    "    if initial_state:\n",
+    "        machine.update(initial_state)\n",
+    "    while machine['pc'] < len(machine['instructions']):\n",
+    "        if trace:\n",
+    "            print(show_machine(machine))\n",
+    "        cmd, args = machine['instructions'][machine['pc']]\n",
+    "        cmd(*args, machine)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def execute(listing, initial_state=None, trace=False):\n",
+    "    m = new_machine()\n",
+    "    program_from_listing(listing, m)\n",
+    "    run(m, initial_state=initial_state, trace=trace)\n",
+    "    return m"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'a: 52, b: 0, c: 0, d: 0, pc: 48'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "program = open('07-program.txt').read()\n",
+    "show_machine(execute(program, initial_state={'a': 7}))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'a: 250504, b: 0, c: 0, d: 0, pc: 48'"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "program = open('07-program.txt').read()\n",
+    "show_machine(execute(program, initial_state={'a': 937}))"
+   ]
+  },
+  {
+   "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
+}
index abc09cc70b204bab2e9340cc612e1cb7f439cfa1..562543e4d3dfa253ee27f8c8909e2886452e58f2 100644 (file)
@@ -8,14 +8,15 @@
     "\n",
     "## Instructions\n",
     "\n",
     "\n",
     "## Instructions\n",
     "\n",
-    "Four registers, `a`, `b`, `c`, and `d`.\n",
-    "Program counter, `pc`.\n",
+    "After a good day sightseeing, it's back to the hotel and time for some refreshment. Unfortunately, the minibar in your room refuses to open. It's been hacked, with some ransomware! You'll need to provide the correct unlock code so you can get a nice, cold drink.\n",
     "\n",
     "\n",
-    "Each register can hold 8-byte integers (Java `long`s).\n",
+    "You could pay a large chunk of bitcoin, or you could defeat the ransomware some other way. \n",
     "\n",
     "\n",
-    "Machine carries out the instruction at location `pc`. After it's executed, `pc` increments by 1.\n",
+    "You quickly find the schematics of the minibar lock. It's a fairly simple machine. It has four registers, `a`, `b`, `c`, `d`, and a special purpose `pc` register for the program counter. Each register can hold a 64-bit value (far bigger than any number in the programs you'll be running). You can assume all registers hold zero when the program starts.\n",
     "\n",
     "\n",
-    "`jmp` and `jpz` override this normal change in `pc`.\n",
+    "On each clock tick, the machine executes the instruction pointed to by the `pc`, then increments `pc`. The machine halts when the machine tries to read from a location beyond the end of the program.\n",
+    "\n",
+    "The machine has only a few instructions. They're listed by handy mnemonics:\n",
     "\n",
     "| Instruction | Description |\n",
     "|:------------|:------------|\n",
     "\n",
     "| Instruction | Description |\n",
     "|:------------|:------------|\n",
     "| `jmp i`     | jump to instruction `i` places forward |\n",
     "| `jpz r i`   | jump to instruction `i` places forward if<br>register `r` contains zero, otherwise continue to next instruction |\n",
     "\n",
     "| `jmp i`     | jump to instruction `i` places forward |\n",
     "| `jpz r i`   | jump to instruction `i` places forward if<br>register `r` contains zero, otherwise continue to next instruction |\n",
     "\n",
-    "For `jmp` and `jpz`, `i` is relative to the current instruction. `i` can be negative to jump to earlier places in the program. `i`=1 is a no-op, `i`=0 causes an infinite loop."
+    "The `jmp` and `jpz` instructions jump relative to the current instruction, overriding the normal change in `pc`. `jmp -1` would jump back to the previous instruction; `jpz a 2` would skip the next instruction if register `a` contains zero.\n",
+    "\n",
+    "Before you start execution of a program, you can set the values of some registers.\n",
+    "\n",
+    "For example, this program multiplies the values in the a and b registers, leaving the result in the c register:\n",
+    "\n",
+    "```\n",
+    "set c 0\n",
+    "cpy a d\n",
+    "jpz b 8\n",
+    "dec b\n",
+    "cpy d a\n",
+    "jpz a 4\n",
+    "inc c\n",
+    "dec a\n",
+    "jmp -3\n",
+    "jmp -7\n",
+    "set d 0\n",
+    "```\n",
+    "\n",
+    "# Part 1\n",
+    "\n",
+    "You think you've worked out how to generate the code wanted by the ransomware. The program is given in `07-program.txt`, one instruction per line. \n",
+    "\n",
+    "Starting with register `a` holding 7, and all other registers holding zero, what does register `a` contain when the program finishes?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "It seems your guess of 7 as the starting value was wrong.\n",
+    "\n",
+    "# Part 2\n",
+    "\n",
+    "The program is still given in `07-program.txt`, one instruction per line. \n",
+    "\n",
+    "Starting with register `a` holding 937, and all other registers and memory locations holding zero, what does register `a` contain when the program finishes?"
    ]
   },
   {
    ]
   },
   {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 45,
+   "execution_count": 13,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 14,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 53,
+   "execution_count": 15,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 16,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 17,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "['inc', 'a']"
       ]
      },
        "['inc', 'a']"
       ]
      },
-     "execution_count": 15,
+     "execution_count": 17,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 47,
+   "execution_count": 18,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 49,
+   "execution_count": 19,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 20,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 21,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 22,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " 'pc': 4}"
       ]
      },
        " 'pc': 4}"
       ]
      },
-     "execution_count": 19,
+     "execution_count": 22,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 23,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " 'pc': 5}"
       ]
      },
        " 'pc': 5}"
       ]
      },
-     "execution_count": 20,
+     "execution_count": 23,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 24,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " 'pc': 5}"
       ]
      },
        " 'pc': 5}"
       ]
      },
-     "execution_count": 21,
+     "execution_count": 24,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 25,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " 'pc': 10}"
       ]
      },
        " 'pc': 10}"
       ]
      },
-     "execution_count": 22,
+     "execution_count": 25,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 71,
+   "execution_count": 26,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " 'pc': 9}"
       ]
      },
        " 'pc': 9}"
       ]
      },
-     "execution_count": 71,
+     "execution_count": 26,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 64,
+   "execution_count": 27,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 65,
+   "execution_count": 28,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "'a: 0, b: 1, c: 8, d: 0, pc: 10'"
       ]
      },
        "'a: 0, b: 1, c: 8, d: 0, pc: 10'"
       ]
      },
-     "execution_count": 65,
+     "execution_count": 28,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 66,
+   "execution_count": 29,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 30,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "'a: 4, b: 0, c: 12, d: 0, pc: 9'"
       ]
      },
        "'a: 4, b: 0, c: 12, d: 0, pc: 9'"
       ]
      },
-     "execution_count": 25,
+     "execution_count": 30,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 67,
+   "execution_count": 31,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "'a: 0, b: 0, c: 27, d: 0, pc: 11'"
       ]
      },
        "'a: 0, b: 0, c: 27, d: 0, pc: 11'"
       ]
      },
-     "execution_count": 67,
+     "execution_count": 31,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 68,
+   "execution_count": 32,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": 33,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": 34,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "'a: 2, b: 0, c: 10, d: 2, pc: 13'"
       ]
      },
        "'a: 2, b: 0, c: 10, d: 2, pc: 13'"
       ]
      },
-     "execution_count": 28,
+     "execution_count": 34,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": 35,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 30,
+   "execution_count": 36,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "'a: 52, b: 0, c: 0, d: 0, pc: 48'"
       ]
      },
        "'a: 52, b: 0, c: 0, d: 0, pc: 48'"
       ]
      },
-     "execution_count": 30,
+     "execution_count": 36,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 31,
+   "execution_count": 37,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "40"
       ]
      },
        "40"
       ]
      },
-     "execution_count": 31,
+     "execution_count": 37,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 38,
    "metadata": {
     "collapsed": true
    },
    "metadata": {
     "collapsed": true
    },
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
+   "execution_count": 39,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "52"
       ]
      },
        "52"
       ]
      },
-     "execution_count": 33,
+     "execution_count": 39,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
+   "execution_count": 40,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        "(250504, 937)"
       ]
      },
        "(250504, 937)"
       ]
      },
-     "execution_count": 34,
+     "execution_count": 40,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 36,
+   "execution_count": 41,
    "metadata": {
     "scrolled": true
    },
    "metadata": {
     "scrolled": true
    },
        "[]"
       ]
      },
        "[]"
       ]
      },
-     "execution_count": 36,
+     "execution_count": 41,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 37,
+   "execution_count": 42,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
-     "ename": "KeyboardInterrupt",
-     "evalue": "",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
-      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
-      "\u001b[0;32m<ipython-input-37-a9f4d977edea>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mshow_machine\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mexecute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprogram\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minitial_state\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m{\u001b[0m\u001b[0;34m'a'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m937\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
-      "\u001b[0;32m<ipython-input-18-d22f089366e4>\u001b[0m in \u001b[0;36mexecute\u001b[0;34m(listing, initial_state, trace)\u001b[0m\n\u001b[1;32m      2\u001b[0m     \u001b[0mm\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnew_machine\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m     \u001b[0mprogram_from_listing\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlisting\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mm\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m     \u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mm\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minitial_state\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0minitial_state\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrace\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtrace\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      5\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mm\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;32m<ipython-input-17-5478d48920ba>\u001b[0m in \u001b[0;36mrun\u001b[0;34m(machine, initial_state, trace)\u001b[0m\n\u001b[1;32m      2\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0minitial_state\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m         \u001b[0mmachine\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mupdate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minitial_state\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m     \u001b[0;32mwhile\u001b[0m \u001b[0mmachine\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'pc'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmachine\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'instructions'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      5\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mtrace\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m             \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mshow_machine\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmachine\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
-      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
-     ]
+     "data": {
+      "text/plain": [
+       "'a: 250504, b: 0, c: 0, d: 0, pc: 48'"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
     }
    ],
    "source": [
     }
    ],
    "source": [
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
+   "execution_count": 43,
+   "metadata": {
+    "collapsed": true
+   },
    "outputs": [],
    "source": [
     "# labelled_instructions = [i.strip() for i in program.split('\\n') \n",
    "outputs": [],
    "source": [
     "# labelled_instructions = [i.strip() for i in program.split('\\n') \n",
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 58,
+   "execution_count": 44,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " 'pc': 4}"
       ]
      },
        " 'pc': 4}"
       ]
      },
-     "execution_count": 58,
+     "execution_count": 44,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 59,
+   "execution_count": 45,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 55,
+   "execution_count": 46,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " 'pc': 4}"
       ]
      },
        " 'pc': 4}"
       ]
      },
-     "execution_count": 55,
+     "execution_count": 46,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 61,
+   "execution_count": 47,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
        " 'pc': 14}"
       ]
      },
        " 'pc': 14}"
       ]
      },
-     "execution_count": 61,
+     "execution_count": 47,
      "metadata": {},
      "output_type": "execute_result"
     }
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 62,
+   "execution_count": 48,
    "metadata": {},
    "outputs": [
     {
    "metadata": {},
    "outputs": [
     {
diff --git a/08-word-chains/visa-woes-solution.ipynb b/08-word-chains/visa-woes-solution.ipynb
new file mode 100644 (file)
index 0000000..009e187
--- /dev/null
@@ -0,0 +1,1118 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Visa woes\n",
+    "\n",
+    "It seems there's been a problem with your visa, and the authorities have only just noticed, even though you're coming to the end of your holiday. There's no option but to navigate the bowels of the Foreign Ministry, to find the right series of offices to visit.\n",
+    "\n",
+    "For some reason known only to themselves, all the offices have a four-letter code that just happens to be an English word. (All the ministry office codes are given in the file [08-rooms.txt](08-rooms.txt).) An office will give you the authorisation to move to a different office if the codes differ by just one letter. For instance, the authorisation from office `rash` will allow you to move to the office `bash` and you can move from `able` to `axle`.\n",
+    "\n",
+    "You can move from office `rash` to `jags` by visiting five offices in total:\n",
+    "\n",
+    "```\n",
+    "rash\n",
+    "Bash\n",
+    "basS\n",
+    "baGs\n",
+    "Jags\n",
+    "```\n",
+    "\n",
+    "where the capital letters indicate the changed letters in each step. There are other ways of getting from `rash` to `jags`, but there is no shorter route.\n",
+    "\n",
+    "# Part 1\n",
+    "\n",
+    "Including the offices at both ends, what is the smallest number of offices do you have to visit to get from `coax` to `stay`?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You may have found a route to your goal, but what if `stay` wasn't the right office? How many offices could you get in a few steps from a starting point?\n",
+    "\n",
+    "For example, there are 11 offices you can reach in one step from `rash`:\n",
+    "\n",
+    "`bash`, `cash`, `dash`, `gash`, `hash`, `lash`, `mash`, `rasp`, `rush`, `sash`, `wash`\n",
+    "\n",
+    "There are 47 distinct offices you could reach in up to two steps:\n",
+    "\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`\n",
+    "\n",
+    "The there are 180 distinct offices reachable in up to three steps from `rash`.\n",
+    "\n",
+    "The ministry office codes are still given in the file [08-rooms.txt](08-rooms.txt).\n",
+    "\n",
+    "# Part 2\n",
+    "\n",
+    "How many different offices could you visit in no more than 10 steps from `coax`?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import string\n",
+    "import heapq"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2336"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "words = [w.strip() for w in open('08-rooms.txt').readlines()]\n",
+    "len(words)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "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": 5,
+   "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": 6,
+   "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": 7,
+   "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": 8,
+   "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": 9,
+   "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": 10,
+   "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 finished:\n",
+    "        return current\n",
+    "    else:\n",
+    "        return None        "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "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 finished:\n",
+    "        return current\n",
+    "    else:\n",
+    "        return None   "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "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 finished:\n",
+    "        return current\n",
+    "    else:\n",
+    "        return None        "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "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 finished:\n",
+    "        return current\n",
+    "    else:\n",
+    "        return None        "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "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 finished:\n",
+    "        return current\n",
+    "    else:\n",
+    "        return None        "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "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 finished:\n",
+    "        return current\n",
+    "    else:\n",
+    "        return None   "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['vice', 'dice', 'dire', 'dare', 'ware', 'wars']"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "astar_search('vice', 'wars')"
+   ]
+  },
+  {
+   "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_raw('vice', 'wars')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['boon', 'boot', 'bolt', 'belt', 'bell', 'sell']"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "astar_search_raw('boon', 'sell')"
+   ]
+  },
+  {
+   "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": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "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.5 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: 166 µs per loop\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%timeit\n",
+    "astar_search_closed('vice', 'wars')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "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: 554 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: 90.6 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": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['bash',\n",
+       " 'cash',\n",
+       " 'dash',\n",
+       " 'gash',\n",
+       " 'hash',\n",
+       " 'lash',\n",
+       " 'mash',\n",
+       " 'sash',\n",
+       " 'wash',\n",
+       " 'rush',\n",
+       " 'rasp']"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "neighbours['rash']"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(11,\n",
+       " '`bash`, `cash`, `dash`, `gash`, `hash`, `lash`, `mash`, `rasp`, `rush`, `sash`, `wash`')"
+      ]
+     },
+     "execution_count": 31,
+     "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": 32,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(11,\n",
+       " '<code>bash</code>, <code>cash</code>, <code>dash</code>, <code>gash</code>, <code>hash</code>, <code>lash</code>, <code>mash</code>, <code>rasp</code>, <code>rush</code>, <code>sash</code>, <code>wash</code>')"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(reachable_in('rash', 1)), ', '.join(sorted('<code>{}</code>'.format(r) for r in reachable_in('rash', 1)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "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": 33,
+     "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": 34,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(47,\n",
+       " '<code>base</code>, <code>bash</code>, <code>bask</code>, <code>bass</code>, <code>bast</code>, <code>bath</code>, <code>bosh</code>, <code>bush</code>, <code>case</code>, <code>cash</code>, <code>cask</code>, <code>cast</code>, <code>dash</code>, <code>dish</code>, <code>gash</code>, <code>gasp</code>, <code>gosh</code>, <code>gush</code>, <code>hash</code>, <code>hasp</code>, <code>hath</code>, <code>hush</code>, <code>lash</code>, <code>lass</code>, <code>last</code>, <code>lath</code>, <code>lush</code>, <code>mash</code>, <code>mask</code>, <code>mass</code>, <code>mast</code>, <code>math</code>, <code>mesh</code>, <code>mush</code>, <code>push</code>, <code>ramp</code>, <code>rasp</code>, <code>ruse</code>, <code>rush</code>, <code>rusk</code>, <code>rust</code>, <code>sash</code>, <code>sass</code>, <code>tush</code>, <code>wash</code>, <code>wasp</code>, <code>wish</code>')"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(reachable_in('rash', 2)), ', '.join(sorted('<code>{}</code>'.format(r) for r in reachable_in('rash', 2)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "180"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(reachable_in('rash', 3))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2195"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(reachable_in('rash', 10))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2192"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(reachable_in('vice', 10))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "100 loops, best of 3: 5.81 ms per loop\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%timeit\n",
+    "len(reachable_in('rash', 10))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "100 loops, best of 3: 2.71 ms per loop\n"
+     ]
+    }
+   ],
+   "source": [
+    "%%timeit\n",
+    "len(reachable_in('rash', 10, trim_extras=True))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2188"
+      ]
+     },
+     "execution_count": 40,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(reachable_in('stay', 10))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2193"
+      ]
+     },
+     "execution_count": 41,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(reachable_in('coax', 10))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "280"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "stay5 = reachable_in('stay', 4)\n",
+    "len(stay5)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "296"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "extras = set()\n",
+    "for w in stay5:\n",
+    "    extras.update(neighbours[w])\n",
+    "extras.difference_update(stay5)\n",
+    "len(extras)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'know step yeps test pout book beck poor boos veep teed gent saws dyer hemp soon deem legs bets twit whim belt rock well bled whet prop spec weep peed loan week clef feed lock yens vent doer less teem toot yews blur clue pert pegs brew flea trig vets sued felt perk bobs brat tens beef leap bloc shoo moan boob jeez suet sits rood drag goat stay chip fled fist than loot pets suck peek pled heel hair sill prep char knot lens meek trap jeep beet crew draw tell nets peep meet sows glue bees bent pelt whit need foot bran chop gram chew teen veil lent gees fret soft leis pent gets weed keen reek news prim drab wets sics deed bows pier akin pock geed grey bogs goad skis peck prod loam keep pens hoot best reed yous sewn been tram pest whom bout unit deep boot dual lees omit peel sues berm dock yock shes lets mock grow jell whip lean thin sots geek stem floe tees sort fees gout mead dram said twin prom bras bier heft foul root fell melt bops coup coot atop brad chin moot shoe sacs chit hell door lead feet boon bolt leaf bell bias eery goop reel text boom herd rent leek rend club self send sick term airs frog yell next czar plus mean brow foam crow troy nest heed dell load glib peps cent chow pees bend jock held tent soil poop moor sped emit boss fest crop mews knit tout crag knob grab thaw vial sack help jets very boys flue whir newt wiry beep room pews crab baas cock coop hock blue flee moat skid quit dial brag cell aloe grad hews went leak toad wees mewl coat dent'"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "' '.join(extras)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['coax', 'coat', 'boat', 'boar', 'soar', 'star', 'stay']"
+      ]
+     },
+     "execution_count": 45,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "astar_search('coax', 'stay')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "CPU times: user 620 ms, sys: 4 ms, total: 624 ms\n",
+      "Wall time: 624 ms\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "['coax', 'coat', 'chat', 'shat', 'spat', 'spay', 'stay']"
+      ]
+     },
+     "execution_count": 46,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "%time bfs_search_closed('coax', 'stay')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# %time bfs_search('coax', 'stay')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['czar', 'tzar', 'tear', 'sear', 'star', 'stay']"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "astar_search('czar', 'stay')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# %time bfs_search('czar', 'stay')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "# %time bfs_search('coax', 'stay')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 79,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "185"
+      ]
+     },
+     "execution_count": 79,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "rushn = reachable_in('rush', 3)\n",
+    "rushn.add('rush')\n",
+    "len(rushn)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 80,
+   "metadata": {
+    "collapsed": true,
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "links = set()\n",
+    "for w in rushn:\n",
+    "    for n in neighbours[w]:\n",
+    "        if n in rushn:\n",
+    "            links.add(frozenset((n, w)))\n",
+    "\n",
+    "with open('rush3.dot', 'w') as f:\n",
+    "    f.write('graph g {\\n')\n",
+    "    for l in links:\n",
+    "        lt = tuple(l)\n",
+    "        f.write('\"{}\" -- \"{}\";\\n'.format(lt[0], lt[1]))\n",
+    "    f.write('}\\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
+}
diff --git a/08-word-chains/word-chain-solution.ipynb b/08-word-chains/word-chain-solution.ipynb
deleted file mode 100644 (file)
index ba6e8bf..0000000
+++ /dev/null
@@ -1,1092 +0,0 @@
-{
- "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": 2,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "import string\n",
-    "import heapq"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "2336"
-      ]
-     },
-     "execution_count": 3,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "words = [w.strip() for w in open('08-rooms.txt').readlines()]\n",
-    "len(words)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "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": 5,
-   "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": 6,
-   "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": 7,
-   "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": 8,
-   "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": 9,
-   "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": 10,
-   "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 finished:\n",
-    "        return current\n",
-    "    else:\n",
-    "        return None        "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "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 finished:\n",
-    "        return current\n",
-    "    else:\n",
-    "        return None   "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "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 finished:\n",
-    "        return current\n",
-    "    else:\n",
-    "        return None        "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "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 finished:\n",
-    "        return current\n",
-    "    else:\n",
-    "        return None        "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "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 finished:\n",
-    "        return current\n",
-    "    else:\n",
-    "        return None        "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "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 finished:\n",
-    "        return current\n",
-    "    else:\n",
-    "        return None   "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "['vice', 'dice', 'dire', 'dare', 'ware', 'wars']"
-      ]
-     },
-     "execution_count": 16,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "astar_search('vice', 'wars')"
-   ]
-  },
-  {
-   "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_raw('vice', 'wars')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "['boon', 'boot', 'bolt', 'belt', 'bell', 'sell']"
-      ]
-     },
-     "execution_count": 18,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "astar_search_raw('boon', 'sell')"
-   ]
-  },
-  {
-   "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": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "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.5 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: 166 µs per loop\n"
-     ]
-    }
-   ],
-   "source": [
-    "%%timeit\n",
-    "astar_search_closed('vice', 'wars')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 26,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "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: 554 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: 90.6 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": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "['bash',\n",
-       " 'cash',\n",
-       " 'dash',\n",
-       " 'gash',\n",
-       " 'hash',\n",
-       " 'lash',\n",
-       " 'mash',\n",
-       " 'sash',\n",
-       " 'wash',\n",
-       " 'rush',\n",
-       " 'rasp']"
-      ]
-     },
-     "execution_count": 30,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "neighbours['rash']"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 31,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "(11,\n",
-       " '`bash`, `cash`, `dash`, `gash`, `hash`, `lash`, `mash`, `rasp`, `rush`, `sash`, `wash`')"
-      ]
-     },
-     "execution_count": 31,
-     "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": 32,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "(11,\n",
-       " '<code>bash</code>, <code>cash</code>, <code>dash</code>, <code>gash</code>, <code>hash</code>, <code>lash</code>, <code>mash</code>, <code>rasp</code>, <code>rush</code>, <code>sash</code>, <code>wash</code>')"
-      ]
-     },
-     "execution_count": 32,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "len(reachable_in('rash', 1)), ', '.join(sorted('<code>{}</code>'.format(r) for r in reachable_in('rash', 1)))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 33,
-   "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": 33,
-     "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": 34,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "(47,\n",
-       " '<code>base</code>, <code>bash</code>, <code>bask</code>, <code>bass</code>, <code>bast</code>, <code>bath</code>, <code>bosh</code>, <code>bush</code>, <code>case</code>, <code>cash</code>, <code>cask</code>, <code>cast</code>, <code>dash</code>, <code>dish</code>, <code>gash</code>, <code>gasp</code>, <code>gosh</code>, <code>gush</code>, <code>hash</code>, <code>hasp</code>, <code>hath</code>, <code>hush</code>, <code>lash</code>, <code>lass</code>, <code>last</code>, <code>lath</code>, <code>lush</code>, <code>mash</code>, <code>mask</code>, <code>mass</code>, <code>mast</code>, <code>math</code>, <code>mesh</code>, <code>mush</code>, <code>push</code>, <code>ramp</code>, <code>rasp</code>, <code>ruse</code>, <code>rush</code>, <code>rusk</code>, <code>rust</code>, <code>sash</code>, <code>sass</code>, <code>tush</code>, <code>wash</code>, <code>wasp</code>, <code>wish</code>')"
-      ]
-     },
-     "execution_count": 34,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "len(reachable_in('rash', 2)), ', '.join(sorted('<code>{}</code>'.format(r) for r in reachable_in('rash', 2)))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 35,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "180"
-      ]
-     },
-     "execution_count": 35,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "len(reachable_in('rash', 3))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 36,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "2195"
-      ]
-     },
-     "execution_count": 36,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "len(reachable_in('rash', 10))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 37,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "2192"
-      ]
-     },
-     "execution_count": 37,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "len(reachable_in('vice', 10))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 38,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "100 loops, best of 3: 5.81 ms per loop\n"
-     ]
-    }
-   ],
-   "source": [
-    "%%timeit\n",
-    "len(reachable_in('rash', 10))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 39,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "100 loops, best of 3: 2.71 ms per loop\n"
-     ]
-    }
-   ],
-   "source": [
-    "%%timeit\n",
-    "len(reachable_in('rash', 10, trim_extras=True))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 40,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "2188"
-      ]
-     },
-     "execution_count": 40,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "len(reachable_in('stay', 10))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 41,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "2193"
-      ]
-     },
-     "execution_count": 41,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "len(reachable_in('coax', 10))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 42,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "280"
-      ]
-     },
-     "execution_count": 42,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "stay5 = reachable_in('stay', 4)\n",
-    "len(stay5)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 43,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "296"
-      ]
-     },
-     "execution_count": 43,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "extras = set()\n",
-    "for w in stay5:\n",
-    "    extras.update(neighbours[w])\n",
-    "extras.difference_update(stay5)\n",
-    "len(extras)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 44,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'know step yeps test pout book beck poor boos veep teed gent saws dyer hemp soon deem legs bets twit whim belt rock well bled whet prop spec weep peed loan week clef feed lock yens vent doer less teem toot yews blur clue pert pegs brew flea trig vets sued felt perk bobs brat tens beef leap bloc shoo moan boob jeez suet sits rood drag goat stay chip fled fist than loot pets suck peek pled heel hair sill prep char knot lens meek trap jeep beet crew draw tell nets peep meet sows glue bees bent pelt whit need foot bran chop gram chew teen veil lent gees fret soft leis pent gets weed keen reek news prim drab wets sics deed bows pier akin pock geed grey bogs goad skis peck prod loam keep pens hoot best reed yous sewn been tram pest whom bout unit deep boot dual lees omit peel sues berm dock yock shes lets mock grow jell whip lean thin sots geek stem floe tees sort fees gout mead dram said twin prom bras bier heft foul root fell melt bops coup coot atop brad chin moot shoe sacs chit hell door lead feet boon bolt leaf bell bias eery goop reel text boom herd rent leek rend club self send sick term airs frog yell next czar plus mean brow foam crow troy nest heed dell load glib peps cent chow pees bend jock held tent soil poop moor sped emit boss fest crop mews knit tout crag knob grab thaw vial sack help jets very boys flue whir newt wiry beep room pews crab baas cock coop hock blue flee moat skid quit dial brag cell aloe grad hews went leak toad wees mewl coat dent'"
-      ]
-     },
-     "execution_count": 44,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "' '.join(extras)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 45,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "['coax', 'coat', 'boat', 'boar', 'soar', 'star', 'stay']"
-      ]
-     },
-     "execution_count": 45,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "astar_search('coax', 'stay')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 46,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "CPU times: user 620 ms, sys: 4 ms, total: 624 ms\n",
-      "Wall time: 624 ms\n"
-     ]
-    },
-    {
-     "data": {
-      "text/plain": [
-       "['coax', 'coat', 'chat', 'shat', 'spat', 'spay', 'stay']"
-      ]
-     },
-     "execution_count": 46,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "%time bfs_search_closed('coax', 'stay')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 47,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "# %time bfs_search('coax', 'stay')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 48,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "['czar', 'tzar', 'tear', 'sear', 'star', 'stay']"
-      ]
-     },
-     "execution_count": 48,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "astar_search('czar', 'stay')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 49,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "# %time bfs_search('czar', 'stay')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 50,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
-   "source": [
-    "# %time bfs_search('coax', 'stay')"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 79,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "185"
-      ]
-     },
-     "execution_count": 79,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "rushn = reachable_in('rush', 3)\n",
-    "rushn.add('rush')\n",
-    "len(rushn)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 80,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [],
-   "source": [
-    "links = set()\n",
-    "for w in rushn:\n",
-    "    for n in neighbours[w]:\n",
-    "        if n in rushn:\n",
-    "            links.add(frozenset((n, w)))\n",
-    "\n",
-    "with open('rush3.dot', 'w') as f:\n",
-    "    f.write('graph g {\\n')\n",
-    "    for l in links:\n",
-    "        lt = tuple(l)\n",
-    "        f.write('\"{}\" -- \"{}\";\\n'.format(lt[0], lt[1]))\n",
-    "    f.write('}\\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
-}
index bf6f6c111d4a1fb3cbcd2e98855cae20994a4b14..61d009756777b3cb64ff1bd1b0547a07cdf247a5 100644 (file)
@@ -4,40 +4,85 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "# Wordsearch\n",
-    "Given a text file, consisting of three parts (a grid size, a grid, and a list of words), find:\n",
-    "* the words present in the grid, \n",
-    "* the longest word present in the grid, \n",
-    "* the number of words not present in the grid, \n",
-    "* the longest word not present that can be formed from the leftover letters\n",
+    "First nights in hotels are always a bit of an anticlimax, what with the recovery from travel and all. You decided to do one of your wordsearch puzzles.\n",
     "\n",
     "\n",
-    "The only words that need be considered are the ones given in the list in the puzzle input.\n",
+    "These puzzles are a bit different from normal because they have a puzzle grid and a list of words, but only some of the words are in the puzzle; some of the words given are decoys and aren't present.\n",
     "\n",
     "\n",
-    "The puzzle consists of:\n",
-    "1. A line consisting of _w_`x`_h_, where _w_ and _h_ are integers giving the width and height of the grid.\n",
-    "2. The grid itself, consisting of _h_ lines each of _w_ letters.\n",
-    "3. A list of words, one word per line, of arbitrary length. "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Example\n",
+    "For instance, given the grid:\n",
     "\n",
     "\n",
-    "\n",
-    "`...p.mown.\n",
-    ".sdse..ee.\n",
-    ".e.elad.cr\n",
-    "pi.dtir.ah\n",
+    "```\n",
+    "fhjpamownq\n",
+    "wsdseuqeev\n",
+    "ieaeladhcr\n",
+    "piedtiriah\n",
     "rzsiwovspu\n",
     "rzsiwovspu\n",
-    "oawh.kieab\n",
-    "brow.c.rda\n",
-    "ecnotops.r\n",
-    "d.kc.d...b\n",
-    ".staple...`\n",
+    "oawhakieab\n",
+    "browpcfrda\n",
+    "ecnotopssr\n",
+    "dikchdnpnb\n",
+    "bstapleokr\n",
+    "```\n",
+    "and the list of words:\n",
+    "\n",
+    "* adapting, apace, bombing, cackles, carnal, chump, coccyxes, cowhides, crazies, crumbled, dock, fickler, foaming, guts, knows, lived, minuend, molested, mown, pears, probed, rhubarb, rioted, shinier, solaria, staple, tops, wide, winced\n",
+    "\n",
+    "you can find these words:\n",
+    "\n",
+    "* apace, cowhides, crazies, dock, knows, lived, mown, pears, probed, rhubarb, rioted, staple, tops, wide\n",
+    "\n",
+    "but these are the decoys:\n",
+    "\n",
+    "* adapting, bombing, cackles, carnal, chump, coccyxes, crumbled, fickler, foaming, guts, minuend, molested, shinier, solaria, winced\n",
+    "\n",
+    "For this puzzle, there are 14 words with a total length of 76 letters. (Some of the words may overlap in the grid, but don't worry about that when counting word lengths in your solution.)\n",
+    "\n",
+    "## About wordsearches\n",
+    "\n",
+    "Words can go in any of the eight directions (up, down, left, right, and diagonals) in a straight line. A letter in the grid can be in more than one word. Words don't wrap around the edges of the grid.\n",
+    "\n",
+    "In the example above, the words \"lived\", \"wide\" and \"staple\" are in these positions (two words are diagonal and share a letter).\n",
+    "\n",
+    "```\n",
+    "..........\n",
+    ".......e..\n",
+    "....l.d...\n",
+    ".....i....\n",
+    "....w.v...\n",
+    ".......e..\n",
+    "........d.\n",
+    "..........\n",
+    "..........\n",
+    ".staple...\n",
+    "```\n",
+    "\n",
+    "The longest word, \"cowhides\", runs vertically upwards:\n",
+    "\n",
+    "```\n",
+    "..........\n",
+    "...s......\n",
+    "...e......\n",
+    "...d......\n",
+    "...i......\n",
+    "...h......\n",
+    "...w......\n",
+    "...o......\n",
+    "...c......\n",
+    "..........\n",
+    "```\n",
+    "\n",
+    "If there are words present in the grid that aren't in the list of words given, ignore them. For instance, you can see the word \"brow\" running left to right on the seventh row of the grid, but that doesn't count as a word in this puzzle because \"brow\" isn't in the list of words you're given.\n",
+    "\n",
+    "You're safe to assume that each word in the puzzle is present either zero or one times, never more.\n",
+    "\n",
+    "## File format\n",
+    "The wordsearch puzzle is given as a text file. The first line of the file is WxH, where W and H are the width and height of the puzzle grid, in characters. The next H lines are the grid, each line being W characters long. Finally, there's an arbitrary number of words to look for, one on each line.\n",
+    "\n",
+    "Ignore any trailing or leading blank lines, and any whitespace on a line.\n",
+    "\n",
+    "The example puzzle above, a ten by ten grid, would be written to a file as:\n",
     "\n",
     "```\n",
     "\n",
     "```\n",
+    "10x10\n",
     "fhjpamownq\n",
     "wsdseuqeev\n",
     "ieaeladhcr\n",
     "fhjpamownq\n",
     "wsdseuqeev\n",
     "ieaeladhcr\n",
     "ecnotopssr\n",
     "dikchdnpnb\n",
     "bstapleokr\n",
     "ecnotopssr\n",
     "dikchdnpnb\n",
     "bstapleokr\n",
+    "adapting\n",
+    "apace\n",
+    "bombing\n",
+    "cackles\n",
+    "carnal\n",
+    "chump\n",
+    "coccyxes\n",
+    "cowhides\n",
+    "crazies\n",
+    "crumbled\n",
+    "dock\n",
+    "fickler\n",
+    "foaming\n",
+    "guts\n",
+    "knows\n",
+    "lived\n",
+    "minuend\n",
+    "molested\n",
+    "mown\n",
+    "pears\n",
+    "probed\n",
+    "rhubarb\n",
+    "rioted\n",
+    "shinier\n",
+    "solaria\n",
+    "staple\n",
+    "tops\n",
+    "wide\n",
+    "winced\n",
     "```\n",
     "\n",
     "```\n",
     "\n",
-    "14 words added;  6 directions\n",
+    "# Part 1\n",
     "\n",
     "\n",
-    "Present: apace cowhides crazies dock knows lived mown pears probed rhubarb rioted staple tops wide\n",
+    "Your wordsearch puzzle is given in [10-wordsearch.txt](10-wordsearch.txt). \n",
+    "\n",
+    "What is the total of the lengths of all the words present in the puzzle?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "After you've solved the wordsearch and found all the words you can, you'll have some letters unused in any word. For the example wordsearch, once you've found the words, you're left with this:\n",
     "\n",
     "\n",
-    "Decoys: adapting bombing boor brick cackles carnal casino chaplets chump coaster coccyxes coddle collies creels crumbled cunt curds curled curlier deepen demeanor dicier dowses ensuing faddish fest fickler foaming gambol garoting gliding gristle grunts guts ibex impugns instants kielbasy lanyard loamier lugs market meanly minuend misprint mitts molested moonshot mucking oaks olives orgasmic pastrami perfect proceed puckered quashed refined regards retraces revel ridges ringlet scoff shinier siren solaria sprain sunder sunup tamped tapes thirds throw tiller times trains tranquil transfix typesets uric wariness welts whimsy winced winced\n",
+    "```\n",
+    "fhj.a....q\n",
+    "w....uq..v\n",
+    "i.a....h..\n",
+    "..e....i..\n",
+    "..........\n",
+    "....a.....\n",
+    "....p.f...\n",
+    "........s.\n",
+    ".i..h.npn.\n",
+    "b......okr\n",
+    "```\n",
+    "The letters remaining in the grid are `aaabeffhhhiiijknnoppqqrsuvw`. 9 of those letters are vowels. \n",
     "\n",
     "\n",
-    "Decoys: fickler, adapting, chump, foaming, molested, carnal, crumbled, guts, minuend, bombing, winced, coccyxes, solaria, shinier, cackles\n",
+    "# Part 2\n",
     "\n",
     "\n",
-    "All words: adapting, apace, bombing, cackles, carnal, chump, coccyxes, cowhides, crazies, crumbled, dock, fickler, foaming, guts, knows, lived, minuend, molested, mown, pears, probed, rhubarb, rioted, shinier, solaria, staple, tops, wide, winced\n",
+    "Your wordsearch puzzle is still given in [10-wordsearch.txt](10-wordsearch.txt).\n",
     "\n",
     "\n",
-    "Directions:  [('probed', '`(True, 3, 0, <Direction.down: 4>)`'), ('staple', '`(True, 9, 1, <Direction.right: 2>)`'), ('rioted', '`(True, 6, 7, <Direction.upleft: 5>)`'), ('cowhides', '`(True, 8, 3, <Direction.up: 3>)`'), ('tops', '`(True, 7, 4, <Direction.right: 2>)`'), ('knows', '`(True, 8, 2, <Direction.up: 3>)`'), ('lived', '`(True, 2, 4, <Direction.downright: 8>)`'), ('rhubarb', '`(True, 2, 9, <Direction.down: 4>)`'), ('crazies', '`(True, 7, 1, <Direction.up: 3>)`'), ('dock', '`(True, 8, 5, <Direction.up: 3>)`'), ('apace', '`(True, 5, 8, <Direction.up: 3>)`'), ('mown', '`(True, 0, 5, <Direction.right: 2>)`'), ('pears', '`(True, 0, 3, <Direction.downright: 8>)`'), ('wide', '`(True, 4, 4, <Direction.upright: 6>)`')]"
+    "How many vowels are left over after solving this puzzle?"
    ]
   },
   {
    ]
   },
   {