Removing files from data analysis directory
[ou-summer-of-code-2017.git] / 06-tour-shapes / tour-creation-for-background.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "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",
8 "1. which tours are closed?\n",
9 "2. what is the area enclosed by the tour?"
10 ]
11 },
12 {
13 "cell_type": "code",
14 "execution_count": 1,
15 "metadata": {
16 "collapsed": true
17 },
18 "outputs": [],
19 "source": [
20 "import collections\n",
21 "import enum\n",
22 "import random\n",
23 "import os\n",
24 "\n",
25 "import matplotlib.pyplot as plt\n",
26 "%matplotlib inline"
27 ]
28 },
29 {
30 "cell_type": "code",
31 "execution_count": 2,
32 "metadata": {
33 "collapsed": true
34 },
35 "outputs": [],
36 "source": [
37 "class Direction(enum.Enum):\n",
38 " UP = 1\n",
39 " RIGHT = 2\n",
40 " DOWN = 3\n",
41 " LEFT = 4\n",
42 " \n",
43 "turn_lefts = {Direction.UP: Direction.LEFT, Direction.LEFT: Direction.DOWN,\n",
44 " Direction.DOWN: Direction.RIGHT, Direction.RIGHT: Direction.UP}\n",
45 "\n",
46 "turn_rights = {Direction.UP: Direction.RIGHT, Direction.RIGHT: Direction.DOWN,\n",
47 " Direction.DOWN: Direction.LEFT, Direction.LEFT: Direction.UP}\n",
48 "\n",
49 "def turn_left(d):\n",
50 " return turn_lefts[d]\n",
51 "\n",
52 "def turn_right(d):\n",
53 " return turn_rights[d]\n"
54 ]
55 },
56 {
57 "cell_type": "code",
58 "execution_count": 3,
59 "metadata": {
60 "collapsed": true
61 },
62 "outputs": [],
63 "source": [
64 "Step = collections.namedtuple('Step', ['x', 'y', 'dir'])\n",
65 "Mistake = collections.namedtuple('Mistake', ['i', 'step'])"
66 ]
67 },
68 {
69 "cell_type": "code",
70 "execution_count": 4,
71 "metadata": {
72 "collapsed": true
73 },
74 "outputs": [],
75 "source": [
76 "def advance(step, d):\n",
77 " if d == Direction.UP:\n",
78 " return Step(step.x, step.y+1, d)\n",
79 " elif d == Direction.DOWN:\n",
80 " return Step(step.x, step.y-1, d)\n",
81 " elif d == Direction.LEFT:\n",
82 " return Step(step.x-1, step.y, d)\n",
83 " elif d == Direction.RIGHT:\n",
84 " return Step(step.x+1, step.y, d)"
85 ]
86 },
87 {
88 "cell_type": "code",
89 "execution_count": 5,
90 "metadata": {
91 "collapsed": true
92 },
93 "outputs": [],
94 "source": [
95 "def trace_tour(tour, startx=0, starty=0, startdir=Direction.RIGHT):\n",
96 " current = Step(startx, starty, startdir)\n",
97 " trace = [current]\n",
98 " for s in tour:\n",
99 " if s == 'F':\n",
100 " current = advance(current, current.dir)\n",
101 " elif s == 'L':\n",
102 " current = advance(current, turn_left(current.dir))\n",
103 " elif s == 'R':\n",
104 " current = advance(current, turn_right(current.dir))\n",
105 " trace += [current]\n",
106 " return trace "
107 ]
108 },
109 {
110 "cell_type": "code",
111 "execution_count": 6,
112 "metadata": {
113 "collapsed": true
114 },
115 "outputs": [],
116 "source": [
117 "def positions(trace):\n",
118 " return [(s.x, s.y) for s in trace]"
119 ]
120 },
121 {
122 "cell_type": "code",
123 "execution_count": 7,
124 "metadata": {
125 "collapsed": true
126 },
127 "outputs": [],
128 "source": [
129 "def valid(trace):\n",
130 " return (trace[-1].x == 0 \n",
131 " and trace[-1].y == 0 \n",
132 " and len(set(positions(trace))) + 1 == len(trace))"
133 ]
134 },
135 {
136 "cell_type": "code",
137 "execution_count": 8,
138 "metadata": {
139 "collapsed": true
140 },
141 "outputs": [],
142 "source": [
143 "def chunks(items, n=2):\n",
144 " return [items[i:i+n] for i in range(len(items) - n + 1)]"
145 ]
146 },
147 {
148 "cell_type": "markdown",
149 "metadata": {},
150 "source": [
151 "Using the [Shoelace formula](https://en.wikipedia.org/wiki/Shoelace_formula)"
152 ]
153 },
154 {
155 "cell_type": "code",
156 "execution_count": 9,
157 "metadata": {
158 "collapsed": true
159 },
160 "outputs": [],
161 "source": [
162 "def shoelace(trace):\n",
163 " return abs(sum(s.x * t.y - t.x * s.y for s, t in chunks(trace, 2))) // 2"
164 ]
165 },
166 {
167 "cell_type": "code",
168 "execution_count": 10,
169 "metadata": {
170 "collapsed": true
171 },
172 "outputs": [],
173 "source": [
174 "def step(s, current):\n",
175 " if s == 'F':\n",
176 " return advance(current, current.dir)\n",
177 " elif s == 'L':\n",
178 " return advance(current, turn_left(current.dir))\n",
179 " elif s == 'R':\n",
180 " return advance(current, turn_right(current.dir))\n",
181 " else:\n",
182 " raise ValueError"
183 ]
184 },
185 {
186 "cell_type": "code",
187 "execution_count": 11,
188 "metadata": {
189 "collapsed": true
190 },
191 "outputs": [],
192 "source": [
193 "def valid_prefix(tour):\n",
194 " current = Step(0, 0, Direction.RIGHT)\n",
195 " prefix = []\n",
196 " posns = []\n",
197 " for s in tour:\n",
198 " current = step(s, current)\n",
199 " prefix += [s]\n",
200 " if (current.x, current.y) in posns:\n",
201 " return ''\n",
202 " elif current.x == 0 and current.y == 0: \n",
203 " return ''.join(prefix)\n",
204 " posns += [(current.x, current.y)]\n",
205 " if current.x == 0 and current.y == 0:\n",
206 " return ''.join(prefix)\n",
207 " else:\n",
208 " return ''"
209 ]
210 },
211 {
212 "cell_type": "code",
213 "execution_count": 12,
214 "metadata": {
215 "collapsed": true
216 },
217 "outputs": [],
218 "source": [
219 "def mistake_positions(trace, debug=False):\n",
220 " mistakes = []\n",
221 " current = trace[0]\n",
222 " posns = [(0, 0)]\n",
223 " for i, current in enumerate(trace[1:]):\n",
224 " if (current.x, current.y) in posns:\n",
225 " if debug: print(i, current)\n",
226 " mistakes += [Mistake(i+1, current)]\n",
227 " posns += [(current.x, current.y)]\n",
228 " if (current.x, current.y) == (0, 0):\n",
229 " return mistakes[:-1]\n",
230 " else:\n",
231 " return mistakes + [Mistake(len(trace)+1, current)]"
232 ]
233 },
234 {
235 "cell_type": "code",
236 "execution_count": 13,
237 "metadata": {
238 "collapsed": true
239 },
240 "outputs": [],
241 "source": [
242 "def returns_to_origin(mistake_positions):\n",
243 " return [i for i, m in mistake_positions\n",
244 " if (m.x, m.y) == (0, 0)]"
245 ]
246 },
247 {
248 "cell_type": "code",
249 "execution_count": 14,
250 "metadata": {
251 "collapsed": true
252 },
253 "outputs": [],
254 "source": [
255 "def random_walk(steps=1000):\n",
256 " return ''.join(random.choice('FFLR') for _ in range(steps))"
257 ]
258 },
259 {
260 "cell_type": "code",
261 "execution_count": 15,
262 "metadata": {
263 "collapsed": true
264 },
265 "outputs": [],
266 "source": [
267 "def bounds(trace):\n",
268 " return (max(s.x for s in trace),\n",
269 " max(s.y for s in trace),\n",
270 " min(s.x for s in trace),\n",
271 " min(s.y for s in trace))"
272 ]
273 },
274 {
275 "cell_type": "code",
276 "execution_count": 1,
277 "metadata": {},
278 "outputs": [
279 {
280 "ename": "NameError",
281 "evalue": "name 'Direction' is not defined",
282 "output_type": "error",
283 "traceback": [
284 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
285 "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
286 "\u001b[0;32m<ipython-input-1-f5ea591d6161>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m plot_wh = {Direction.UP: (0, 1), Direction.LEFT: (-1, 0),\n\u001b[0m\u001b[1;32m 2\u001b[0m Direction.DOWN: (0, -1), Direction.RIGHT: (1, 0)}\n",
287 "\u001b[0;31mNameError\u001b[0m: name 'Direction' is not defined"
288 ]
289 }
290 ],
291 "source": [
292 "plot_wh = {Direction.UP: (0, 1), Direction.LEFT: (-1, 0),\n",
293 " Direction.DOWN: (0, -1), Direction.RIGHT: (1, 0)}"
294 ]
295 },
296 {
297 "cell_type": "code",
298 "execution_count": 16,
299 "metadata": {
300 "collapsed": true
301 },
302 "outputs": [],
303 "source": [
304 "def plot_trace(trace, colour='k', highlight_start=True,\n",
305 " xybounds=None, fig=None, subplot_details=None, filename=None):\n",
306 " plt.axis('on')\n",
307 " plt.axes().set_aspect('equal')\n",
308 " \n",
309 " if highlight_start:\n",
310 " plt.axes().add_patch(plt.Circle((trace[0].x, trace[0].y), 0.2, color=colour))\n",
311 " \n",
312 " for s, t in chunks(trace, 2):\n",
313 " w, h = plot_wh[t.dir]\n",
314 " 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",
315 " xh, yh, xl, yl = bounds(trace)\n",
316 " if xybounds is not None: \n",
317 " bxh, byh, bxl, byl = xybounds\n",
318 " plt.xlim([min(xl, bxl)-1, max(xh, bxh)+1])\n",
319 " plt.ylim([min(yl, byl)-1, max(yh, byh)+1])\n",
320 " else:\n",
321 " plt.xlim([xl-1, xh+1])\n",
322 " plt.ylim([yl-1, yh+1])\n",
323 " if filename:\n",
324 " plt.savefig(filename)"
325 ]
326 },
327 {
328 "cell_type": "code",
329 "execution_count": 17,
330 "metadata": {
331 "collapsed": true
332 },
333 "outputs": [],
334 "source": [
335 "def trim_loop(tour):\n",
336 " trace = trace_tour(tour)\n",
337 " mistakes = mistake_positions(trace)\n",
338 " end_mistake_index = 0\n",
339 "# 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",
340 " # while this mistake extends to the next step in the trace...\n",
341 " while (mistakes[end_mistake_index].i + 1 < len(trace) and \n",
342 " end_mistake_index + 1 < len(mistakes) and\n",
343 " mistakes[end_mistake_index].i + 1 == \n",
344 " mistakes[end_mistake_index + 1].i):\n",
345 "# 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",
346 " # push this mistake finish point later\n",
347 " end_mistake_index += 1\n",
348 " mistake = mistakes[end_mistake_index]\n",
349 " \n",
350 " # find the first location that mentions where this mistake ends (which the point where the loop starts)\n",
351 " mistake_loop_start = max(i for i, loc in enumerate(trace[:mistake.i])\n",
352 " if (loc.x, loc.y) == (mistake.step.x, mistake.step.y))\n",
353 "# print('Dealing with mistake from', mistake_loop_start, 'to', mistake.i, ', trace has len', len(trace))\n",
354 " \n",
355 " # direction before entering the loop\n",
356 " direction_before = trace[mistake_loop_start].dir\n",
357 " \n",
358 " # find the new instruction to turn from heading before the loop to heading after the loop\n",
359 " new_instruction = 'F'\n",
360 " if (mistake.i + 1) < len(trace):\n",
361 " if turn_left(direction_before) == trace[mistake.i + 1].dir:\n",
362 " new_instruction = 'L'\n",
363 " if turn_right(direction_before) == trace[mistake.i + 1].dir:\n",
364 " new_instruction = 'R'\n",
365 "# if (mistake.i + 1) < len(trace):\n",
366 "# print('turning from', direction_before, 'to', trace[mistake.i + 1].dir, 'with', new_instruction )\n",
367 "# else:\n",
368 "# print('turning from', direction_before, 'to BEYOND END', 'with', new_instruction )\n",
369 " return tour[:mistake_loop_start] + new_instruction + tour[mistake.i+1:]\n",
370 "# return mistake, mistake_loop_start, trace[mistake_loop_start-2:mistake_loop_start+8]"
371 ]
372 },
373 {
374 "cell_type": "code",
375 "execution_count": 18,
376 "metadata": {
377 "collapsed": true
378 },
379 "outputs": [],
380 "source": [
381 "def trim_all_loops(tour, mistake_reduction_attempt_limit=10):\n",
382 " trace = trace_tour(tour)\n",
383 " mistake_limit = 1\n",
384 " if trace[-1].x == 0 and trace[-1].y == 0:\n",
385 " mistake_limit = 0\n",
386 " mistakes = mistake_positions(trace)\n",
387 " \n",
388 " old_mistake_count = len(mistakes)\n",
389 " mistake_reduction_tries = 0\n",
390 " \n",
391 " while len(mistakes) > mistake_limit and mistake_reduction_tries < mistake_reduction_attempt_limit:\n",
392 " tour = trim_loop(tour)\n",
393 " trace = trace_tour(tour)\n",
394 " mistakes = mistake_positions(trace)\n",
395 " if len(mistakes) < old_mistake_count:\n",
396 " old_mistake_count = len(mistakes)\n",
397 " mistake_reduction_tries = 0\n",
398 " else:\n",
399 " mistake_reduction_tries += 1\n",
400 " if mistake_reduction_tries >= mistake_reduction_attempt_limit:\n",
401 " return ''\n",
402 " else:\n",
403 " return tour"
404 ]
405 },
406 {
407 "cell_type": "code",
408 "execution_count": 19,
409 "metadata": {
410 "collapsed": true
411 },
412 "outputs": [],
413 "source": [
414 "def reverse_tour(tour):\n",
415 " def swap(tour_step):\n",
416 " if tour_step == 'R':\n",
417 " return 'L'\n",
418 " elif tour_step == 'L':\n",
419 " return 'R'\n",
420 " else:\n",
421 " return tour_step\n",
422 " \n",
423 " return ''.join(swap(s) for s in reversed(tour))"
424 ]
425 },
426 {
427 "cell_type": "code",
428 "execution_count": 20,
429 "metadata": {
430 "collapsed": true
431 },
432 "outputs": [],
433 "source": [
434 "def wander_near(locus, current, limit=10):\n",
435 " valid_proposal = False\n",
436 " while not valid_proposal:\n",
437 " s = random.choice('FFFRL')\n",
438 " if s == 'F':\n",
439 " proposed = advance(current, current.dir)\n",
440 " elif s == 'L':\n",
441 " proposed = advance(current, turn_left(current.dir))\n",
442 " elif s == 'R':\n",
443 " proposed = advance(current, turn_right(current.dir))\n",
444 " if abs(proposed.x - locus.x) < limit and abs(proposed.y - locus.y) < limit:\n",
445 " valid_proposal = True\n",
446 "# print('At {} going to {} by step {} to {}'.format(current, locus, s, proposed))\n",
447 " return s, proposed"
448 ]
449 },
450 {
451 "cell_type": "code",
452 "execution_count": 21,
453 "metadata": {
454 "collapsed": true
455 },
456 "outputs": [],
457 "source": [
458 "def seek(goal, current):\n",
459 " dx = current.x - goal.x\n",
460 " dy = current.y - goal.y\n",
461 "\n",
462 " if dx < 0 and abs(dx) > abs(dy): # to the left\n",
463 " side = 'left'\n",
464 " if current.dir == Direction.RIGHT:\n",
465 " s = 'F'\n",
466 " elif current.dir == Direction.UP:\n",
467 " s = 'R'\n",
468 " else:\n",
469 " s = 'L'\n",
470 " elif dx > 0 and abs(dx) > abs(dy): # to the right\n",
471 " side = 'right'\n",
472 " if current.dir == Direction.LEFT:\n",
473 " s = 'F'\n",
474 " elif current.dir == Direction.UP:\n",
475 " s = 'L'\n",
476 " else:\n",
477 " s = 'R'\n",
478 " elif dy > 0 and abs(dx) <= abs(dy): # above\n",
479 " side = 'above'\n",
480 " if current.dir == Direction.DOWN:\n",
481 " s = 'F'\n",
482 " elif current.dir == Direction.RIGHT:\n",
483 " s = 'R'\n",
484 " else:\n",
485 " s = 'L'\n",
486 " else: # below\n",
487 " side = 'below'\n",
488 " if current.dir == Direction.UP:\n",
489 " s = 'F'\n",
490 " elif current.dir == Direction.LEFT:\n",
491 " s = 'R'\n",
492 " else:\n",
493 " s = 'L'\n",
494 " if s == 'F':\n",
495 " proposed = advance(current, current.dir)\n",
496 " elif s == 'L':\n",
497 " proposed = advance(current, turn_left(current.dir))\n",
498 " elif s == 'R':\n",
499 " proposed = advance(current, turn_right(current.dir))\n",
500 " \n",
501 "# print('At {} going to {}, currently {}, by step {} to {}'.format(current, goal, side, s, proposed))\n",
502 "\n",
503 " return s, proposed"
504 ]
505 },
506 {
507 "cell_type": "code",
508 "execution_count": 22,
509 "metadata": {
510 "collapsed": true
511 },
512 "outputs": [],
513 "source": [
514 "def guided_walk(loci, locus_limit=5, wander_limit=10, seek_step_limit=20):\n",
515 " trail = ''\n",
516 " current = Step(0, 0, Direction.RIGHT) \n",
517 " l = 0\n",
518 " finished = False\n",
519 " while not finished:\n",
520 " if abs(current.x - loci[l].x) < locus_limit and abs(current.y - loci[l].y) < locus_limit:\n",
521 " l += 1\n",
522 " if l == len(loci) - 1:\n",
523 " finished = True\n",
524 " s, proposed = wander_near(loci[l], current, limit=wander_limit)\n",
525 " trail += s\n",
526 " current = proposed\n",
527 "# print('!! Finished loci')\n",
528 " seek_steps = 0\n",
529 " while not (current.x == loci[l].x and current.y == loci[l].y) and seek_steps < seek_step_limit:\n",
530 "# error = max(abs(current.x - loci[l].x), abs(current.y - loci[l].y))\n",
531 "# s, proposed = wander_near(loci[l], current, limit=error+1)\n",
532 " s, proposed = seek(loci[l], current)\n",
533 " trail += s\n",
534 " current = proposed\n",
535 " seek_steps += 1\n",
536 " if seek_steps >= seek_step_limit:\n",
537 " return ''\n",
538 " else:\n",
539 " return trail"
540 ]
541 },
542 {
543 "cell_type": "code",
544 "execution_count": 24,
545 "metadata": {
546 "collapsed": true
547 },
548 "outputs": [],
549 "source": [
550 "def square_tour(a=80):\n",
551 " \"a is width of square\"\n",
552 " return ('F' * a + 'L') * 4"
553 ]
554 },
555 {
556 "cell_type": "code",
557 "execution_count": 25,
558 "metadata": {
559 "collapsed": true
560 },
561 "outputs": [],
562 "source": [
563 "def cross_tour(a=50, b=40):\n",
564 " \"a is width of cross arm, b is length of cross arm\"\n",
565 " return ('F' * a + 'L' + 'F' * b + 'R' + 'F' * b + 'L') * 4"
566 ]
567 },
568 {
569 "cell_type": "code",
570 "execution_count": 26,
571 "metadata": {
572 "collapsed": true
573 },
574 "outputs": [],
575 "source": [
576 "def quincunx_tour(a=60, b=30, c=50):\n",
577 " \"a is length of indent, b is indent/outdent distance, c is outdent outer length\"\n",
578 " return ('F' * a + 'R' + 'F' * b + 'L' + 'F' * c + 'L' + 'F' * c + 'L' + 'F' * b + 'R') * 4\n"
579 ]
580 },
581 {
582 "cell_type": "code",
583 "execution_count": 27,
584 "metadata": {
585 "collapsed": true
586 },
587 "outputs": [],
588 "source": [
589 "heart_points = [Step(60, 50, Direction.UP), Step(50, 90, Direction.UP),\n",
590 " Step(20, 70, Direction.UP), \n",
591 " Step(-40, 90, Direction.UP), Step(-60, 80, Direction.UP), \n",
592 " Step(0, 0, Direction.RIGHT)]\n",
593 "\n",
594 "heart_tour = ''\n",
595 "current = Step(0, 0, Direction.RIGHT)\n",
596 "\n",
597 "for hp in heart_points:\n",
598 " while not (current.x == hp.x and current.y == hp.y):\n",
599 " s, proposed = seek(hp, current)\n",
600 " heart_tour += s\n",
601 " current = proposed\n",
602 "\n",
603 "def heart_tour_func(): return heart_tour"
604 ]
605 },
606 {
607 "cell_type": "code",
608 "execution_count": 28,
609 "metadata": {
610 "collapsed": true
611 },
612 "outputs": [],
613 "source": [
614 "# success_count = 0\n",
615 "# while success_count <= 20:\n",
616 "# lc = trace_tour(square_tour(a=10))\n",
617 "# rw = guided_walk(lc, wander_limit=4, locus_limit=2)\n",
618 "# if rw:\n",
619 "# rw_trimmed = trim_all_loops(rw)\n",
620 "# if len(rw_trimmed) > 10:\n",
621 "# with open('small-squares.txt', 'a') as f:\n",
622 "# f.write(rw_trimmed + '\\n')\n",
623 "# success_count += 1"
624 ]
625 },
626 {
627 "cell_type": "code",
628 "execution_count": 29,
629 "metadata": {
630 "collapsed": true
631 },
632 "outputs": [],
633 "source": [
634 "# success_count = 0\n",
635 "# while success_count <= 20:\n",
636 "# lc = trace_tour(square_tour())\n",
637 "# rw = guided_walk(lc)\n",
638 "# if rw:\n",
639 "# rw_trimmed = trim_all_loops(rw)\n",
640 "# if len(rw_trimmed) > 10:\n",
641 "# with open('large-squares.txt', 'a') as f:\n",
642 "# f.write(rw_trimmed + '\\n')\n",
643 "# success_count += 1"
644 ]
645 },
646 {
647 "cell_type": "code",
648 "execution_count": 30,
649 "metadata": {
650 "collapsed": true
651 },
652 "outputs": [],
653 "source": [
654 "# success_count = 0\n",
655 "# while success_count <= 20:\n",
656 "# lc = trace_tour(cross_tour())\n",
657 "# rw = guided_walk(lc)\n",
658 "# if rw:\n",
659 "# rw_trimmed = trim_all_loops(rw)\n",
660 "# if len(rw_trimmed) > 10:\n",
661 "# with open('cross.txt', 'a') as f:\n",
662 "# f.write(rw_trimmed + '\\n')\n",
663 "# success_count += 1"
664 ]
665 },
666 {
667 "cell_type": "code",
668 "execution_count": 31,
669 "metadata": {
670 "collapsed": true
671 },
672 "outputs": [],
673 "source": [
674 "# success_count = 0\n",
675 "# while success_count <= 20:\n",
676 "# lc = trace_tour(quincunx_tour())\n",
677 "# rw = guided_walk(lc)\n",
678 "# if rw:\n",
679 "# rw_trimmed = trim_all_loops(rw)\n",
680 "# if len(rw_trimmed) > 10:\n",
681 "# with open('quincunx.txt', 'a') as f:\n",
682 "# f.write(rw_trimmed + '\\n')\n",
683 "# success_count += 1"
684 ]
685 },
686 {
687 "cell_type": "code",
688 "execution_count": 32,
689 "metadata": {
690 "collapsed": true
691 },
692 "outputs": [],
693 "source": [
694 "patterns = [square_tour, cross_tour, quincunx_tour, heart_tour_func]\n",
695 "tours_filename = 'tours.txt'\n",
696 "\n",
697 "try:\n",
698 " os.remove(tours_filename)\n",
699 "except OSError:\n",
700 " pass\n",
701 "\n",
702 "success_count = 0\n",
703 "while success_count < 100:\n",
704 " lc = trace_tour(random.choice(patterns)())\n",
705 " rw = guided_walk(lc)\n",
706 " if rw:\n",
707 " rw_trimmed = trim_all_loops(rw)\n",
708 " if len(rw_trimmed) > 10:\n",
709 " with open(tours_filename, 'a') as f:\n",
710 " f.write(rw_trimmed + '\\n')\n",
711 " success_count += 1"
712 ]
713 },
714 {
715 "cell_type": "code",
716 "execution_count": null,
717 "metadata": {
718 "collapsed": true
719 },
720 "outputs": [],
721 "source": []
722 }
723 ],
724 "metadata": {
725 "kernelspec": {
726 "display_name": "Python 3",
727 "language": "python",
728 "name": "python3"
729 },
730 "language_info": {
731 "codemirror_mode": {
732 "name": "ipython",
733 "version": 3
734 },
735 "file_extension": ".py",
736 "mimetype": "text/x-python",
737 "name": "python",
738 "nbconvert_exporter": "python",
739 "pygments_lexer": "ipython3",
740 "version": "3.5.2+"
741 }
742 },
743 "nbformat": 4,
744 "nbformat_minor": 2
745 }