{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Given a sequence of {F|L|R}, each of which is \"move forward one step\", \"turn left, then move forward one step\", \"turn right, then move forward one step\":\n", "1. which tours are closed?\n", "2. what is the area enclosed by the tour?" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import collections\n", "import enum\n", "import random\n", "import os\n", "\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class Direction(enum.Enum):\n", " UP = 1\n", " RIGHT = 2\n", " DOWN = 3\n", " LEFT = 4\n", " \n", "turn_lefts = {Direction.UP: Direction.LEFT, Direction.LEFT: Direction.DOWN,\n", " Direction.DOWN: Direction.RIGHT, Direction.RIGHT: Direction.UP}\n", "\n", "turn_rights = {Direction.UP: Direction.RIGHT, Direction.RIGHT: Direction.DOWN,\n", " Direction.DOWN: Direction.LEFT, Direction.LEFT: Direction.UP}\n", "\n", "def turn_left(d):\n", " return turn_lefts[d]\n", "\n", "def turn_right(d):\n", " return turn_rights[d]\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "Step = collections.namedtuple('Step', ['x', 'y', 'dir'])\n", "Mistake = collections.namedtuple('Mistake', ['i', 'step'])" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def advance(step, d):\n", " if d == Direction.UP:\n", " return Step(step.x, step.y+1, d)\n", " elif d == Direction.DOWN:\n", " return Step(step.x, step.y-1, d)\n", " elif d == Direction.LEFT:\n", " return Step(step.x-1, step.y, d)\n", " elif d == Direction.RIGHT:\n", " return Step(step.x+1, step.y, d)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def step(s, current):\n", " if s == 'F':\n", " return advance(current, current.dir)\n", " elif s == 'L':\n", " return advance(current, turn_left(current.dir))\n", " elif s == 'R':\n", " return advance(current, turn_right(current.dir))\n", " else:\n", " raise ValueError" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def trace_tour(tour, startx=0, starty=0, startdir=Direction.RIGHT):\n", " current = Step(startx, starty, startdir)\n", " trace = [current]\n", " for s in tour:\n", " current = step(s, current)\n", " trace += [current]\n", " return trace " ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def positions(trace):\n", " return [(s.x, s.y) for s in trace]" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def valid(trace):\n", " return (trace[-1].x == 0 \n", " and trace[-1].y == 0 \n", " and len(set(positions(trace))) + 1 == len(trace))" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def valid_prefix(tour):\n", " current = Step(0, 0, Direction.RIGHT)\n", " prefix = []\n", " posns = []\n", " for s in tour:\n", " current = step(s, current)\n", " prefix += [s]\n", " if (current.x, current.y) in posns:\n", " return ''\n", " elif current.x == 0 and current.y == 0: \n", " return ''.join(prefix)\n", " posns += [(current.x, current.y)]\n", " if current.x == 0 and current.y == 0:\n", " return ''.join(prefix)\n", " else:\n", " return ''" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def mistake_positions(trace, debug=False):\n", " mistakes = []\n", " current = trace[0]\n", " posns = [(0, 0)]\n", " for i, current in enumerate(trace[1:]):\n", " if (current.x, current.y) in posns:\n", " if debug: print(i, current)\n", " mistakes += [Mistake(i+1, current)]\n", " posns += [(current.x, current.y)]\n", " if (current.x, current.y) == (0, 0):\n", " return mistakes[:-1]\n", " else:\n", " return mistakes + [Mistake(len(trace)+1, current)]" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def returns_to_origin(mistake_positions):\n", " return [i for i, m in mistake_positions\n", " if (m.x, m.y) == (0, 0)]" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": true }, "outputs": [], "source": [ "sample_tours = ['FFLRLLFLRL', 'FLLFFLFFFLFFLFLLRRFR', 'FFRLLFRLLFFFRFLLRLLRRLLRLL']" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def random_walk(steps=1000):\n", " return ''.join(random.choice('FFLR') for _ in range(steps))" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def bounds(trace):\n", " return (max(s.x for s in trace),\n", " max(s.y for s in trace),\n", " min(s.x for s in trace),\n", " min(s.y for s in trace))" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": true }, "outputs": [], "source": [ "plot_wh = {Direction.UP: (0, 1), Direction.LEFT: (-1, 0),\n", " Direction.DOWN: (0, -1), Direction.RIGHT: (1, 0)}" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def chunks(items, n=2):\n", " return [items[i:i+n] for i in range(len(items) - n + 1)]" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "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", " xh, yh, xl, yl = bounds(trace)\n", " if xybounds is not None: \n", " bxh, byh, bxl, byl = xybounds\n", " plt.xlim([min(xl, bxl)-1, max(xh, bxh)+1])\n", " plt.ylim([min(yl, byl)-1, max(yh, byh)+1])\n", " else:\n", " plt.xlim([xl-1, xh+1])\n", " plt.ylim([yl-1, yh+1])\n", " if filename:\n", " plt.savefig(filename)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def trim_loop(tour, random_mistake=False):\n", " trace = trace_tour(tour)\n", " mistakes = mistake_positions(trace)\n", " if random_mistake:\n", " end_mistake_index = random.randrange(len(mistakes))\n", " else:\n", " end_mistake_index = 0\n", "# print('end_mistake_index {} pointing to trace position {}; {} mistakes and {} in trace; {}'.format(end_mistake_index, mistakes[end_mistake_index].i, len(mistakes), len(trace), mistakes))\n", " # while this mistake extends to the next step in the trace...\n", " while (mistakes[end_mistake_index].i + 1 < len(trace) and \n", " end_mistake_index + 1 < len(mistakes) and\n", " mistakes[end_mistake_index].i + 1 == \n", " mistakes[end_mistake_index + 1].i):\n", "# print('end_mistake_index {} pointing to trace position {}; {} mistakes and {} in trace'.format(end_mistake_index, mistakes[end_mistake_index].i, len(mistakes), len(trace), mistakes))\n", " # push this mistake finish point later\n", " end_mistake_index += 1\n", " mistake = mistakes[end_mistake_index]\n", " \n", " # find the first location that mentions where this mistake ends (which the point where the loop starts)\n", " mistake_loop_start = max(i for i, loc in enumerate(trace[:mistake.i])\n", " if (loc.x, loc.y) == (mistake.step.x, mistake.step.y))\n", "# print('Dealing with mistake from', mistake_loop_start, 'to', mistake.i, ', trace has len', len(trace))\n", " \n", " # direction before entering the loop\n", " direction_before = trace[mistake_loop_start].dir\n", " \n", " # find the new instruction to turn from heading before the loop to heading after the loop\n", " new_instruction = 'F'\n", " if (mistake.i + 1) < len(trace):\n", " if turn_left(direction_before) == trace[mistake.i + 1].dir:\n", " new_instruction = 'L'\n", " if turn_right(direction_before) == trace[mistake.i + 1].dir:\n", " new_instruction = 'R'\n", "# if (mistake.i + 1) < len(trace):\n", "# print('turning from', direction_before, 'to', trace[mistake.i + 1].dir, 'with', new_instruction )\n", "# else:\n", "# print('turning from', direction_before, 'to BEYOND END', 'with', new_instruction )\n", " return tour[:mistake_loop_start] + new_instruction + tour[mistake.i+1:]\n", "# return mistake, mistake_loop_start, trace[mistake_loop_start-2:mistake_loop_start+8]" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def trim_all_loops(tour, mistake_reduction_attempt_limit=10):\n", " trace = trace_tour(tour)\n", " mistake_limit = 1\n", " if trace[-1].x == 0 and trace[-1].y == 0:\n", " mistake_limit = 0\n", " mistakes = mistake_positions(trace)\n", " \n", " old_mistake_count = len(mistakes)\n", " mistake_reduction_tries = 0\n", " \n", " while len(mistakes) > mistake_limit and mistake_reduction_tries < mistake_reduction_attempt_limit:\n", " tour = trim_loop(tour)\n", " trace = trace_tour(tour)\n", " mistakes = mistake_positions(trace)\n", " if len(mistakes) < old_mistake_count:\n", " old_mistake_count = len(mistakes)\n", " mistake_reduction_tries = 0\n", " else:\n", " mistake_reduction_tries += 1\n", " if mistake_reduction_tries >= mistake_reduction_attempt_limit:\n", " return ''\n", " else:\n", " return tour" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def reverse_tour(tour):\n", " def swap(tour_step):\n", " if tour_step == 'R':\n", " return 'L'\n", " elif tour_step == 'L':\n", " return 'R'\n", " else:\n", " return tour_step\n", " \n", " return ''.join(swap(s) for s in reversed(tour))" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def wander_near(locus, current, limit=10):\n", " valid_proposal = False\n", " while not valid_proposal:\n", " s = random.choice('FFFRL')\n", " if s == 'F':\n", " proposed = advance(current, current.dir)\n", " elif s == 'L':\n", " proposed = advance(current, turn_left(current.dir))\n", " elif s == 'R':\n", " proposed = advance(current, turn_right(current.dir))\n", " if abs(proposed.x - locus.x) < limit and abs(proposed.y - locus.y) < limit:\n", " valid_proposal = True\n", "# print('At {} going to {} by step {} to {}'.format(current, locus, s, proposed))\n", " return s, proposed" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def seek(goal, current):\n", " dx = current.x - goal.x\n", " dy = current.y - goal.y\n", "\n", " if dx < 0 and abs(dx) > abs(dy): # to the left\n", " side = 'left'\n", " if current.dir == Direction.RIGHT:\n", " s = 'F'\n", " elif current.dir == Direction.UP:\n", " s = 'R'\n", " else:\n", " s = 'L'\n", " elif dx > 0 and abs(dx) > abs(dy): # to the right\n", " side = 'right'\n", " if current.dir == Direction.LEFT:\n", " s = 'F'\n", " elif current.dir == Direction.UP:\n", " s = 'L'\n", " else:\n", " s = 'R'\n", " elif dy > 0 and abs(dx) <= abs(dy): # above\n", " side = 'above'\n", " if current.dir == Direction.DOWN:\n", " s = 'F'\n", " elif current.dir == Direction.RIGHT:\n", " s = 'R'\n", " else:\n", " s = 'L'\n", " else: # below\n", " side = 'below'\n", " if current.dir == Direction.UP:\n", " s = 'F'\n", " elif current.dir == Direction.LEFT:\n", " s = 'R'\n", " else:\n", " s = 'L'\n", " if s == 'F':\n", " proposed = advance(current, current.dir)\n", " elif s == 'L':\n", " proposed = advance(current, turn_left(current.dir))\n", " elif s == 'R':\n", " proposed = advance(current, turn_right(current.dir))\n", " \n", "# print('At {} going to {}, currently {}, by step {} to {}'.format(current, goal, side, s, proposed))\n", "\n", " return s, proposed" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def guided_walk(loci, locus_limit=5, wander_limit=10, seek_step_limit=20, return_anyway=False):\n", " trail = ''\n", " current = Step(0, 0, Direction.RIGHT) \n", " l = 0\n", " finished = False\n", " while not finished:\n", " if abs(current.x - loci[l].x) < locus_limit and abs(current.y - loci[l].y) < locus_limit:\n", " l += 1\n", " if l == len(loci) - 1:\n", " finished = True\n", " s, proposed = wander_near(loci[l], current, limit=wander_limit)\n", " trail += s\n", " current = proposed\n", "# print('!! Finished loci')\n", " seek_steps = 0\n", " while not (current.x == loci[l].x and current.y == loci[l].y) and seek_steps < seek_step_limit:\n", "# error = max(abs(current.x - loci[l].x), abs(current.y - loci[l].y))\n", "# s, proposed = wander_near(loci[l], current, limit=error+1)\n", " s, proposed = seek(loci[l], current)\n", " trail += s\n", " current = proposed\n", " seek_steps += 1\n", " if seek_steps >= seek_step_limit and not return_anyway:\n", " return ''\n", " else:\n", " return trail" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "image/png": "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\nVLpP4CKFIBNJl6SFQEV+muMwZFu3buWGG25QGDKRAEKHIVsFPOHufxk9LykEWfRehSETqYDQYcgs\n+ouVHIIMNIFIpBKC3V7MzB4E/g+4xMyOmdmtwF3A9WZ2mFwUorvOt424Y1ARiETCSdrxXkoYsn8o\n8lJJIcjyJb2EISLh6H4CItNEqucO6H4CIuGleiqxiISX6pqAhg2LpJdmEYpUuYreWUgdgyLhDAwM\nJFqvIoVA3FbROAGRcLLZbKL1KloIaJyASPqoY1Bkmkj11QF1DIqEp3ECIlUu1TUBDRsWCS/VhYCG\nDYuEl+pbjseZUzgykXBSPU4gPvmTdlyIyPhSPU4gHiSk5oBI+qhjUKTKqWNQZJq4IOMEzOxGM3vV\nzI6Y2e2T2ZaITE7SuTmJCwEzywD/Si5E2Z8DnzSzSwu9V8OGRdJrMjWBK4Hfufsf3H0A+Am58GRj\naNiwSHpN5qxcDryZ9/w4uYJhjPgS4bXXXktHRwdz584FoL+/n9mzZ9Pd3c1FF13E6dOn6ezsZO3a\ntbS2ttLT08PChQvp7Oxk3rx5dHR00NPTw6pVq2htbaWzs5MlS5bQ0dHBzJkz6e/vp6+vj4svvpiW\nlhY6OjpoaGg4p0+it7eX5cuX09raSnt7O2vWrOHtt99mcHCQ+vp6enp6aGpq4u2336a9vZ1169Zx\n8uRJ+vr6mDt3Lt3d3SxcuJCzZ8/S1dXFmjVraG1tpauri2w2S21tLXPmzKGrq4ve3l5Wrlw5ktdl\ny5bR1tZGNptleHiY3t5eVqxYQWtrKx0dHaxcuZIzZ84wPDxMNpult7eXZcuWcfLkSdra2li3bh2n\nTp1iYGCAgYEB6urqRvLa0dHBunXrRvbbggUL6OzspLGxkfb2drq7u1m9evVIXpuamujo6KC+vp6+\nvr4x+23FihW0tbVhZnR0dDBjxoyRvLS3t7N69WpOnz7N0NAQM2fOpKenh6VLl468Hu+3/v5+5syZ\nQ3d3N4sWLeLMmTPnHON4eXyMjx8/Tl1dHatXr6alpYXOzk6WLl1Ke3s7dXV1DA4OjslrvN/cnWw2\nS09PT9Fj3NDQQHd3N01NTRw9epRMJsPatWs5efIkvb29zJ8/n66uLhYsWEBbW9s5+y3+nra3tzNr\n1ix6enrGHOPly5dz9uzZke9cX18fM2fOZGhoiI6ODlatWsXp06cZHh6mrq6Onp6ec/br2rVrOXXq\nVNFzY926dbS0tBQ8N06cOJHsTHb3RH/Ax4H78p5/CrinwPt8y5YtvmzZMgcc8Lq6upHH8V9DQ8PI\n4wULFox5Pf9v8eLFk3p94cKFI4/r6+vHvD5v3ryRx/Pnzx/z+owZMwpua7J5zWazY17P3xezZ88e\n83r+ssbGxjGv19TUjDxetGjRpPKav/7MmTPHvJ6/r+bOnTvm9fx9Xc5jnP8ZCx2X/O9WofwVOsb5\nx2Kyxzj/cxf67ucftzlz5ox5fSLnxvz58725udmbm5sd8JLO5UkUAlcDT+U9vwO4vVAhMFpzc/OY\nZaEoLaV1odO6UJ+p1EJgMn0CvwH+xMxWmVkd8PfkwpOJyBRSUkDSoiub3QjcQ66D8X53HxOOzMyS\nJyAik+IlBCSdVCEgIlOfbioiUuVUCIhUuYoXAiGHGpvZ/WbWYmb78pY1mtkzZnbYzJ42s3llSGeF\nmT1rZgfNbL+Z3RYwrRlm9isz2xOl1RwtX21mL0RpPWRmZRuJZWYZM3vJzB4PmZaZ/d7MXo4+26+j\nZWXfh9F255nZdjM7ZGYHzOyqQMfrkujzvBT9bzOz2wJ+ri+b2Stmts/MfmxmdRM+XqVcQijXH7lC\n5zVgFZAF9gKXlnH7fwtcBuzLW3Y38LXo8e3AXWVIZwlwWfR4NnAYuDREWtG2GqL/NcALwFXAw8Dm\naPm9wD+VcT9+Gfhv4PHoeZC0gKNA46hlofbhfwK3Ro9rgXmh0spLMwO8BVwc6Hu4LNqHdXnH6ZaJ\nHq+yfeASM301sDvvecGxBZNMY9WoQuBVoCl6vAR4NcDnegxYHzotoAF4kdzIzFYgk7dfnypTGiuA\nnwPX5RUCJwOl9QawcNSysu9DYA7weoHloY/XDcD/BPxcy4A/AI1RwfY4cP1EvxuVbg4UGmq8PHCa\nF7l7C4C7nwAWl3PjZraaXO3jBXIHuexpRdXzPcAJcifo68BZd4/njh4n94Uoh+8BXyU3Ag0zWwic\nCZSWA0+b2W/M7PPRshD7cC1wysweiKrp95lZQ6C08n0CeDB6XPa03P0t4LvAMeCPQBvwEhP8blS6\nECh0zXLKXqM0s9nADuBL7t5JoM/i7sPufjm5X+krgXcVettk0zGzjUCLu+/lnWNljD1u5fqc73X3\nvwY2AF80s/eVcdv5aoErgB+6+xVAF7laaLDvnpllgZuB7dGisqdlZvPJTdpbRe5EnwXcVOCt5027\n0oXAcWBl3vMV5NpMIbWYWROAmS0hV1WatKizZQfwX+6+M2RaMXdvB54nV8WbH03nhvLtx2uAm83s\nKPAQ8AHg+8C8AGnFv4i4+0lyTaorCbMPjwNvuvuL0fNHyBUKIY/XTcBv3f1U9DxEWuuBo+5+2t2H\ngEeB9zLB70alC4FKDDUe/cv1OPCZ6PEtwM7RKyT0I+Cgu98TMi0zWxT3JJtZPbkDfxB4DthczrTc\n/RvuvtLd15I7Ns+6+6dCpGVmDVFNCjObRa79vJ8A+zCqhr9pZpdEiz4IHAiRVp5PkitIYyHSOgZc\nbWYzzcx453NN7HiVsyOkxM6MG8n1pv8OuKPM236QXKnXF+2gW8l1mvwiSvPnwPwypHMNMETu6sYe\ncu2wG4EFAdL6i2j7e4F9wL9Ey9cAvwKOkOsNzpZ5X17LOx2DZU8r2ma8//bH34UQ+zDa7rvJ/Qjt\nBX5G7upAqLTqyXWmzslbFiqtZuBQ9N3YRu6q24SOl4YNi1Q5jRgUqXIqBESqnAoBkSqnQkCkyqkQ\nEKlyKgREqpwKAZEqp0JApMr9P8nYgJi0MFyGAAAAAElFTkSuQmCC\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def square_tour(a=80):\n", " \"a is width of square\"\n", " return ('F' * a + 'L') * 4\n", "\n", "plot_trace(trace_tour(square_tour()))" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "image/png": "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\nybOEYIzJ+/+3mLJIMXCXRQAAAABJRU5ErkJggg==\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def cross_tour(a=50, b=40):\n", " \"a is width of cross arm, b is length of cross arm\"\n", " return ('F' * a + 'L' + 'F' * b + 'R' + 'F' * b + 'L') * 4\n", "\n", "plot_trace(trace_tour(cross_tour()))" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def quincunx_tour(a=60, b=30, c=50):\n", " \"a is length of indent, b is indent/outdent distance, c is outdent outer length\"\n", " return ('F' * a + 'R' + 'F' * b + 'L' + 'F' * c + 'L' + 'F' * c + 'L' + 'F' * b + 'R') * 4\n", "plot_trace(trace_tour(quincunx_tour()))" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "image/png": "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\nKEqpEBbSo95XcuDAAe677z6uu+46PvjgA9txlFIhLGTPo6zK1VdfzUsvvcSwYcMAePjhh5k7d67l\nVEqpUFTTFqVXC/fWhogYX+zjs88+Y9CgQZ7r69at8xRPpZTyxsaNG0lOTq72wr1B36J0GzhwYIUB\nntOnT1tOpJSqK0KmUF5q4sSJiAi333677ShKqTAXkoXyyJEjvP/++3To0IG3337bdhylVJgLyULZ\nunVrRo0aRUREBAAdOnRg+vTpllMppYLV5s2b6dOnDxMnTqzR40NmMKcy69atY+zYsZw7dw6Aixcv\nUq9ePb/sSykVusqfFvSTn/yENWvWeG73ZjAnpAvlJfvhwoULREREEBkZWePzpZRS4cM9ABwREUGL\nFi3Iy8ur8POwG/W+EveqxTExMdSrV4/f/OY3lhMppWwzxuBwODyH6Grzqa9h06Istz86dOjAt99+\nG7B9KqWCk4hQUFBAo0aNEJF/6WnWqRblpQ4ePIiIkJqaajuKUirANmzYQGxsrKcoiggOh6NWh+PC\nrlBu3LiRvn370qpVK9auXWs7jlIqwB544AHOnz9P586dmTZtGo0bN671NiN9kCuo/PjHP2b79u2s\nXbuW1NRU3nvvPerXr09qaqoO8CgVxo4cOcL27ds9n7/19ddf+2zbYVco3a6++moAxo4dC8B//dd/\ncc8999iMpJTyozZt2ngujxs3zqfbDruut1vHjh0rzA3fvXu35URKKX978803Mcbwzjvv+HS7YVso\nL7Vo0SJd/FepMLNjx44Ko9nNmzf3y37Ctutd3jfffMOiRYtYu3atLv6rVBhZsWIFAI8++ihxcXGM\nHDnSL/sJu/Mor+See+7hlVde4e6776Zly5b8/ve/tx1JKVUDBw4cYMGCBXz22Wfs2rWr5gvy1rUp\njN7YunUrQ4YM8VzftGkT119/vcVESqmauNzc7Zpsp86ecH45gwcPrjDAc/bsWcuJlFI1NWXKFIwx\nNS6S1VGnCuWlRo8ejYgwefJk21GUUlXIy8urMHDTr1+/gO27TnW9yzt27Bj79u1j+vTpHDlypMbH\nOJRSgbF9+3b69+/PunXrqFevHoMHD8bhqF1bT49Reqlt27Z89913xMfHM3z4cNLT021HUkqVs2nT\nJn79619z+PBhzpw549NGjRZKL61bt44JEyZw5swZoOYfZ6mU8o/yAzcjR47kww8/9Om2tVBWQ2lp\n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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "heart_points = [Step(60, 50, Direction.UP), Step(50, 90, Direction.UP),\n", " Step(20, 70, Direction.UP), \n", " Step(-40, 90, Direction.UP), Step(-60, 80, Direction.UP), \n", " Step(0, 0, Direction.RIGHT)]\n", "\n", "heart_tour = ''\n", "current = Step(0, 0, Direction.RIGHT)\n", "\n", "for hp in heart_points:\n", " while not (current.x == hp.x and current.y == hp.y):\n", " s, proposed = seek(hp, current)\n", " heart_tour += s\n", " current = proposed\n", "\n", "plot_trace(trace_tour(heart_tour))\n", "\n", "def heart_tour_func(): return heart_tour" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def trim_some_mistakes(tour, mistake_limit):\n", " trimmed_tour = rw\n", " mistake_count = len(mistake_positions(trace_tour(trimmed_tour)))\n", " while len(mistake_positions(trace_tour(trimmed_tour))) > mistake_limit:\n", " trimmed_tour = trim_loop(trimmed_tour, random_mistake=True)\n", " return trimmed_tour" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "cross.txt\t small-squares.txt\t tours.txt\r\n", "large-squares.txt tours-open.txt\t tours-with-mistakes.txt\r\n", "quincunx.txt\t tours-random-walk.txt\r\n" ] } ], "source": [ "!ls *txt" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "113" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "valid_tours = [t.strip() for t in open('tours.txt').readlines() if valid(trace_tour(t.strip()))]\n", "valid_tours += [t.strip() for t in open('tours-with-mistakes.txt').readlines() if valid(trace_tour(t.strip()))]\n", "valid_tours += [t.strip() for t in open('tours-open.txt').readlines() if valid(trace_tour(t.strip()))]\n", "valid_tours += [t.strip() for t in open('tours-random-walk.txt').readlines() if valid(trace_tour(t.strip()))]\n", "\n", "len(valid_tours)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all(valid(trace_tour(t)) for t in valid_tours)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(87, 0)" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tours_with_mistakes = [t.strip() for t in open('tours-with-mistakes.txt').readlines() \n", " if not valid(trace_tour(t.strip()))]\n", "len(tours_with_mistakes)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "100" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tours_open = [t.strip() for t in open('tours-open.txt').readlines() \n", " if not valid(trace_tour(t.strip()))]\n", "len(tours_open)" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(84, 116)" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tours_walks_loops = [t.strip() for t in open('tours-random-walk.txt').readlines() \n", " if len(mistake_positions(trace_tour(t.strip()))) > 1]\n", "tours_walks_unloops = [t.strip() for t in open('tours-random-walk.txt').readlines() \n", " if len(mistake_positions(trace_tour(t.strip()))) == 1]\n", "len(tours_walks_loops), len(tours_walks_unloops)" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot_trace(trace_tour(tours_with_mistakes[31]))" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "65" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(1 for t in valid_tours if len(t) > 100)" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "48" ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "problem_set = [t for t in valid_tours if len(t) <= 100]\n", "len(problem_set)" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(48, 65)" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# problem_set += [t for t in valid_tours if len(t) > 100][0::2]\n", "valids_to_split = [t for t in valid_tours if len(t) > 100]\n", "len(problem_set), len(valids_to_split)" ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "148" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "problem_set += random.sample(tours_with_mistakes + tours_open + tours_walks_loops + tours_walks_unloops, 100)\n", "len(problem_set)" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2284" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "max(len(t) for t in valids_to_split)" ] }, { "cell_type": "code", "execution_count": 96, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1680" ] }, "execution_count": 96, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum(len(t) for t in problem_set if valid(trace_tour(t)))" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[(i, j) \n", " for i in range(len(problem_set)) \n", " for j in range(len(problem_set))\n", " if i != j\n", " if valid(trace_tour(problem_set[i] + problem_set[j]))]" ] }, { "cell_type": "code", "execution_count": 87, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "attempting 0\n", "** found split for 0\n", "attempting 1\n", "attempting 2\n", "attempting 3\n", "attempting 4\n", "attempting 5\n", "attempting 6\n", "attempting 7\n", "attempting 8\n", "attempting 9\n", "attempting 10\n", "attempting 11\n", "** found split for 11\n", "attempting 12\n", "attempting 13\n", "attempting 14\n", "attempting 15\n", "attempting 16\n", "attempting 17\n", "** found split for 17\n", "attempting 18\n", "attempting 19\n", "attempting 20\n", "attempting 21\n", "attempting 22\n", "attempting 23\n", "attempting 24\n", "attempting 25\n", "attempting 26\n", "attempting 27\n", "attempting 28\n", "attempting 29\n", "** found split for 29\n", "attempting 30\n", "attempting 31\n", "attempting 32\n", "attempting 33\n", "attempting 34\n", "** found split for 34\n", "attempting 35\n", "attempting 36\n", "attempting 37\n", "attempting 38\n", "** found split for 38\n", "attempting 39\n", "attempting 40\n", "attempting 41\n", "** found split for 41\n", "attempting 42\n", "attempting 43\n", "attempting 44\n", "attempting 45\n", "attempting 46\n", "attempting 47\n", "attempting 48\n", "** found split for 48\n", "attempting 49\n", "** found split for 49\n", "attempting 50\n", "** found split for 50\n", "attempting 51\n", "attempting 52\n", "attempting 53\n", "attempting 54\n", "attempting 55\n", "attempting 56\n", "attempting 57\n", "** found split for 57\n", "attempting 58\n", "attempting 59\n", "** found split for 59\n", "attempting 60\n", "attempting 61\n", "attempting 62\n", "** found split for 62\n", "attempting 63\n", "attempting 64\n" ] } ], "source": [ "split_valids = []\n", "unsplit_valids = []\n", "i = 0\n", "for v in valids_to_split:\n", " can_add = False\n", " attempts_remaining = 500\n", " print('attempting', i)\n", " while not can_add and attempts_remaining > 0:\n", " # print('splitting', i, 'attempt', attempts_remaining)\n", " attempts_remaining -= 1\n", "# split_pos = len(v) // 2 + random.randrange(10)\n", " split_pos = random.randint(20, len(v) - 40)\n", " vl = v[:split_pos]\n", " vr = v[split_pos:]\n", " can_add = True\n", " if valid(trace_tour(vr + vl)): can_add = False\n", " for other in problem_set:\n", " if can_add and valid(trace_tour(other + vl)): can_add = False\n", " if can_add and valid(trace_tour(other + vr)): can_add = False\n", " if can_add and valid(trace_tour(vl + other)): can_add = False\n", " if can_add and valid(trace_tour(vr + other)): can_add = False\n", " for other in split_valids:\n", " if can_add and valid(trace_tour(other + vl)): can_add = False\n", " if can_add and valid(trace_tour(other + vr)): can_add = False\n", " if can_add and valid(trace_tour(vl + other)): can_add = False\n", " if can_add and valid(trace_tour(vr + other)): can_add = False\n", " if can_add:\n", " split_valids += [vl, vr]\n", " print('** found split for', i)\n", " else:\n", " unsplit_valids += [v]\n", " i += 1" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['RLFLRFRLLFFRRLFFFRFLLFFFLFLRFRFFFRFLLFRFRFFFFRFFLFLFLRRFRFFFFLFFFFFFRLFLFLFRRFFFLFRFFRRFLLFFFRFRFFLRLFFLFRFFFLFFFFLRFFFFFLFFRLFFFFFFFFRFFFFFFRFFFFFFRLFFFLFRFRFLFFFFLFFFFFFLRFFFFLRLFFRFFRFLFFFFFFFLFLRFRLFFFFFFRLRFFLFFRFRLFFFRLFRLFFFLFFRLFLFFLFRRFFFLRFFLFFLRFFRFLRFFFLFFRFFLRFFFFFRFLFRLFRRFLFFFFRRFLRLFLFFFFFFLFFFFFFRFLRLFRLFLFFRFFLFFFFFFRRFFFLLFFRFFLRFFRRLLFRFFFFFFLFFFLFFFLRFFLFRRFLRLRFFFRFLFFFFFRLRFLFLFFRRFLFFFRLLFRLLRRLFLFRFFRFLFFFFRFFFLFFLFRFRFLRFFFFFLRFLFLFFFRFFFLFRRFLFLFFLFFRFFFFFFRRFLFFRFFFLRFLFFFFFFFFLRFFRRLFFFFFLRLFFFFFRLFFFFFFFFFFFLRFFLFRFFFFLRLLFRFRLRFFFLFLFFFRFFFFFRFFRFFLFRLLFRFLRFFFFLFFLFRFFFRLFFRRFLRLFLFFFLRFLRFFFFFFLFFFRFRFFFFFF',\n", " 'LLRRLFFFFFFFLFFFRFFFFFFFLLRFFRFFFRFFFLLFFRLRFFFLFRFFRFLFRFFFRFLLFFLFFFFFFRRFLRFRLFFFLFFFFFFFFLFFRLFFFFRFFFRFFFLFFFRLR',\n", " 'RLFFFLFFFRFFFRFFLFFLFFRFFFFLFFRFRFFFRFLLRLFFFFLFFRFRFFRLRFFLFLFFRFFLFLRFRFFFLFFFLFRFLFFFFRRLFRFLFFFFFFLFRFFLFRFFFFFFFFLLFRFFFLFRFFRFFFFFFFRRLFLLRFFRLFRLFFFLFFRFFRFRFLFFLFFRFFFRLLFFFLFFFLRFFFFFFRLFRFFLFFFFRLFFRRLLFFFFLRLFFFFRFRFFLFFFFFFFFLFFRRFFFFLFFFFLFLFFRFFFRFFFFFRLRFFFFFRFLFFFLFFFFLFFFFFRFFFFFFLFFFRFLLFFFRFRFFFFLRFFFRLFFRLFFRFLRFFFFFFFFFFLRFLFFFFFFRLFFFFLRLFRLFRLFFFRFLRFFLRFLFFFFFFFFFFFFFFLFFRLFFFRLFFFFFFFRFLRFRLFFFRLFRFFFFFFFFFFFFFLFFFFFFFFFFFLLRFFLFFRLFRFLRFFFLRFFFFFFRFFRLFRLFFFLRFFFFRFFRFFFFFFFFFFLFFFFFFLFLRFFFFRFLLFRFLRFFRFFFLFRFLFRLFFFFFFFFLFLFRFFFFLFFRFFFFRLRRFFLLFFRFLFRFFFFFFLRFFFFFRFFFRFRFLFFLFLRLRLFFLRFFLFFRFFFFLFFFFFLFFFFFRLFFFFRFFFFFRFFFFFFFFFFRFLFFFFFLRLLFFFFRFFFRFLRFFLFFFFLFRRFLFFFFLRFFRLFFLFFFFLRFFLFRRFFFFRFLFFFRFL',\n", " 'FLFFRRFFFFRLLFFFLFLLRRFFFRFFFLRFFFLFLFFRRFFFFLLFRFFLFRFFRFFFRFLFFFFRLFFFLRFFFFRFRLFFRLLFFFFFF']" ] }, "execution_count": 97, "metadata": {}, "output_type": "execute_result" } ], "source": [ "split_valids[:4]" ] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 1),\n", " (2, 3),\n", " (4, 5),\n", " (6, 7),\n", " (8, 9),\n", " (10, 11),\n", " (12, 13),\n", " (14, 15),\n", " (16, 17),\n", " (18, 19),\n", " (20, 21),\n", " (22, 23),\n", " (24, 25)]" ] }, "execution_count": 98, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[(i, j) \n", " for i in range(len(split_valids)) \n", " for j in range(len(split_valids))\n", " if i != j\n", " if valid(trace_tour(split_valids[i] + split_valids[j]))]" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "226" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "problem_set += (split_valids + unsplit_valids)\n", "len(problem_set)" ] }, { "cell_type": "code", "execution_count": 100, "metadata": { "collapsed": true }, "outputs": [], "source": [ "with open('06-tours.txt', 'w') as f:\n", " f.writelines(t + '\\n' for t in random.sample(problem_set, len(problem_set)))" ] }, { "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 }