From a411357b201d8391e5e7c23893fca8705fd4cced Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Wed, 2 Aug 2017 12:25:34 +0100 Subject: [PATCH] Added questions to all problem pages, solution workings for days 1 and 2 --- .../ticket-pricing-solution.ipynb | 274 ++++++++++-- 02-lifts/lifts-solution.ipynb | 162 ++++++-- 03-door-codes/door-codes-solution.ipynb | 32 +- 04-amidakuji/amidakuji-solution-1.ipynb | 2 +- ...stion-example-tour-000-s0010-m000-trim.png | Bin 0 -> 2325 bytes .../question-example-tour-000-s0010-m000.png | Bin 0 -> 2325 bytes ...stion-example-tour-001-s0012-m000-trim.png | Bin 0 -> 2285 bytes .../question-example-tour-001-s0012-m000.png | Bin 0 -> 2285 bytes ...stion-example-tour-002-s0012-m001-trim.png | Bin 0 -> 2418 bytes .../question-example-tour-002-s0012-m001.png | Bin 0 -> 2418 bytes ...stion-example-tour-003-s0014-m001-trim.png | Bin 0 -> 2298 bytes .../question-example-tour-003-s0014-m001.png | Bin 0 -> 2298 bytes ...stion-example-tour-004-s0051-m001-trim.png | Bin 0 -> 3001 bytes .../question-example-tour-004-s0051-m001.png | Bin 0 -> 3001 bytes ...stion-example-tour-005-s0043-m001-trim.png | Bin 0 -> 2882 bytes .../question-example-tour-005-s0043-m001.png | Bin 0 -> 2882 bytes ...stion-example-tour-006-s0094-m000-trim.png | Bin 0 -> 4309 bytes .../question-example-tour-006-s0094-m000.png | Bin 0 -> 4309 bytes 06-tour-shapes/question-examples.txt | 7 + .../tour-creation-for-background.ipynb | 7 +- .../tour-shapes-build-problem-set.ipynb | 7 +- .../tour-shapes-build-raw-tours.ipynb | 11 +- 06-tour-shapes/tour-shapes-sample-tours.ipynb | 237 +++++------ 06-tour-shapes/tour-shapes-solution.ipynb | 207 ++++++++-- 07-interpreter/interpreter-solution.ipynb | 390 ++++++++++++++++++ 07-interpreter/machine-code-4-reg.ipynb | 181 ++++---- ...olution.ipynb => visa-woes-solution.ipynb} | 38 +- 10-word-search/wordsearch-solution.ipynb | 163 ++++++-- 28 files changed, 1377 insertions(+), 341 deletions(-) create mode 100644 06-tour-shapes/question-example-tour-000-s0010-m000-trim.png create mode 100644 06-tour-shapes/question-example-tour-000-s0010-m000.png create mode 100644 06-tour-shapes/question-example-tour-001-s0012-m000-trim.png create mode 100644 06-tour-shapes/question-example-tour-001-s0012-m000.png create mode 100644 06-tour-shapes/question-example-tour-002-s0012-m001-trim.png create mode 100644 06-tour-shapes/question-example-tour-002-s0012-m001.png create mode 100644 06-tour-shapes/question-example-tour-003-s0014-m001-trim.png create mode 100644 06-tour-shapes/question-example-tour-003-s0014-m001.png create mode 100644 06-tour-shapes/question-example-tour-004-s0051-m001-trim.png create mode 100644 06-tour-shapes/question-example-tour-004-s0051-m001.png create mode 100644 06-tour-shapes/question-example-tour-005-s0043-m001-trim.png create mode 100644 06-tour-shapes/question-example-tour-005-s0043-m001.png create mode 100644 06-tour-shapes/question-example-tour-006-s0094-m000-trim.png create mode 100644 06-tour-shapes/question-example-tour-006-s0094-m000.png create mode 100644 06-tour-shapes/question-examples.txt create mode 100644 07-interpreter/interpreter-solution.ipynb rename 08-word-chains/{word-chain-solution.ipynb => visa-woes-solution.ipynb} (91%) diff --git a/01-ticket-prices/ticket-pricing-solution.ipynb b/01-ticket-prices/ticket-pricing-solution.ipynb index 8ba2044..eb0cd2e 100644 --- a/01-ticket-prices/ticket-pricing-solution.ipynb +++ b/01-ticket-prices/ticket-pricing-solution.ipynb @@ -41,6 +41,245 @@ "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 `[ for in ]`\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": {}, @@ -192,41 +431,6 @@ "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, diff --git a/02-lifts/lifts-solution.ipynb b/02-lifts/lifts-solution.ipynb index dc7724f..c52facc 100644 --- a/02-lifts/lifts-solution.ipynb +++ b/02-lifts/lifts-solution.ipynb @@ -32,9 +32,34 @@ "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", - "execution_count": 1, + "execution_count": 2, "metadata": { "collapsed": true }, @@ -49,9 +74,16 @@ " 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", - "execution_count": 2, + "execution_count": 3, "metadata": { "collapsed": true }, @@ -64,9 +96,16 @@ " return current" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Finally, open the file of instructions and find the final floor." + ] + }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -75,7 +114,7 @@ "209" ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -87,9 +126,16 @@ "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", - "execution_count": 4, + "execution_count": 5, "metadata": { "collapsed": true }, @@ -106,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -115,7 +161,7 @@ "(10002, 216, -6)" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -136,7 +182,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -145,7 +191,7 @@ "209" ] }, - "execution_count": 6, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -166,9 +212,69 @@ "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", - "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 }, @@ -187,7 +293,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -196,7 +302,7 @@ "215" ] }, - "execution_count": 8, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -207,7 +313,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -216,7 +322,7 @@ "-5" ] }, - "execution_count": 9, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -227,7 +333,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -236,7 +342,7 @@ "209" ] }, - "execution_count": 10, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -247,7 +353,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -256,7 +362,7 @@ "-2" ] }, - "execution_count": 11, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -267,7 +373,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -276,7 +382,7 @@ "1259" ] }, - "execution_count": 12, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -287,7 +393,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -479,7 +585,7 @@ " 215: 2})" ] }, - "execution_count": 13, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -491,7 +597,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -500,7 +606,7 @@ "-2" ] }, - "execution_count": 14, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -511,7 +617,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -520,7 +626,7 @@ "(209, 215)" ] }, - "execution_count": 12, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -534,7 +640,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -543,7 +649,7 @@ "(209, 215)" ] }, - "execution_count": 13, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } diff --git a/03-door-codes/door-codes-solution.ipynb b/03-door-codes/door-codes-solution.ipynb index 7c5867f..b1fd105 100644 --- a/03-door-codes/door-codes-solution.ipynb +++ b/03-door-codes/door-codes-solution.ipynb @@ -45,7 +45,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": { "collapsed": true }, @@ -56,7 +56,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": { "collapsed": true }, @@ -71,7 +71,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -80,7 +80,7 @@ "('a', 'z', 'z', 'a')" ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -91,14 +91,34 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "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')" ] }, { diff --git a/04-amidakuji/amidakuji-solution-1.ipynb b/04-amidakuji/amidakuji-solution-1.ipynb index 15a816a..0a9b424 100644 --- a/04-amidakuji/amidakuji-solution-1.ipynb +++ b/04-amidakuji/amidakuji-solution-1.ipynb @@ -40,7 +40,7 @@ "\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` .)" ] 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 index 0000000000000000000000000000000000000000..bab9f89396731e7bbc09c65b5a70e96b931c833e GIT binary patch literal 2325 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 literal 0 HcmV?d00001 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 index 0000000000000000000000000000000000000000..3181a5c29d52bdd9ea5fdd03a4b96e3fd033eb4c GIT binary patch literal 2418 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 literal 0 HcmV?d00001 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 index 0000000000000000000000000000000000000000..14938611c3ea6f8ed675167065d3d2a37f0f6123 GIT binary patch literal 2418 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 literal 0 HcmV?d00001 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 index 0000000000000000000000000000000000000000..132bef079255d46899921e720c554f1f90362740 GIT binary patch literal 2298 zcmd5-dsNbC8vZpq)>uc`M$Nq9YOA|b3TnwnDXXb@cf`b0u<(MJijIPpGO*cNb-iUy zm=|QIEiWlvut7oPI69?i=&B`N$ruYsB_%IN!2aC-_MDynJKy=v`@EOu{m%K`?>S$= zcY)`04jLZ>06@pb+XD>%`;dG4D=+{&_-kJ-Xugbh3vdH~w$ekN@LHg65#x;x0D!C3 z0FZkV0CvGpt^@$cZ~%~A0s!Pa05D9g;Rc@p6JJF8o$~-Rd8H$K(9=%w@=6EWe+lAz zK%ce>1Hl23Pk`rv#jp11TJ0Y=-*$bkE+f?~9svGe0XDb*pi`N*!LoKA54ZDKGpqBc zBK^3d&(`A!&NYGmv>o`(QdrNt0Zh3MjH6FSoYcP;dMADP$DeKn*!?l!cK$=mceQ37 zEPZE|WxZB3t5s48b=Sgd|O%lxy@~ncr zlxOzH&Tn^SVotfDu)#~c<_BT%K|}|#(WAFvX)-;i;x5U`Tn5WP)V5l!8FZU0dyNF? zcTKUf$BR3a-Gek2*;S<8qFKAlRlHT*8(C z?=m{C;eEg(+6kv&b&HHiCo}y4UU1 zTQEojPVLpS(%`tg4pHkp2>H~n&6n^()Fwf=;t}t66P+2%e-Cyuzh8{d?5}N&I%ESS zs3ry&y1K5h(r#Vb8Y;OnDCwF2W{OoAgdhU1%Bw|5Q|*rI`t`XI%7)vj+9;!*MA+Ky zQSeID?W&YOGuMr$A3S~PYDW|4MI?vuA#WS2&jZ9T(`#oNDyK&upz3QFRrg}nc4qQ2 zOLXRc(Q|rs;|VmW%JgXOEs}Fpv)ld7Ckb?|AmNz>t&?tbM3&*k$0qr;^oJK?;TcwE z<1q`bIEOhW5;8eUpZfYGKkM;AcjLGPmEjH>-tK|8D+%!%*v_F@5=Ax_Yx9J3+=g)F z=QktFL(XJ2f$)9jP$Wt;LY`H*xUrWm)>X&q;Kmvp9octV%coGH6_8@v+V4A_^lSLp zDF%0V(Y&fM9DCVw1~9vnm&`h}Lr+#)$3u=-kP?NhS$K=fQFC%4G3A^A*SA=n zrr0YtjCcA^{mEyjtE&myfx_cN{jQDe$3*^EWT3;Z`?enU9=lIeC_^(}2d@lHY6)9* z@8n~1RgJTnzhp#9cd5SJRuy*g;FXaI?flPX=D+*&8u`#yJpQSU=NgOkE^#81I3qHS zSYouQRn5#$S2~rNc=;~%mzfgV&W2Bu#nU2goOpW{LzV82F}x%p@+&$7yFtzBNyRpY z7%HI58vD~XttTv6NGN^^VVx-Y4b*zKGSY8RloFZOz+QMi`a>-gfov`st*YF#w*Erq z3wb=PopU3eLCA4%a;y%IVr@yenA;EY6P59Gjxgh{R2VyyqmHwbYuSFF2pdf}BB!*) z1vF-UH!@l@xfw=w$gm2WGvWnznJe*U<^E<$yyvD6ViK`6*#^agma1Brae+A7-aH+F zl6Lg#&q#;=ecR)LH$O8;=e2iyon(%&xqts1BGPPl2KBxs-EOD)$AU%%3Q1y7 zhlcg=E!b>&lR;vCi#{`|u#rNc^=VZb8rGHPp1rs!XE)(kQV3BgPVT%QfAfYET|mK< z9SB>LBMSe)&t7%;*4q5M|I1O41a-A+A>eAjusisr|C!`@ffS1;#UW$T;y?p9!0i#X z@NaG5_UG+SAsy_I_9u_S?U8Ueq}Oiwe+bDbu?d9i-zQMSv`~;>ymx{}TzX7eLMkaC ig$SV0{{CpRmlqmb{^+v5#g>9qfRAUO2h07^5B~vVhH1wD literal 0 HcmV?d00001 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 index 0000000000000000000000000000000000000000..848d13f02205c3a872e83f996f2c76de9f5629a0 GIT binary patch literal 3001 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 literal 0 HcmV?d00001 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 index 0000000000000000000000000000000000000000..2a0d8f03d60d67fca4a938363f6cd5833f60403d GIT binary patch literal 2882 zcmb7`dpuNY7svOwG?VM3oJwIL>YUI}BG;KPC?a-ABNPMEGILo_ah(-_LglriS)-uJKfkN3^_eD~gKt>1pu+Mnn1S#6`Gsl!b$q!$jHEm@RBroO>neb zJQBZsYE6VXIkRN~ zJL1=(sDy}%fk@3gZLhB%#^NWf5}PA9g-q;+riUKJ@;);xY(FO=GFt0*$nU=~v73d~ zor+8wwd0@Ji`<(;jZJLYvzzN(_je=ukN4N6`y3j;Ud`g81j*-uQ~frA4K0%*pMZs< zUTXQZBB+zOGTDa|0``wiSuE_VpYxhVnoS(doTCu3_$=ItPoKAI;Ic9uO`v1K>{2S5 zY+P^AGukNwK8^zB{kJl8M?Kp zS`ni7`}iVW1L`H4wnUMq$FG@7#jA_51BaBR;>o^;Oy&)YtoY_TjdkJE1uU&M!>l!B zBlg`lU30~OebDjj%D;ZnoHiMZDp4LIbkq;YHf*g(gK6`~16yyal3sUO3$r8Ay~W#e zW(@=iza}iyNo-2(8vwKrN=^0`~Pg!^^Uzk*%mFy&!dXE*32R^KD8LVB-InWdQP;^#87i=-15X* zHJ+7eThX3G;qm_GC4Vw(pgdG_3$U-uQ8xv`vZZg)&cTFp1u_&GNi2^CR+D;qH$JU3 z8Gl`#1kB}TaE#Ev$`mW(h8*OuCkCev^XpOZYvAiOi~hLOq!X|YroSNykHQsipIUiO zqIZ_31h);0m!HWC>Z%^mY}~gpnw9WE;LnqKOyAM?y0e9j6GFGGaId*?Bw89*p+>FO z)=di#uN|V8kI2ix;{;*U=Qjka8_savreNNTm4Zsl(a4?vKYxAnHV&&4@@Y47H}hZt zVngkV*GIpqYIKCNY=f%_X$We#3@dc@`K?-Bc5L(TicLsixkgawP;%7VIH$nmvW~IM zlXopd^Pzhea^SY3qwc|_4tLcW$pnYPvn{UUVPzGT;X4MU12yU%4KAtpdvfM(mwGc| zz25rwGBf)tGhlgqNv26 zS*lDwoa8W2pN+P;M(zHS*vqM_NJEKNrz~9e$>&`yq~=&Ll}+3mP@{|1}-Tk``m#_Ms?6kMD5IwpstJ8*_P8P6pS};($f1svdRc-9K(${ae+#nCG=uU-_demO@ruG4}{Vb`vLc2#fjXT!W2;-%61 z5hK1oNfWN8&sbMxW$0Kp%}e4jMpk;VlWBn-$rs&E0|l+BFd3BJV=Zk<1mI%1_R4MI z<%xRz+SR_ACdKy2ycrg}%Y_lMru|4N7;o(~Hq|L+9uujP|qg4wq(*auwP8mB-qlieSJOmb?-gro^w9Sy`S@bf6k4+VQRp|ev%yk04^g# zuo(a_mG54M83urK-gk{54!G-@=mJ0miet;^AmjP8i=mkb0ECDGKx8xkY%olba{%D4 z2mrqv0RZ$I08SvX8gFVc9L&xT12C}j5Y^kncw+O_*Y{({7RF@(KqsD@VJNIfBa^GF z(}$V3&jX>}RsFkh0SH}p0AM-I=l}|sA##%dfJe&+tZNZ8PRjQ6vUC^eY$6~OBA5j& z7wtcnvK;`K!+f@NKb=Ti=!Y6MtBwh0#y-FL-5A-S;#mvMvXzn_Y)f#HJyLnUMR>Hm zR2=EAGU)$ji^GHJuHv~$gaQOIextrl7qM%<+}uSG5A+cFm#NQ(w zZuEAf_G`kstp%4CQ$MZFp?xr;?5;Mx! zvA}O5cSF{Ov*Q|a)a1jq%(6xxy=z@(J>NK*#w#jWpG)9m6Vq$yN>aS=Kh-eyKf5JE zL7!w5i51GI^4oO{qUt`X z#`mE4I+yNCkX5|5*gI{`o8V_ftC_D*pDE?<&9Ns%F-v36K4Ceh9j!Yt*}rWArr<*9 zPg9x@JL=bq;kdY2+IRLUf-OmGc-W_7tKOo2j-zZI{(^rE2zBOw6t7-5YJJ9%(kiOq zC;E}&_8R7}~UhUNjgw&qd)_3bVLtKT?!KE3E3(Gqx z-n0!3t70j)v=O@S^}~)c9c3x&F<;yD`dB$V-%f?+{X~Yjt>oRoZF_}F2|Y$zbzjG; zU5FFUT(}O2JNV)!>^9xqUd&%K^>CCk3y}18g{lo5o&WMZi$DI44 z37hw4j0&L%7QH1SkkrJCsM|fwD;%{Vx7)AqzQ}(p=VvW@mG>Q$zIiVNxz*lT=1&^J zg~+0Hg*3gl6}C~iqBtu`EqM?v5iwbk(qwe!7Y|Qa0@mWOJekwk;qofii#dNGZs>>}n_g6Ta%Z{K_DT{{ zWO|-?+%Isa`&mHu({P=S#h(*qZKAX`oZYF8M>2dRQFEf6fx@PsSL>0_&`NkKm|cc0 z->*Mr<@nS`;`N)^5|Ne^mfz!E!1YSLXbW>2wbLHsactW0Q1l@l~P1Qie?qiqDmvmd>Y7wru0_o*-AGdM#!~;_W*=3$ zWn{Ij>7LAj1m-zUk6aB%fe2&TAPPw>{CISmT>Xi7to8u(Dbkbc8oy0XmEDFBtI)oI z&maj^r<-FqytAfTa<=chgpVWNE(>O)m8Pr+jC4=Mw2Ci0^8Zovu47`@{pn)y{R)!d zA8--!yhIsmu6m^(o(M&hn6Pz8aCGHyDkL0sOz-D?r6)3 z!8qP;keZoGw~ljM4dRXY;!VwCc{IMiT>SrSz^kReKrtDqy?n;2B`5s~zJbw4W(C_G zk%3;+3ucyUkXy|EXd`B_SJqZiU%E))GIrq~`CCw-r2KA;-2E6oX_U*7H^e@TD&?}p zT#BDPntDN1xV8A9tUnt>D6`_j+B#}~O#3%h9*xcxY3nB%u^v<7W7e5B^CGE#+@bAG z?gP+{rsfLNjjv8hV0_>vj9I30Vrop8gY|*~hv@vGeENbwBqzogQ~zLXo%&TPP+TNp zd0ALrI`tr4_u?25ua+8k$cS)kCqJ2$d%_pv4jiBj1cRodex_zDwwmc<;sQv;ePDi@ zFFV)&Nv<5#*N?l3b++qJT7T3UUj7%o7oS6 z*3+Yh@Xu6Vm#e;zo9Bc!z?m>jLKe`Ov-{Z1|CVFXRT@g_8Ax_iIZY^s%<3^|xtVo` zI&n}J%HYQ0i=j%wls8c}mfXmpAg zV)jM6&!A(uA9hzMWKNq5n z&(ne(Z!tU7DsSD=m@}XPAFxj31#Ssn|F!2sCo0k;M<$4fD|kwSIEh|-#QB73I==+w z{gelK@B-TNLAb7pxr z3+&R(jy45t|BLgf4Qxu$PvB|FCuc*~@vnjBWeWnPwJ!MIA>x|&n4)lQiHp6o#VR%a z>K)0!SbG{V6XDH~wXNmb8rJl-Vt9snIh&4HHip!}ZSjoko^U8qU&IIFiopsm9LIU< zS@OpNkKD`6Id#d(1FI<9{;dXc{{7q#5>l!rTbwzYk@&i@404EIHHV3zO89OZ>4r{~s^vFxf& z;XsG52w_TXQM5(jv+9sPt}%MzP<2qZ^}#RUqkAAQkXVtx`OQGcofw?3-E2wAX~bC( zx>t*p&)py`DrGZ?sr(#8#yujo8LqA2tz!#X3Eng^nEe=!bzOc!&UU(&A%Ac^q?YS2 zd(7>Tsp*r)v6stuet1sK(e{fZef2kdQLl^&%fEqODIKye(OYI&(7w`P;nROpPD1VoX#)zu;oKgUfZ0*6pSkA*~?9?Sf1Y~DFgis zv9Tw;jo&oR7ZJdQD3^ z69dh+w)@1)B{fMhFqH&pY*Sbl9W)c7h%F62qEk`O;04{t9uK`h58G*d`&er3?)EgI zmmMnl^7Ro&lgu0QByxn})W1N*i=!xUa8yz?FM)GVHlr`W|DZAw``ywlX+S~eJFVn9 zK&4PlXc^Dp9F#MyFunf7s~KhZB}&*V$IwvqlN{V}Sc0vr)nC==v&RGt*hb88TZzP) z&nMEvMFs+Ks~oL0G8GDGl(}GaG*X>RKOCJdc_s}RePHD`YxcH!x@g%>J>&2CJn||O z>FR`Z1G(IFV+i1aqLP}NqPm=-l7*5ANLdA>s3xPR1X5H4r9*D~M+0wPSNN^q|K0%7 zMp)w0LJ?DIudq3y>{+t_s!_009OkpF`{`ujLO;~7S#?Y(Gxqt_@5aau70+65maU}RU|WKl%+bpGEkdL1 zrD8~bl|lbMTO1x#cNNc7BIF^E@f-DZLa^J> z37TBzg512q=jIJlmbnVdB%$V^+9=9cSABR|G2$+*c`a%=-j9wydI=VEug}st5Cu$GTyQ&vasX z%dK9R4vbT_SGk(g1& zjs<=jxf`-JoEz7Wr6wP?WtK4l>0RqO=lRCbG+sf``g{T>o2Xt(SCWF#|5U@+|Lm3s z1$~lHAXX@&){h5-@zbB8^}JbXLl=5QwPWlntge%?RV}0*K2A^7NeLO~z}-745wg%L z>>esVwsU{L%_n7KImf~L$fv3$Ka-t=!k8jVa0K3Uffxl1s6n)-4$ZIhNi8(j7ghIB zHNFSU*SU0Gf~?}bMc-+2-UL4@TFrcg`b;T*Z;m}Bf>|1a_6f;4?P%SJ$^LB{Fa;M( zf11*S*ipY;49CUI(!R4-5o}4K!^1uuTlE(Ga~x&!@E3e*K&UeZqpg?W?>rm2V z0xR;UsFSN9zrZp5*ytx`_o1#ISJiruo41+YSy=8~@X=pxK6Z?aDQn}aRqHdBlvWW9 zM}FuppGz(h>9b!rt4mE9odO<6NIh>V%n(b+_iC?RAf)!pw!T}}8R9C84ld1TTv*;o z@uqEPSQSgUrH#;qt{--s=_pHCkNMiJ*T>4~`F1Ki?^aRi1ZL`sTe9@SFA~R?fsZtDLxhQSEZG$)c1M!RKOH>{ zo({0pnvZ;``tPr}A2^*)NZ`@qPd5d{JXfA>kTWJh_Ox-nGXYiK#>xbzR5?MzL*C;7 zYdVzaYeQNp7j;*^tMz@hmCKBE>+aBPs1h-0l)feR6XZ~ntQQt;t2KOR)(mbvq-Cxg zSy?7@?u$sf*;wQ9C)cp~Rd3Xm2JV>f?Mc*!ywF<(E9!@)YCo|MxGC_o#o#-b6Qf_e zF+^<{H!t;AOKzKA$5K^QU52kgZ1%?te|zmLj?9Vp_k($FJRFPJ1m8H!Fw%&LH1rNJ z8hBo-A=Gj6{rZq>Y<^yuFiVe!abwA$4ygqcNhcyA%$wpFtBc|elTAZf_Zpw^m9~u` zy{{~hXtR`SQdwOSUXB{S@!&O@pkP)3Evhu4%%_1|Xv)8ZmOf@0)r}-2Z!Gl>ZuU{7 zT1Hmen(j$2h-02}_sG_OHjpCUcEuJPIQRM~A9u?p@R z_zaRzb-Fo*!#iubC1?B2i~Bh8?y_J;T4~A(|48>#Osm+!BmW;o?>Z)i-JdQN->)DU z{s9*z&#NS|lzW)lx$UyMCEoxWhh+e==3Py?d_u$*i!W>J3M%|C;uCBz;?PLS;s~ua zPRx8>%|PT0LMEUo)YVJS1=)+RJCXT5{5_;2RiyWLB{4 z5gF)3y+CHU2D!!jk2Yc^du44U^`(m>E@Kz|k-r7xOUm!o$lj0flR~*Hc|+{esFE&Q z%%%9*W2s82LaoIQW&GJ7f|(T`*49z`W7@y5@@RCna9cmoi1oM{FSE|PnHNd@;|^_i zavy+pG&PsMZhUo89ODBwVazg}6H{Z#9IO`{I7H_Y;nf!aA~`X}nED56>(sAWfnvfD z%gaLgQmF^=x);Zgc(v5PLq>$-JNe11M<#qR?!W=sKrm=J>St=kVyl@xCN6+f+y~~f z`Lc8UpXAChef>D4?!hg>(VWAOU`~4mZj605=_7gTW3=;7qKZWRNdygY zCngt@T8KNfQ&w9Q(c?qh2nrXF6B-!!*4AF%83F1X$(W?24Oj;|7}A_L48+UB!@b<1 zmNjk6NOU`x?J^z>^vv50nUVJ610HMoZH84{9uF_Cc&p@)H%4vc*WLA$!%gwAi z)R6_~knk8K7jw@XTu|fUNRKM`g$$b+k-ec25HW5W;-@{sD1b5s+RXhh8^!Oc!?UDdbyTEf2gJ(cnLl>8sC<{O{84Zv=iN`Q~H0{<#os ze4ZBUM2p$!RypgI#+(5a_<(gH4{%H9`ma47I#GcpF)~3!T)|Ts#7Okwqs}K))A__P z@25P_gGy-6Q%bNCS1#t>ex0(h>`GG3Ao!WM%$7VLRc_M--ex>1e3(pTDV2`6PnzWG z#=n2r>(0COf%!-Qy(8r2EX1$%+@bx|E=y7}-?vLviki{ob8V?^W2mh&eNDse&6(xh zEU-&AJKE&6{V&d^Hn1s1KY^zypPCI_$G--imo4y{*1F(-hlpw7V~WC$h+pibEmo=V zRqsd)#@f?}nFw!=tZgmd*083x6~i;s%h`0qvN5C%Zi{DR_k=@{`XW9UR}7Ya;W*Ay z&yqhLc=TRw&hh(hF7Lly=%lmPa6eiL?y-*H5uUZ@$4=8~nrN^ot29NwqUs(v?r}&! zwoLexEzSeX+j0G?(Tn_rxv1r~r`$(^XItBc>-nWMb$42I4E?IKLSPxf6pEvYRbwIfFPS zO!sQB^0^zNMWt*eF_oXENV`YGHp8_wymf3rE5Vya2D2aIv98Nc$k|T!GUN`fhtzT% zW{Iof`aq_6&lH|mv9Vfi-@Y@AS{AA}Q$n{sQkD87R^_&#fZ z8kTx*Al;hQ*l(R^?Ah5|87k%?^;2^snA7>?9=3c4%4?f*n1WG7J$u>770U}7C1s$W zAvX4;xAB|C`NI6za9mSAHM=4GEjG-u>)SAv)-EQ)?P5Q04UNtY8h6|%E`EFe_dAsV zcVeLV)^?w$xr8Q38m5vUg>4G!qJw5a6tJb?M|CO+8oZzz+2f%~^st@Qw~r;~?ru*b zdfA~OFJB*pG)ccPPa;PsO#KT~JUEIX2S+7U^Ab1*Wi$E`{0}N4(cdlI5(X4>zSBy+ z15^^_gqHRk&OtfT3e)RPzM4^nU!sJ~atsYsKgq$JfF;<On4v=x6094BV8e%Mwts%MP&ONW$UlF^343oa`M3ZwGV^qNCswo(A#qq)a0h7GtIsgCw literal 0 HcmV?d00001 diff --git a/06-tour-shapes/question-examples.txt b/06-tour-shapes/question-examples.txt new file mode 100644 index 0000000..0eaa964 --- /dev/null +++ b/06-tour-shapes/question-examples.txt @@ -0,0 +1,7 @@ +FFRRFLRRFR +FFLLRLRLLFLR +RRFFLLFFFFLF +RRLLRRFFRFRFLR +FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFF +FLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL +FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFFFLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL diff --git a/06-tour-shapes/tour-creation-for-background.ipynb b/06-tour-shapes/tour-creation-for-background.ipynb index 74716df..e9848a5 100644 --- a/06-tour-shapes/tour-creation-for-background.ipynb +++ b/06-tour-shapes/tour-creation-for-background.ipynb @@ -301,9 +301,14 @@ }, "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", + " \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", diff --git a/06-tour-shapes/tour-shapes-build-problem-set.ipynb b/06-tour-shapes/tour-shapes-build-problem-set.ipynb index 05df310..5d9c57d 100644 --- a/06-tour-shapes/tour-shapes-build-problem-set.ipynb +++ b/06-tour-shapes/tour-shapes-build-problem-set.ipynb @@ -278,9 +278,14 @@ }, "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", + " \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", diff --git a/06-tour-shapes/tour-shapes-build-raw-tours.ipynb b/06-tour-shapes/tour-shapes-build-raw-tours.ipynb index 7903070..7731efa 100644 --- a/06-tour-shapes/tour-shapes-build-raw-tours.ipynb +++ b/06-tour-shapes/tour-shapes-build-raw-tours.ipynb @@ -1111,9 +1111,14 @@ }, "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", + " \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", @@ -3224,7 +3229,9 @@ { "cell_type": "code", "execution_count": 119, - "metadata": {}, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ "tours_filename = 'tours-random-walk.txt'\n", diff --git a/06-tour-shapes/tour-shapes-sample-tours.ipynb b/06-tour-shapes/tour-shapes-sample-tours.ipynb index e438aed..59f7720 100644 --- a/06-tour-shapes/tour-shapes-sample-tours.ipynb +++ b/06-tour-shapes/tour-shapes-sample-tours.ipynb @@ -272,18 +272,23 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 58, "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", + " \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", @@ -483,7 +488,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 23, "metadata": { "collapsed": true }, @@ -519,14 +524,14 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 53, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -539,14 +544,14 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 54, "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": [ - "" + "" ] }, "metadata": {}, @@ -563,14 +568,34 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 57, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_trace(trace_tour(square_tour(a=5)))" + ] + }, + { + "cell_type": "code", + "execution_count": 55, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -587,14 +612,14 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 56, "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": "iVBORw0KGgoAAAANSUhEUgAAAQYAAAD7CAYAAACITjpPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEF9JREFUeJzt3dlu3Fh6wPE/Jdmy5EWW25aX7ullOo8QIMEEQRoYBAMk\n75A3yGUeIECu8gB5hOQyQDBXczOXk2CABANM7tJLetNmSZYtL7JlMxeHlSqTIk9pWCoeFv8/QJBL\nxTo+xeWrw68OP2Z5niNJk5a67oCk9BgYJFUYGCRVGBgkVRgYJFUYGCRVrHTdAYAsy34J/CnwAXAI\n7AIfATeBH4GnwGfAVeB/gTPgc+At8FXx90+B0+LxBvAIOAG+Be5foO03wB/VtP01cKvU9hZwFzgC\ndoAPi2W2gePitavntP01Yf1/dk7bz4HfAj/P8/zdH7xiRZZlfw78mrB+l4CfAq+BLwn7wEfAC+Ab\nwnbcImy3Hwjb4jZhnzkCPgHWCNv9VdFWdk7bXwE3atp+Cnw/0fYeYb/8GFgHvgNeTrT9TfH7vLZf\nFv/3B4R9/Fnx+ofAZtH2QdH29VLbf5Pn+b/UrbckAgPw18B/A08Ib+6QcPBcI7yxl8Vyy4SNlBc/\n7wgH4NXi8avi8UnxmlfF8q+Ltk+K9s4IG/iQsOEm2x4diO8IB/pKqe2npbZPCTvSSanfsbZH/aZo\na6fU9heEDb4/7UrUuf6JsP5/KH5D2B9G2/INYZ1vF79PCIF5n7AtDwhB4YSw3a4SDrizoq2csG2X\ni3+/Kdpan2h755y2z2ra3i9eN5pgtEsIOue1/Wqi7eeE/W1vou3j4j3mpbY/Bf4ZSD4wAPxlnufb\nXXciFVmWjYKf2tkDvszz/IuuO5KKLMv+gzCKqJVSjiHrugMJcp20d4XwCauxF4QRdK2UAoPn0lUp\nbZ++uks459bYfUK+pFZKO96VrjuQoLP4Iop4TcgDaWyFkAdrXCAVb7vuQII8lWhvn5Bo1tge48T3\nuVIaMZho02W4STid0NhbwkiqVkqBwU/HquX4IorYAO503YnEPCTMA6qVUmBIqS+pMMfQ3nPC3BiN\njeYA1TLHkDaDZXuHhBmuGtsmMkJPacfzVEKX4R7wk647kZgVIoMCA0PaXCftreEEp7JHhGt0aqUU\nGPxWospJX+09IVw3oLFXRL6VSCnHIF2GY+Bx151IzE5sAUcMafNUor0HhMuMNXadcIl/rZQCQ0p9\nSYWBob1rON2+7C6hbkitlE4lHDFUuU7a2yfMftTYqH5DLQND2lwn7Y0KpGhslx7NY1CVpxLtPSAy\n/XeANgll5mqlFBhS6ksqDAztreC+VXaLyIVlKZ1K+J19lacS7e3iZddlJ4Rak7VSCgzSZXiHHzpl\nh1iPodc8lWhvi8j03wGKfl2ZUmBw9FJlsNRlWCMywSmlg9HLrqsMDO3tEqlvOECjmyPVSmnE4LC5\nynXS3gomH8ueY/n4Xktp+/TVPcJlxhqzfHzPWdqtvddELjEeIMvH95ynEu3tY6GWsn3CjZZrpTRi\nMNGmy3ATq0SXnRG5CU9KgcFPxyrLx7e3QbhruMYsH99z5hjas3x8leXje85g2d4h8EPXnUjMDj26\n7NpTiSrzLu3dxfLxZctYPr7XUto+fbVOqHGoMcvH95yTvto7xvLxZadYPr7XHEW19wTLx5dFb9nn\niEGLzvLxVTeIFMhNKTCk1JdUOGJoz/LxVZaP7znXSXuWj6+yfHzPuU7ae4kTnMqi5eNTCgyq2suy\nbLQBvwc+Kv59Ssi0jy4nfkq4UemoJPgeoabf7eLxD4TrBUZ1Cb4nDCWziedHQ8tTwqSghw1tXyGU\nIK9r+xHjU8PJfr8mJALr+r1P2Cfr2v6u6Oc0bT8jBIUtDLBlm4TL0WulFBjMMbzv74E/IVwF94qw\no98mHJTPCAfCJuHgHhXd2CR8xXlEmMTyQbHcIeNyXqPHtwjn36dFexs1bR8TDqxR24fFcneAN4QA\ntU4Yrk+2vVb0+2nR76vFv18Xj5cm2r5d/B71+w5hOvhBqd9HhMTZetHv46LfVwmVj08n2n4y0fbf\nXWTFD8AGkcCQ5Xn3wTTLshx4lOf5dtd9kRZdlmW/Az7O83yzbpmURgxm4KX5OCDyTU1Kw3dn+Unz\ncZdIubuUAkNKoxdpka0T8gy1UjoYHTFI83FI5MKylEYM3WdBpWHoVfl4A4M0H1tYPl5SyRUsHy+p\nZA/Lx0sqeUuPysdLmo9ojYqUAoP3UJASYY5BGh7Lx0uqWMLy8ZJKLB8vqeI1lo+XVGL5eEkV17F8\nvKSSLSLl41M6GB0xSPPxoviplVKOwcAgzUe0fHxKIwZJ83GbUN6tVkqBIaW+SIvsNuN7eZwrpYPR\n0m7SfJwQ7slRK6UcgzMfpfl4TOTYT+mGMyPfEILEJ4RRxFeEuw89INzZ6FvCXXQ2CXc2+rFYdo3w\nhg8Il5ReKZ57AXxetDnZdg58eU7bdwl3Qiq3fQD8Ps/zL2b89rUgsiz7GfBLQiGUTwnFUHYI+9Ln\nhCuIvyXcZWt02fOXhGpKHxZ//5ow1L9H2He/I0xhvkm4E9dk27uET/6mtlcJt/Ert32c5/noFoYV\nqYwY/hH4K8Kb2yUctCfF79F9GI8IxSX2CYUsbxJW3AHhoL5GWEnHxXLXite+Kn5WatpeLdp+3dD2\nWtHuX1zWCtBC+AfCB9ZvGe83jwnFV08J+/EO4SB9SfiQ2iHsm8eEK4z3itc8LpY5IOyv1wm3Dzwq\n2l4lVHsetb0KbBdtjNreJaQLnhb/5/5E23/b9EaSGDH0QZZlVwkbYCl3pekcWZb9G/CLPM8by6b1\nQUrJR6nvTgmfxr1nYLggRwtqcJvIrd/6wsBwQVmW+e2J6izM8bQwb2QOHCko5gkhQdh7BgZpdnLC\nNwK9Z2CYXgbmGNRok8hU474wMFyQOQY1WJgPDQODNDtHhElEvWdgkGZnmQW5cZKB4YLMMajBneKn\n9wwMF2SOQQ3Ouu7ArBgYpNk5YIrS7H1gYJBmZ40wLbr3DAwXZI5BDW4B6113YhYMDNPLwRyDGr3p\nugOzYmCQZueQUHGp9wwM0uzcxMuuB8drJRSzhhOcBsccg2JOu+7ArBgYpmdAUMwx8H3XnZgFA8P0\ncvBUQo1uE0q1956BYXoZeCqhRle67sCsGBik2XnOglwvYWCQZucV4YYxvWdguCBzDGqwifMYhskc\ngxoszPG0MG9kDhwpKMby8ZIqcsLNkHvPwDA9p0Qr5jZwv+tOzIKB4YLMMWgIDAzTc6SgmEMsHz84\njhQUY/n4oTLHoAaWjx8qcwxqYGk3SRVHWD5eUskqsNF1J2bBwHBB5hjUYAO43nUnZsHAMD1Luynm\nddcdmBUDgzQ7R1jaTVLJDeBh152YBQPD9LxWQjHrOMFpcMwxKMby8QNkQFCM5eMHyPLxitnA8vGD\nY/l4xVztugOzYmCQZsfy8ZIqXmL5+GEyx6AGlo8fKnMMarAQcxjAwHARjhQU8wQ46boTs2BgkGYn\nJyQge8/AMD2nRCtmE8vHD5M5BjVYmA8NA8P0Fmaj69IcAY+77sQsGBim50hBMcssyDG1EG9inswx\nqMEmlo8fJnMMamD5eEkVlo+XVHENy8cPkzkGNbiF5eMHx9JuijHHIKniAEu7SSq5CTzouhOzYGCY\nntdKKGYdWOm6E7NgYJieOQbFeIu6ATIgKOYJ5hgGx/LxirF8/ABZPl4xlo+XVPEceNt1J2bBwCDN\nzktgp+tOzIKB4YLMMajBJvBh152YBQPDBZljUIOFOZ4W5o3MgSMFxTzF8vGSSt5i+fjBcUq0Yiwf\nP1TmGDQEBobpOVJQzCGWjx8cRwqKsXz8UJljUIOFKR+fxLXjWZatATcIn8rvit9LvD+9dBk4K/6e\nTzw/Cm5Z8fe8+PfoMRPPT9v25OPRa5eLvmYGB9V4C5Bl2T3G++hon4P399HRvjYy2iez0uPJ599N\ntHFe2+8mlm1qOwMe53n+jhpJBAbgRdcdkGbgV8DPgb2uOzKF3wA/q3syS+HDL8uyHPgwz/OFqMkv\npSzLsn8HHuV5/nHdMinlGEzuSfOxBfykaYGUAkPt+Y6kmXpZ/NRKJccAjhikeYleGp7SiKH7ZIc0\nDBvA3aYFUgoMKfVFWmSbhDxDrZQORkcM0ny8AJ41LZBSjsHAIM3HHpFBgSMGaXg+AB42LZBSYEhp\n9CItsuuEPEOtlALDQpTdlnrgKbDftICf0tLwHANrTQukNGIwxyDNxxZQe50EpBUYHL1I87FKyDPU\nSulgNMcgzcdj4FrTAimNGLxWQpqPUyJl7lMKDOYYpPl4APy0aYGUAsNy1x2QBmKJyPGWUo7BegzS\nfGzjlGhJJdHjPqXAYPJRmo+HwOdNCxgYpOF5U/zUMscgDc82kQ9iRwzS8KwB600LGBik4blPpHy8\npxIJy7LsM8IlsocQ7puZZdn/B9BZPl70tr2t4HssH99Xxd25yn+7tMcL3vavgF+gkR0ix1tKgcGI\nXvVnwLeM74U4umFv2WjdTRNcyzf6nfz7rNvOS7+7aPs/CfeT1NgGobxbrZQCQ0r5jlT8T57nfbhB\narKyLFvF6fZl0fLxKQUGRwxV5l3a2yZyifEAWT5eg3cGvO66E4mxfHzPpbR9+mqLyPTfAbJ8fM8Z\nLNszv1AVLR+f0sFoaTddhh1CjUON9ap8vPMYqhwxtLcEXOm6E4npVfl4RwxVDoPb2yIy/XeAousk\npcBgVK8yWLZ3VvxobBW40bRASqcSHgRVnl61t4fzGMp6VT5eugxrhCnAGjslTHKqZWBIm9unvej0\n3wF6AHzWtEBKO56JtirPjduLfjoOUK/Kx5tjqDLH0N4+ka/mBmiHSGBIacSgKgNDe5tEpv8OUHS/\nSikweBBUuU7auwHc6roTiXlIj25R50FQ5WXX7T0DnnTdicScYfl4DdwTYLfrTiRmO7aAIwYtui3g\nk647kZhrWD6+11LaPn21ijMfy6Ll41Pa8TyVqHKdtHfEuJiuAsvH95zrpL0TTD6WRcvHpzRisPZA\nleukvQdY2q3sFnCnaYGUAkNKfUmF66S9azjdvmyTkGeoldKphJ+OVeYY2rN8fNVLLB/fa+YY2nuD\n5ePLLB/fcwaG9u5jjqHM8vE9Z7BsL6V9PBU3sHy8Bm4Xcwxlx4TybrVSiqYOm6scMbS3RFofgCk4\nJnJfiZQCgyOGKr9ma+8e8HHXnUjMPXo0Jdry8VUGy/be4Xos61X5eL+zr/L0qr1dvEVd2QE9urrS\n82ldhmtYPr7slHANSa2UAoOq3D7t3cHy8WW9Kh+f0mlNKiwf394pkUuMBygjcryldDB6EFSlFLj7\nyvLxVXtEjv2UdjwTbboMm4Shs8ZyIjm9lAKDqgyW7d3A5GPZIyLXj6R0KrGVZdkS4WvLUURbIXwH\nnRV/v0I45RgdMNnEsku8HwlHbY1euzzxfF3bb4vnsom/cwltL008n9W0DX6FOwsnwNMsyx5Sv76b\ntu0K7++Tk/tgTtj2o+cn22ratn9o20y8Ppv4d877+01+TtuT+2RO5NQ9pcDwX113IEHec7G93wB/\nDPzYdUcS869NT2Z57vQBSe8zxyCpwsAgqcLAIKnCwCCpwsAgqcLAIKnCwCCpwsAgqcLAIKnCwCCp\nwsAgqcLAIKnCwCCpwsAgqcLAIKnCwCCpwsAgqcLAIKnCwCCpwsAgqcLAIKni/wBe7zt3YGlSkgAA\nAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -617,7 +642,7 @@ "data": { "image/png": "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\n1sd/Aw+RJa+eq45oAAAAAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -662,7 +687,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -671,7 +696,7 @@ "10" ] }, - "execution_count": 68, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" }, @@ -679,7 +704,7 @@ "data": { "image/png": "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\nJogA7b/FLob4OhrHyQAAAABJRU5ErkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -700,7 +725,7 @@ "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAN4AAAEACAYAAADcJMhcAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAACXdJREFUeJzt3WuoZXUdh/HnN86MioaJhUmaRVGBdhG62EV7YVjEJHTR\nksQwDSExM0zTTI1SK6KbVmSpBNLFDC1vJYWCFipJWoploJahRgZW3mecXy/WmuZ4ozqjfteZ9Xxg\nw94HYb6cs5+91jkv/Fd3I+nptSw9QJojw5MCDE8KMDwpwPCkAMOTAgxPCjA8KcDwpADDkwIMTwow\nPCnA8KQAw5MCDE8KMDwpwPCkAMOTAgxPCjA8KcDwpADDkwIMTwowPCnA8KQAw5MCDE8KMDwpwPCk\nAMOTAgxPCjA8KcDwpADDkwIMTwowPCnA8KQAw5MCDE8KMDwpwPCkAMOTAgxPCjA8KcDwpADDA6pq\n86rav6q2Tm9Zp6qWVdW7quqF6S0LVdVuVfWG9I6lbtbhjcF9FLgdOB3YKzxpXXD7ADcDPwCODE8C\n/hPclcAvgG+m9yx11d3pDRFV9SrgMmATYDNgLdP4IPor8Exg0/SQBe5i2LQ8PeRRdunua9MjFmPO\n4f0EeDtwP0NwBfwZuDS5C/gncCCwAtiC4QPh9Ogi+DuwL7ANsOX4tW/l5rA18G7g/O6O36UsSnfP\n8gGcDzTwbOCLDAG+Lb1r3LY5cDhwN3BCes+4aRmwN3ArcMkEfnYPA/cBO6W/N4t5zPmKdz6wqrtr\nfL2yux8Kz3qEqloJrO4J/ZCqahmwrLvXhP79nYGrGT6c1gIX9hK86k3tnj1matHBZDetZXjDp7yO\nIToYrsKvqapl464lYwp/TJD+H98GVo7PTwS2X2rRgeFpienB6vHlmtQt74YyPCnA8KQAw5MCDE8K\nMDwpwPCkAMOTAgxPCjA8KcDwpADDkwIMTwowPCnA8KQAw5MCDE8KMDwpwPCkAMOTAgxPCjA8KcDw\npADDkwIMTwowPCnA8KSAWYY3njjzovH5rlW1IjxJMzO78KpqS+Ba4MXjl64AVuUWaY5mF1533wNc\nvOBL9wKXhOZMUlU9s6p2SO9YqKpWVNVL0zueLLMLb3Q08CDDKbAnd/e94T1TcxZwS1WdMaEADwNu\nrKpLquqV6TEbas4nwv4UeCOw7VTCG2+DfwTsmd4yWs1w5PHVwO7hLbD+QMwHGQ6n/ER3nxTcs2hz\nveIB3ANsMZXoRocxnehgOCN+qp/MVwFfTo9YrDmHt2l6wELj1e4ohjf6Bd1dqQdwIcOV7izgJd39\npuSecdPHGN6vPwde3927dvd9oR/XBvMM9Ok4FNgEKGCPqtqpu28IbdkPeEZ33xb69x/PVxg+kH6f\nHvJkmPMVb2oOYv0H4XJg/9SQ7r57YtHR3as3lujA8KbkzcCnx+e7AycHt+gp5q3mRHT3LVV13fj8\nyvQePbW84kkBhicFGJ4UYHhSgOFJAYYnBRieFGB4UoDhSQGGJwUYnhRgeFKA4UkBhicFGJ4UYHhS\ngOFJAYYnBRieFGB4UoDhSQGGJwUYnhRgeFKA4UkBhicFzDK8qlrO+L+vH4/4rfAkzczswhvPofsH\n8NbxSw8teC49LWYXHnAv8IcFrx8Arg1tWXKqatl4x6ANMLvwejj0/QiGAB8CzuzuO7Krpm8Mbm/g\nZuCi9J6lbq6fXJcCNwE7s/5MOj2BqnofcCKwDbAlsGNVnZZdxc3A57t7bXjHoswyvO7uqroeePnE\nrnbbAQ9X1XYT23UWsIZHvl8+GNqy0ObA8ekRizG7W80FtmY4c3wSxt+bjhtffjK55QnsDVwFrAZu\n6O5KPYBjGH5N+EhVbZH8pizWnMObmvcCWzF8GBxQVduF9zza1d29K7AHcHBqxPhX6aOBlQxX4ENT\nWzaE4U3H8cBmwFqGN9SHs3MeX3df3t2/DE54P8Mt5sMM8R1VVUvufbzkBm/EDgHOYfiZHA6ckZ0z\nWecyfH82Aa4HDliKf2AxvIno7kuA747PT+3uP4YnTVJ3397dp44vf9zd50UHLZLhSQGGJwUYnhRg\neFKA4UkBhicFGJ4UYHhSgOFJAYYnBRieFGB4UoDhSQGGJwUYnhRgeFKA4UkBhicFGJ4UYHhSgOFJ\nAYYnBRieFGB4UoDhSQGGJwUYnhQwu/CqavOqugZYNb6+papeG541SVV1QlXdOr78dVV9PblnYzK7\n8BgOVtx2wevtgXtCW6buQeA54/NnAR3cslGZXXjdvQb4OENsa4GLu/uG7KrHqqrdqupXVfWB4IxT\nGE5eheEoZs+Lf5LM8gx04PvAZxkOgjw6vOUxqupKYGdgC+BfVXVdcM53GM7uO7O77wzu2KjMMrzu\nXlNVFwB7Texqdz3wAPBq1t+N7Dk+0j6THrDOeF78XQy3wkvS7G41F3guMKlzxrv7FuB5wFeB+xmO\nGz6tu2sCjzui35xHWnde/CFVtUl6zGLMObxJ6u6/dffhwI7Al4Czw5MmZbzafQ5YwRDfvtlFi1Pd\n8/xDVVWdD6zq7kpv0f+uqvYDzmT9r0m3AzsstXPQveJpqbkROHd8fi9w1lKLDgxPS0x3X9Pd+4wv\nv9DdR0UHLZLhSQGGJwUYnhRgeFKA4UkBhicFGJ4UYHhSgOFJAYYnBRieFGB4UoDhSQGGJwUYnhRg\neFKA4UkBhicFGJ4UYHhSgOFJAYYnBRieFGB4UoDhSQGGJwUYnhQwu/CqallVfQNYNb4+u6qeHx2l\n2ZldeAzHL++34PU7gReEtmimZhded98HnATcN37pt8BlqT1VdWxVHVRVK1IbHq2q3lNVJ1TVVukt\n61TVLlX1taraIb3lyTC78EanMBxz/ABwRGdP5zyM4ejlv0wowAOBYxg2TSXAtwAHAzdV1RnpMRtq\nzifCfgo4Lr3jURqY2gm1a4GHGG7R09Z9f9YyXDTe0d3nZSctzmzDA6iqlwErwzMuZzjPezXwPeB0\n4MHoouGo450Z7giuYDhz/O7oIvgQcADDKbB/Ao7s7ouykxZv+X//TzZe3f279IaqupjhTX1Cd9+W\n3gNQVT8E7gSO6u7fpPcAVNU5wCuAY4GfhX892GCzvuJJKXP944oUZXhSgOFJAYYnBRieFGB4UoDh\nSQGGJwUYnhRgeFKA4UkBhicFGJ4UYHhSgOFJAYYnBRieFGB4UoDhSQGGJwUYnhRgeFKA4UkBhicF\nGJ4UYHhSgOFJAYYnBRieFGB4UoDhSQGGJwUYnhRgeFKA4UkBhicFGJ4UYHhSgOFJAYYnBRieFGB4\nUoDhSQGGJwUYnhRgeFKA4UkBhicFGJ4UYHhSgOFJAYYnBRieFGB4UoDhSQH/Bj2f02NVdfZHAAAA\nAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -720,7 +745,7 @@ "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": [ - "" + "" ] }, "metadata": {}, @@ -733,25 +758,25 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 33, "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" } @@ -767,14 +792,14 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 34, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -787,7 +812,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -796,7 +821,7 @@ "1" ] }, - "execution_count": 44, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -810,14 +835,14 @@ }, { "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": {}, @@ -830,26 +855,24 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 37, "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": { - "image/png": "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\ngg==\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -866,35 +889,35 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 38, "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" } @@ -912,56 +935,34 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 39, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "317" - ] - }, - "execution_count": 67, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "open('mistakes.txt', 'w').write('\\n'.join(mistakes))" + "# open('mistakes.txt', 'w').write('\\n'.join(mistakes))" ] }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 40, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "137" - ] - }, - "execution_count": 69, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "open('samples.txt', 'w').write('\\n'.join(samples))" + "# open('samples.txt', 'w').write('\\n'.join(samples))" ] }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "('FFRRFLRRFR', 10)" + "('LLRFLFFLFFFFLFFFFLFL', 20)" ] }, - "execution_count": 71, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -972,16 +973,16 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "('RRLLRRFFRFRFLR', 14)" + "('FRFFRRFFLLLL', 12)" ] }, - "execution_count": 83, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -992,24 +993,24 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "'RRFFLLFFFFLF'" + "'RLLFRFFFFFFFRFLF'" ] }, - "execution_count": 74, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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\n", + "image/png": "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\nrkJggg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1024,7 +1025,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 44, "metadata": { "collapsed": true }, @@ -1037,7 +1038,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -1046,7 +1047,7 @@ "'FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFF'" ] }, - "execution_count": 80, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" }, @@ -1054,7 +1055,7 @@ "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAMwAAAEACAYAAAD/f5mJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAACT5JREFUeJzt3V2IbWUdx/Hf78yhFzM7YmXJeYlOGJSZlQYK3VQq2REk\nDYkKjKK60i6NoKsovAsKIrookLroIiizkowKQUmttAwJLT1qqcfeTnl8qTPz72KeXYOUe/3GvebZ\na+b7gcNewlqz/lP7Oy/Mw7NcVQIwzK7eAwBTQjBAgGCAAMEAAYIBAgQDBAgGCBAMECAYIEAwQIBg\ngADBAAGCAQIEAwQIBggQDBAgGCBAMECAYIAAwQABggECBLNEbK+Mef5W3MP2Ltse8x49EcySsP01\nScdt18B/Pw/PP2r7vvCan4bn3y9pVdLawPPXbN8U3uNm26f2+v+JYDA150r6Qq+bm438loftlapa\nHev8rbiH7V2SqoI31tB72H65pEcl/b6qDg79+Iu0u8dN8b+lb/70/K24R1WtZRMNv0dVHWm/Hl2b\n3mNR+JEMCBAMECAYIEAwQIBggADBAAGCAQIEAwT4wyW6sv1qSScPPP0TY84yBMGgG9sXSLohvGxN\n0ndHGGcQfiRDT59qrxdUlef9k3SRpFdV1e29BmbxJbqx/T5J35C0K1ms2RPfYdDT49L60ubegwxF\nMECAYIAAwQABggECBAMECAYIEAwQIBggQDDoaUWS0p0yeyIY9PSe9vq2rlMECAY9PdRef9N1igDB\noKdbJKmq/tx7kKEIBggQDBAgGCBAMECAYIAAwQABggECBAME2JcM3dkuSV+XdGzA6f+Q9AFJRyX9\nZMD5a5I+V1UPbHrADdhmCd3Y3iPp15L2jnyrv0s6paqOP9cPRDDoqj1Edl9VHQ6u2S/pDwMfJDt7\ng790EUtwCAbbmu3rJB1qO2c+Z/zSDwQIBggQDBAgGCBAMECAYIAAwQABggECBINty/YBSS9b5Mdk\n8SUmo234d6uks8NLf7eoGQgGU/IGrcfyiKRDA84/T9Jpkq5Z1ACsJcNktIWaq5K+WVWX95iB32Ew\nGVW11g7v7jUDwQABggECBAMECAYIEAwQIBggQDBAgGCAAMEAAYLBZNh+ZTt8Xa8ZCAZTMtu47y29\nBiAYTEZVHWmH1/aagWCAAMEAAYIBAgQDBAgGCBAMECAYIEAwQIBggADBYDJs75b0mKQnu83AvmSY\nCttnaP2py09W1Qk9ZuA7DCajqu5qh1/uNQPBYIqO9roxwQABggECBAMECAYIEAwQIBggQDBAgGCA\nAMFgiv7V68YEg8mw/dp2eEmvGQgGU/JAe32i1wAEg8moqtmy/h/3moFggADBAAGCAQIEAwQIBggQ\nDBAgGCBAMECAYDBF7nVjgsFk2D5R68+57LInmcRGfpgQ26+RdI+kp6rqhT1m4DsMJqOq7m2H1/Sa\ngWCAAMEAAYIBAgQDBAgGCBAMECAYIEAwQIBggADBYDJsW+tbLB3rNgNryTAVts+UdKekB6tqf48Z\n+A6DKZk9FPaWXgMQDCajqtba4d29ZiAYIEAwQIBggADBAAGCAQIEAwQIBggQDLqxvTLm+WMgGCyM\n7XfYPmK7hvyTdNz2zcn57VZP9/ocd/e6MbYX27sl3Shp7MWJt0r6/Mj3+L8IBotmSbtqwKpe2ytV\ntTr4A4fnj4EfybAQVTX7cemRIbG0a6I3f+9YJIIBIgQDBAgGCBAMECAYIEAwQIBggADBAAH+0j+C\ntkzkjQNPPyjpfEmfqarD402FRWBfshHY/pGkt6fXVVW3pwMvgu3bJT1cVRf3nmUsBLNgtp8v6an2\nn3PXVNl+iaSrJV095WDSz3uq+B1mwapqtvR8dcibpqqOSrp53KnGl37eU0Uw43ms9wCdbOvPm2CA\nAMEAAYIBAgQDBAgGCBAMECAYIEAwC2b7lE1cdlW79twFj4MFI5g5bO+2fVuw2dyf2qV3PdvHfYZv\ntdf7Fzr81jss6Z7eQ4yJ1crzXSbpbEm3SfrlgPM/Kul6SR8K7vGgJFXVw/F0S6KtJTsg6YBtb9fl\nMQQz38/a66er6gcDzv/YmMMssX/ODrZrLBI/ks1VVfe1wzu7DrLkNkTySNdBRkYwQIBggADBAAGC\nAQIEAwQIBggQDBAgmOVwrrTpdWjYQgSzHPa219d3nWIxuj2wdSsQzBy2z2iHZ414m9niy5tGvMeo\nbFvra+Ie7T3LmAhmvtPb6zkj3mNVmvwarOdJ2ifprS2ebYlg5qiq2Vf/r3QdZMlt2Mhv8ENhp4hg\ngADBAAGCAQIEAwQIBggQDBAgGCBAMMvhROk/fy3HEpt0MLbfZXtfcP4B2xcu4Rvz4+31nV2naNpe\nbJe1xwlig6XaZukZz0kcatX2SnjN9ZIODZzpxHZ4kqSx9g37kqQ3acRH99m+QtJXw8uO2T61qo4N\nPP8OSX8M7zEpSxVMVT1t+6CkkwdecpWkb2v4jpHnSbpS0ruDsS5vr1dI+mRwXeKYpBcHb8zNmMVy\nvqS/zjn3JEkflvT+djx3rvbF7ixJZ23njfx23FOUbV8n6dDQJxbb3qP1N9ibq2rIzpebmeliSd8Z\n8ynKtg9L2p/co219e9rQHTnb+ZN/fPqzmfTvMFuhqv7WDqe+Qd2vtug+U//f6VkRDBAgGCBAMECA\nYIAAwQABggECBAMEdmIwhyTJ9ot6D7LBpZJk+/R5J7bz0qVAMdvntcOLxr7XlCzV0pgtcoeCPcY2\nLNQc84vLbP3Vb4euC7X9C0lnaH17ozHMvqAkS0Ge0H8first7cTvMPdKUrBua7aC+MJxxpEkfVbS\n90f8+DMfDM69sb3eMORk27slnSBp7xKuBl+Ynfgd5gXh+bOwRnsTVNXjCn70sb1SVavJPdJrqqra\n+34tuY+kPeH5k7ITv8NEqmq25P57XQfZII1ls9eEH/94O2QjPwDrCAYIEAwQIBggQDBAgGCAAMEA\ngZ0YzJm9B5iCtvmHJL2i6yBLZif+pX+/JNk+X9Jf5px7kqSPjD7Rcrq0vV5p+4sDzn/vmMMsi524\nzdIV2sSGdpKSDe0mr21g+JCkdPfLq6vqmhFGWgo7LphEW1B4iaQfVtXR3vMsM9vnSDo+1t5ty4Jg\ngMBO/KUf2DSCAQIEAwQIBggQDBAgGCBAMECAYIAAwQABggECBAMECAYIEAwQIBggQDBAgGCAAMEA\nAYIBAgQDBAgGCBAMECAYIEAwQIBggADBAAGCAQIEAwQIBggQDBAgGCBAMEDg3wk1m/lkRzKtAAAA\nAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1068,7 +1069,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 46, "metadata": {}, "outputs": [ { @@ -1077,7 +1078,7 @@ "'FLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL'" ] }, - "execution_count": 81, + "execution_count": 46, "metadata": {}, "output_type": "execute_result" }, @@ -1085,7 +1086,7 @@ "data": { "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1099,7 +1100,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -1109,7 +1110,7 @@ " 'FFRFLLFFFRLRRFFFLFLRRFLLFFFFFRFLFFFFFRLLFRFRLLFFFFFFLRFFRLLFRFFFLFFLFFRFRRLLFFRLFFFFFLLFFRFRFL')" ] }, - "execution_count": 84, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" }, @@ -1117,7 +1118,7 @@ "data": { "image/png": "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\ngg==\n", "text/plain": [ - "" + "" ] }, "metadata": {}, diff --git a/06-tour-shapes/tour-shapes-solution.ipynb b/06-tour-shapes/tour-shapes-solution.ipynb index ceb641f..c4949e8 100644 --- a/06-tour-shapes/tour-shapes-solution.ipynb +++ b/06-tour-shapes/tour-shapes-solution.ipynb @@ -4,9 +4,77 @@ "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?" ] }, { @@ -260,15 +328,20 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 39, "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", + " \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", @@ -284,6 +357,66 @@ " plt.savefig(filename)" ] }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\nnO0IPfrWAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "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": [ + "" + ] + }, + "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": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_trace(trace_tour(sample_tours[2]))" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -293,7 +426,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -302,7 +435,7 @@ "226" ] }, - "execution_count": 17, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -315,7 +448,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -324,7 +457,7 @@ "61762" ] }, - "execution_count": 18, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -335,7 +468,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -344,7 +477,7 @@ "100" ] }, - "execution_count": 19, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -355,7 +488,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -364,7 +497,7 @@ "123845" ] }, - "execution_count": 20, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -375,14 +508,14 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "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" ] } ], @@ -400,7 +533,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -409,7 +542,7 @@ "80622" ] }, - "execution_count": 36, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -428,7 +561,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -452,7 +585,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 25, "metadata": { "collapsed": true }, @@ -469,7 +602,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 26, "metadata": { "collapsed": true }, @@ -489,7 +622,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -528,7 +661,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -548,7 +681,7 @@ " (19, 1)]" ] }, - "execution_count": 26, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -559,7 +692,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 29, "metadata": { "collapsed": true }, @@ -580,7 +713,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 30, "metadata": { "collapsed": true }, @@ -605,7 +738,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -614,7 +747,7 @@ "80622" ] }, - "execution_count": 29, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -628,14 +761,14 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 32, "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" ] } ], @@ -673,7 +806,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 33, "metadata": {}, "outputs": [ { @@ -682,7 +815,7 @@ "13" ] }, - "execution_count": 31, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -693,7 +826,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -714,7 +847,7 @@ " (212, 113)]" ] }, - "execution_count": 32, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -725,7 +858,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -746,7 +879,7 @@ " (208, 204)]" ] }, - "execution_count": 33, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -757,7 +890,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 36, "metadata": {}, "outputs": [ { @@ -823,7 +956,7 @@ " (127, 1)]" ] }, - "execution_count": 34, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } diff --git a/07-interpreter/interpreter-solution.ipynb b/07-interpreter/interpreter-solution.ipynb new file mode 100644 index 0000000..78200d9 --- /dev/null +++ b/07-interpreter/interpreter-solution.ipynb @@ -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
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 +} diff --git a/07-interpreter/machine-code-4-reg.ipynb b/07-interpreter/machine-code-4-reg.ipynb index abc09cc..562543e 100644 --- a/07-interpreter/machine-code-4-reg.ipynb +++ b/07-interpreter/machine-code-4-reg.ipynb @@ -8,14 +8,15 @@ "\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", - "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", - "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", - "`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", @@ -26,7 +27,44 @@ "| `jmp i` | jump to instruction `i` places forward |\n", "| `jpz r i` | jump to instruction `i` places forward if
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?" ] }, { @@ -209,7 +247,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 13, "metadata": { "collapsed": true }, @@ -224,7 +262,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": { "collapsed": true }, @@ -240,7 +278,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 15, "metadata": { "collapsed": true }, @@ -253,7 +291,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": { "collapsed": true }, @@ -286,7 +324,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -295,7 +333,7 @@ "['inc', 'a']" ] }, - "execution_count": 15, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -306,7 +344,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -338,7 +376,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -359,7 +397,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 20, "metadata": { "collapsed": true }, @@ -377,7 +415,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 21, "metadata": { "collapsed": true }, @@ -392,7 +430,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -409,7 +447,7 @@ " 'pc': 4}" ] }, - "execution_count": 19, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -426,7 +464,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -444,7 +482,7 @@ " 'pc': 5}" ] }, - "execution_count": 20, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -465,7 +503,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -483,7 +521,7 @@ " 'pc': 5}" ] }, - "execution_count": 21, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -501,7 +539,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -523,7 +561,7 @@ " 'pc': 10}" ] }, - "execution_count": 22, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -548,7 +586,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -570,7 +608,7 @@ " 'pc': 9}" ] }, - "execution_count": 71, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -596,7 +634,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -621,7 +659,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -630,7 +668,7 @@ "'a: 0, b: 1, c: 8, d: 0, pc: 10'" ] }, - "execution_count": 65, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -657,7 +695,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -683,7 +721,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -692,7 +730,7 @@ "'a: 4, b: 0, c: 12, d: 0, pc: 9'" ] }, - "execution_count": 25, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -722,7 +760,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -731,7 +769,7 @@ "'a: 0, b: 0, c: 27, d: 0, pc: 11'" ] }, - "execution_count": 67, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -760,7 +798,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -787,7 +825,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 33, "metadata": {}, "outputs": [ { @@ -816,7 +854,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -825,7 +863,7 @@ "'a: 2, b: 0, c: 10, d: 2, pc: 13'" ] }, - "execution_count": 28, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -856,7 +894,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -889,7 +927,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 36, "metadata": {}, "outputs": [ { @@ -898,7 +936,7 @@ "'a: 52, b: 0, c: 0, d: 0, pc: 48'" ] }, - "execution_count": 30, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -980,7 +1018,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 37, "metadata": {}, "outputs": [ { @@ -989,7 +1027,7 @@ "40" ] }, - "execution_count": 31, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -1000,7 +1038,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 38, "metadata": { "collapsed": true }, @@ -1021,7 +1059,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 39, "metadata": {}, "outputs": [ { @@ -1030,7 +1068,7 @@ "52" ] }, - "execution_count": 33, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -1041,7 +1079,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 40, "metadata": {}, "outputs": [ { @@ -1050,7 +1088,7 @@ "(250504, 937)" ] }, - "execution_count": 34, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -1061,7 +1099,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 41, "metadata": { "scrolled": true }, @@ -1072,7 +1110,7 @@ "[]" ] }, - "execution_count": 36, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -1089,21 +1127,18 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 42, "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\u001b[0m in \u001b[0;36m\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\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\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": [ @@ -1112,8 +1147,10 @@ }, { "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", @@ -1126,7 +1163,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 44, "metadata": {}, "outputs": [ { @@ -1143,7 +1180,7 @@ " 'pc': 4}" ] }, - "execution_count": 58, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -1161,7 +1198,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -1181,7 +1218,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 46, "metadata": {}, "outputs": [ { @@ -1198,7 +1235,7 @@ " 'pc': 4}" ] }, - "execution_count": 55, + "execution_count": 46, "metadata": {}, "output_type": "execute_result" } @@ -1216,7 +1253,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -1243,7 +1280,7 @@ " 'pc': 14}" ] }, - "execution_count": 61, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -1271,7 +1308,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 48, "metadata": {}, "outputs": [ { diff --git a/08-word-chains/word-chain-solution.ipynb b/08-word-chains/visa-woes-solution.ipynb similarity index 91% rename from 08-word-chains/word-chain-solution.ipynb rename to 08-word-chains/visa-woes-solution.ipynb index ba6e8bf..009e187 100644 --- a/08-word-chains/word-chain-solution.ipynb +++ b/08-word-chains/visa-woes-solution.ipynb @@ -4,11 +4,13 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Word chains\n", + "# Visa woes\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", + "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 instance, you can transform 'rash' to 'jags' like this:\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", @@ -18,11 +20,34 @@ "Jags\n", "```\n", "\n", - "(the capital letter is the one changed in each step).\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 1\n", + "# Part 2\n", "\n", - "Given this [list of words](words4.txt), what is the minimum number of steps to go from `vice` to `wars`?" + "How many different offices could you visit in no more than 10 steps from `coax`?" ] }, { @@ -1040,6 +1065,7 @@ "cell_type": "code", "execution_count": 80, "metadata": { + "collapsed": true, "scrolled": true }, "outputs": [], diff --git a/10-word-search/wordsearch-solution.ipynb b/10-word-search/wordsearch-solution.ipynb index bf6f6c1..61d0097 100644 --- a/10-word-search/wordsearch-solution.ipynb +++ b/10-word-search/wordsearch-solution.ipynb @@ -4,40 +4,85 @@ "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", - "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", - "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", - "`...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", - "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", + "10x10\n", "fhjpamownq\n", "wsdseuqeev\n", "ieaeladhcr\n", @@ -48,19 +93,69 @@ "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", - "14 words added; 6 directions\n", + "# Part 1\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", - "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", - "Decoys: fickler, adapting, chump, foaming, molested, carnal, crumbled, guts, minuend, bombing, winced, coccyxes, solaria, shinier, cackles\n", + "# Part 2\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", - "Directions: [('probed', '`(True, 3, 0, )`'), ('staple', '`(True, 9, 1, )`'), ('rioted', '`(True, 6, 7, )`'), ('cowhides', '`(True, 8, 3, )`'), ('tops', '`(True, 7, 4, )`'), ('knows', '`(True, 8, 2, )`'), ('lived', '`(True, 2, 4, )`'), ('rhubarb', '`(True, 2, 9, )`'), ('crazies', '`(True, 7, 1, )`'), ('dock', '`(True, 8, 5, )`'), ('apace', '`(True, 5, 8, )`'), ('mown', '`(True, 0, 5, )`'), ('pears', '`(True, 0, 3, )`'), ('wide', '`(True, 4, 4, )`')]" + "How many vowels are left over after solving this puzzle?" ] }, { -- 2.34.1