Changed day 9 blurb
[ou-summer-of-code-2017.git] / 02-lifts / part2-brainfuck.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 121,
6 "metadata": {
7 "collapsed": true
8 },
9 "outputs": [],
10 "source": [
11 "#!/usr/bin/python\n",
12 "#\n",
13 "# Brainfuck Interpreter\n",
14 "# Copyright 2011 Sebastian Kaspari\n",
15 "#\n",
16 "# Usage: ./brainfuck.py [FILE]\n",
17 "\n",
18 "import sys\n",
19 "\n",
20 "def execute(filename):\n",
21 " f = open(filename, \"r\")\n",
22 " evaluate(f.read())\n",
23 " f.close()\n",
24 "\n",
25 "\n",
26 "def evaluate(code, inp=None, debug=False):\n",
27 " code = cleanup(list(code))\n",
28 " bracemap = buildbracemap(code)\n",
29 "\n",
30 " cells, codeptr, cellptr = [0], 0, 0\n",
31 " inputptr = 0\n",
32 "\n",
33 " try:\n",
34 " while codeptr < len(code):\n",
35 " command = code[codeptr]\n",
36 " \n",
37 " if debug:\n",
38 " print(command, cellptr, cells)\n",
39 "\n",
40 " if command == \">\":\n",
41 " cellptr += 1\n",
42 " if cellptr == len(cells): cells.append(0)\n",
43 "\n",
44 " if command == \"<\":\n",
45 " cellptr = 0 if cellptr <= 0 else cellptr - 1\n",
46 "\n",
47 " if command == \"+\":\n",
48 " cells[cellptr] = cells[cellptr] + 1 if cells[cellptr] < 255 else 0\n",
49 "\n",
50 " if command == \"-\":\n",
51 " cells[cellptr] = cells[cellptr] - 1 if cells[cellptr] > 0 else 255\n",
52 "\n",
53 " if command == \"[\" and cells[cellptr] == 0: codeptr = bracemap[codeptr]\n",
54 " if command == \"]\" and cells[cellptr] != 0: codeptr = bracemap[codeptr]\n",
55 " if command == \".\": sys.stdout.write(chr(cells[cellptr]))\n",
56 " if command == \",\": \n",
57 " if inp is not None:\n",
58 " if inputptr >= len(inp):\n",
59 " raise EOFError\n",
60 " cells[cellptr] = ord(inp[inputptr])\n",
61 " inputptr += 1\n",
62 " else:\n",
63 " cells[cellptr] = ord(getch.getch())\n",
64 "\n",
65 " codeptr += 1\n",
66 " except EOFError:\n",
67 " pass\n",
68 " return cells, codeptr, cellptr\n",
69 "\n",
70 "\n",
71 "def cleanup(code):\n",
72 " return list(filter(lambda x: x in ['.', ',', '[', ']', '<', '>', '+', '-'], code))\n",
73 "\n",
74 "\n",
75 "def buildbracemap(code):\n",
76 " temp_bracestack, bracemap = [], {}\n",
77 "\n",
78 " for position, command in enumerate(code):\n",
79 " if command == \"[\": temp_bracestack.append(position)\n",
80 " if command == \"]\":\n",
81 " start = temp_bracestack.pop()\n",
82 " bracemap[start] = position\n",
83 " bracemap[position] = start\n",
84 " return bracemap\n",
85 "\n",
86 "\n",
87 "# def main():\n",
88 "# if len(sys.argv) == 2: execute(sys.argv[1])\n",
89 "# else: print(\"Usage:\", sys.argv[0], \"filename\")\n",
90 "\n",
91 "# if __name__ == \"__main__\": main()\n"
92 ]
93 },
94 {
95 "cell_type": "code",
96 "execution_count": 128,
97 "metadata": {},
98 "outputs": [
99 {
100 "data": {
101 "text/plain": [
102 "(118, 94, 61)"
103 ]
104 },
105 "execution_count": 128,
106 "metadata": {},
107 "output_type": "execute_result"
108 }
109 ],
110 "source": [
111 "ord('v'), ord('^'), ord('=')"
112 ]
113 },
114 {
115 "cell_type": "markdown",
116 "metadata": {},
117 "source": [
118 "```\n",
119 "set cell 1 to 61\n",
120 "set cell 2 to 94-61=33\n",
121 "set cell 3 to 118-94=24\n",
122 "copy cell 1 into cell 0, using cell 4\n",
123 "\n",
124 "cell 5 for ???? currently at an exit: 1 if at an exit, 0 otherwise\n",
125 "\n",
126 "set cell 6 to 0 (current level)\n",
127 "set cell 7 to for non-negative flag: 0 for +ive, 1 for -ive, 0 for zero.\n",
128 "set cell 8 to 0 (highest exit)\n",
129 "cell 9 for input\n",
130 "cell 10 for whether input has been dealt with: 0 for yes, 1 for no\n",
131 "reserve cell 11 and higher for scratch\n",
132 "\n",
133 "read character into cell 9\n",
134 "while cell 9 != 0\n",
135 " subtract cell 0 from cell 9\n",
136 " if cell 9 == 0 we're at an exit\n",
137 " if cell 7 != 0\n",
138 " if cell 6 is higher then cell 7\n",
139 " copy cell 6 into cell 7\n",
140 " else\n",
141 " subtract cell 2 from cell 9\n",
142 " if cell 9 == 0 we're going up\n",
143 " increment cell 6\n",
144 " if cell 6 is zero\n",
145 " if cell 7 != 0\n",
146 " decrement cell 7\n",
147 " else\n",
148 " decrement cell 6\n",
149 " \n",
150 " copy cell 1 into cell 0 using cell 4\n",
151 " read character into cell 6\n",
152 " \n",
153 "output cell 7\n",
154 "```\n",
155 "\n",
156 "```\n",
157 "read character into cell 9\n",
158 "set cell 10 to 1\n",
159 "while cell 9 != 0\n",
160 " subtract cell 0 from cell 9\n",
161 " while cell 9 == 0 we're not at an exit\n",
162 " subtract cell 1 from cell 9\n",
163 " set cell 10 to 0\n",
164 " while cell 9 == 0 we're going up\n",
165 " increment cell 6\n",
166 " increment cell 6\n",
167 " while cell 6 is zero\n",
168 " set cell 7 to zero \n",
169 " decrement cell 6\n",
170 " while cell 10 != 0 (at an exit)\n",
171 " while cell 7 != 0 (above ground level)\n",
172 " copy cell 8 to cell 11 using cell 13 (highest)\n",
173 " copy cell 6 to cell 12 using cell 13 (current)\n",
174 " set cell 14 to 0\n",
175 " while cell 11 != 0\n",
176 " increment cell 14\n",
177 " while cell 12 != 0\n",
178 " decrement cell 12\n",
179 " set cell 14 to 0, keep pointer at 14 (this exits the inner loop)\n",
180 " decrement cell 11\n",
181 " add cell 12 to cell 8\n",
182 " set cell 7 to 0\n",
183 " set cell 10 to 0\n",
184 " \n",
185 " \n",
186 " \n",
187 " \n",
188 " if cell 7 != 0\n",
189 " if cell 6 is higher then cell 7\n",
190 " copy cell 6 into cell 7\n",
191 " else\n",
192 " \n",
193 " copy cell 1 into cell 0 using cell 4\n",
194 " read character into cell 6\n",
195 "```\n",
196 "\n",
197 "```\n",
198 "Need a flag to say if below ground level, and only update the highest exit level if positive\n",
199 "Hold highest exit in unary, as seq 10, 9, 8... 1, 0.\n",
200 "When get a new exit, set level in leftmost cell, rebuild the sequence.\n",
201 "If when you get to the end, there's a non-zero cell to the right, it wasn't longest.\n",
202 " move to the right until you reach zero, then rebuild the longest sequence right-to-left\n",
203 " when to stop?\n",
204 "```\n"
205 ]
206 },
207 {
208 "cell_type": "code",
209 "execution_count": 3,
210 "metadata": {},
211 "outputs": [
212 {
213 "data": {
214 "text/plain": [
215 "118"
216 ]
217 },
218 "execution_count": 3,
219 "metadata": {},
220 "output_type": "execute_result"
221 }
222 ],
223 "source": [
224 "61+33+24"
225 ]
226 },
227 {
228 "cell_type": "code",
229 "execution_count": 7,
230 "metadata": {
231 "collapsed": true
232 },
233 "outputs": [],
234 "source": [
235 "helloworld= '++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.'"
236 ]
237 },
238 {
239 "cell_type": "code",
240 "execution_count": 20,
241 "metadata": {},
242 "outputs": [
243 {
244 "name": "stdout",
245 "output_type": "stream",
246 "text": [
247 "Hello World!\n"
248 ]
249 },
250 {
251 "data": {
252 "text/plain": [
253 "([0, 0, 72, 100, 87, 33, 10], 106, 6)"
254 ]
255 },
256 "execution_count": 20,
257 "metadata": {},
258 "output_type": "execute_result"
259 }
260 ],
261 "source": [
262 "evaluate(helloworld)"
263 ]
264 },
265 {
266 "cell_type": "code",
267 "execution_count": 19,
268 "metadata": {},
269 "outputs": [
270 {
271 "name": "stdout",
272 "output_type": "stream",
273 "text": [
274 "hello"
275 ]
276 },
277 {
278 "data": {
279 "text/plain": [
280 "([111], 3, 0)"
281 ]
282 },
283 "execution_count": 19,
284 "metadata": {},
285 "output_type": "execute_result"
286 }
287 ],
288 "source": [
289 "evaluate(',[.,]', input='hello')"
290 ]
291 },
292 {
293 "cell_type": "code",
294 "execution_count": 196,
295 "metadata": {
296 "collapsed": true
297 },
298 "outputs": [],
299 "source": [
300 "program = '>' + '+' * 94 + '>' + '+' * 24\n",
301 "program += \"\"\"\n",
302 "copy cell 1 into cell 0 using cell 3\n",
303 "\n",
304 "<\n",
305 "[-<+>>>+<<]\n",
306 "\n",
307 ">>\n",
308 "[-<<+>>]\n",
309 "\n",
310 "read into cell 5\n",
311 ">>,\n",
312 "\n",
313 "[\n",
314 " subtract cell 0 from cell 5\n",
315 " <<<<<[->>>>>-<<<<<]\n",
316 " >>>>>\n",
317 "\n",
318 " if cell 5 != 0 do more\n",
319 " [\n",
320 "\n",
321 " copy cell 2 into cell 0 using cell 3\n",
322 " <<<[->+<<<+>>]\n",
323 "\n",
324 " move cell 3 into cell 2\n",
325 " >[-<+>]\n",
326 " <\n",
327 "\n",
328 " subtract cell 0 from cell 5\n",
329 " <<[->>>>>-<<<<<]\n",
330 " >>>>>\n",
331 "\n",
332 " if cell 5 != 0\n",
333 " [\n",
334 " increment cell 4 by 1\n",
335 " <+>\n",
336 "\n",
337 " clear cell 5 to stop the loop\n",
338 " [-]\n",
339 " ]\n",
340 " decrement cell 4 by 2\n",
341 " <-->\n",
342 "\n",
343 " ]\n",
344 "\n",
345 " increment cell 4 by 1\n",
346 " <+\n",
347 "\n",
348 " copy cell 1 into cell 0 using cell 3\n",
349 " <<<[-<+>>>+<<]\n",
350 "\n",
351 " move cell 3 into cell 1\n",
352 " >>[-<<+>>]\n",
353 "\n",
354 " >>\n",
355 "\n",
356 " read next input\n",
357 " ,\n",
358 "]\n",
359 "write the output\n",
360 "<.\n",
361 "\n",
362 "\"\"\""
363 ]
364 },
365 {
366 "cell_type": "code",
367 "execution_count": 197,
368 "metadata": {},
369 "outputs": [
370 {
371 "data": {
372 "text/plain": [
373 "([94, 94, 24, 0, 3, 0], 255, 5)"
374 ]
375 },
376 "execution_count": 197,
377 "metadata": {},
378 "output_type": "execute_result"
379 }
380 ],
381 "source": [
382 "evaluate(program, inp='^^v=^^^v')"
383 ]
384 },
385 {
386 "cell_type": "code",
387 "execution_count": 198,
388 "metadata": {},
389 "outputs": [
390 {
391 "data": {
392 "text/plain": [
393 "'>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++<[-<+>>>+<<]>>[-<<+>>]>>,[<<<<<[->>>>>-<<<<<]>>>>>[<<<[->+<<<+>>]>[-<+>]<<<[->>>>>-<<<<<]>>>>>[<+>[-]]<-->]<+<<<[-<+>>>+<<]>>[-<<+>>]>>,]<.'"
394 ]
395 },
396 "execution_count": 198,
397 "metadata": {},
398 "output_type": "execute_result"
399 }
400 ],
401 "source": [
402 "''.join(cleanup(program))"
403 ]
404 },
405 {
406 "cell_type": "code",
407 "execution_count": 123,
408 "metadata": {},
409 "outputs": [
410 {
411 "data": {
412 "text/plain": [
413 "([60, 60, 0, 15, 0], 152, 4)"
414 ]
415 },
416 "execution_count": 123,
417 "metadata": {},
418 "output_type": "execute_result"
419 }
420 ],
421 "source": [
422 "inp = open('02-lifts.txt').read().strip()\n",
423 "evaluate(program, inp=inp)"
424 ]
425 },
426 {
427 "cell_type": "code",
428 "execution_count": 124,
429 "metadata": {
430 "collapsed": true
431 },
432 "outputs": [],
433 "source": [
434 "def value(instr):\n",
435 " if instr == '^':\n",
436 " return 1\n",
437 " elif instr == 'v':\n",
438 " return -1\n",
439 " else:\n",
440 " return 0"
441 ]
442 },
443 {
444 "cell_type": "code",
445 "execution_count": 125,
446 "metadata": {
447 "collapsed": true
448 },
449 "outputs": [],
450 "source": [
451 "def final(sequence):\n",
452 " current = 0\n",
453 " for c in sequence:\n",
454 " current += value(c)\n",
455 " return current"
456 ]
457 },
458 {
459 "cell_type": "code",
460 "execution_count": 126,
461 "metadata": {},
462 "outputs": [
463 {
464 "data": {
465 "text/plain": [
466 "209"
467 ]
468 },
469 "execution_count": 126,
470 "metadata": {},
471 "output_type": "execute_result"
472 }
473 ],
474 "source": [
475 "final(inp)"
476 ]
477 },
478 {
479 "cell_type": "code",
480 "execution_count": 193,
481 "metadata": {
482 "scrolled": true
483 },
484 "outputs": [
485 {
486 "name": "stdout",
487 "output_type": "stream",
488 "text": [
489 "0 ([94, 94, 24, 0, 0, 0], 144, 5) \n",
490 "-1 ([94, 94, 24, 0, 255, 0], 255, 5) v\n",
491 "-2 ([94, 94, 24, 0, 254, 0], 255, 5) vv\n",
492 "-3 ([94, 94, 24, 0, 253, 0], 255, 5) vvv\n",
493 "-2 ([94, 94, 24, 0, 254, 0], 255, 5) vvv^\n",
494 "-1 ([94, 94, 24, 0, 255, 0], 255, 5) vvv^^\n",
495 "-2 ([94, 94, 24, 0, 254, 0], 255, 5) vvv^^v\n",
496 "-1 ([94, 94, 24, 0, 255, 0], 255, 5) vvv^^v^\n",
497 "-2 ([94, 94, 24, 0, 254, 0], 255, 5) vvv^^v^v\n",
498 "-2 ([94, 94, 24, 0, 254, 0], 255, 5) vvv^^v^v=\n",
499 "-3 ([94, 94, 24, 0, 253, 0], 255, 5) vvv^^v^v=v\n",
500 "-4 ([94, 94, 24, 0, 252, 0], 255, 5) vvv^^v^v=vv\n",
501 "-3 ([94, 94, 24, 0, 253, 0], 255, 5) vvv^^v^v=vv^\n",
502 "-4 ([94, 94, 24, 0, 252, 0], 255, 5) vvv^^v^v=vv^v\n",
503 "-3 ([94, 94, 24, 0, 253, 0], 255, 5) vvv^^v^v=vv^v^\n",
504 "-2 ([94, 94, 24, 0, 254, 0], 255, 5) vvv^^v^v=vv^v^^\n",
505 "-3 ([94, 94, 24, 0, 253, 0], 255, 5) vvv^^v^v=vv^v^^v\n",
506 "-4 ([94, 94, 24, 0, 252, 0], 255, 5) vvv^^v^v=vv^v^^vv\n",
507 "-5 ([94, 94, 24, 0, 251, 0], 255, 5) vvv^^v^v=vv^v^^vvv\n",
508 "-6 ([94, 94, 24, 0, 250, 0], 255, 5) vvv^^v^v=vv^v^^vvvv\n",
509 "-5 ([94, 94, 24, 0, 251, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^\n",
510 "-4 ([94, 94, 24, 0, 252, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^\n",
511 "-5 ([94, 94, 24, 0, 251, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v\n",
512 "-5 ([94, 94, 24, 0, 251, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=\n",
513 "-4 ([94, 94, 24, 0, 252, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^\n",
514 "-4 ([94, 94, 24, 0, 252, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=\n",
515 "-3 ([94, 94, 24, 0, 253, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^\n",
516 "-2 ([94, 94, 24, 0, 254, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^\n",
517 "-2 ([94, 94, 24, 0, 254, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=\n",
518 "-1 ([94, 94, 24, 0, 255, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^\n",
519 "0 ([94, 94, 24, 0, 0, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^\n",
520 "1 ([94, 94, 24, 0, 1, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^\n",
521 "1 ([94, 94, 24, 0, 1, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=\n",
522 "2 ([94, 94, 24, 0, 2, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^\n",
523 "3 ([94, 94, 24, 0, 3, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^\n",
524 "4 ([94, 94, 24, 0, 4, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^\n",
525 "3 ([94, 94, 24, 0, 3, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v\n",
526 "3 ([94, 94, 24, 0, 3, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=\n",
527 "4 ([94, 94, 24, 0, 4, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^\n",
528 "5 ([94, 94, 24, 0, 5, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^\n",
529 "6 ([94, 94, 24, 0, 6, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^^\n",
530 "6 ([94, 94, 24, 0, 6, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^^=\n",
531 "7 ([94, 94, 24, 0, 7, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^^=^\n",
532 "8 ([94, 94, 24, 0, 8, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^^=^^\n",
533 "7 ([94, 94, 24, 0, 7, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^^=^^v\n",
534 "8 ([94, 94, 24, 0, 8, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^^=^^v^\n",
535 "9 ([94, 94, 24, 0, 9, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^^=^^v^^\n",
536 "8 ([94, 94, 24, 0, 8, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^^=^^v^^v\n",
537 "9 ([94, 94, 24, 0, 9, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^^=^^v^^v^\n",
538 "8 ([94, 94, 24, 0, 8, 0], 255, 5) vvv^^v^v=vv^v^^vvvv^^v=^=^^=^^^=^^^v=^^^=^^v^^v^v\n"
539 ]
540 }
541 ],
542 "source": [
543 "for i in range(50):\n",
544 " print(final(inp[:i]), evaluate(program, inp[:i]), inp[:i])"
545 ]
546 },
547 {
548 "cell_type": "code",
549 "execution_count": 194,
550 "metadata": {
551 "scrolled": true
552 },
553 "outputs": [
554 {
555 "data": {
556 "text/plain": [
557 "(209, ([94, 94, 24, 0, 209, 0], 255, 5))"
558 ]
559 },
560 "execution_count": 194,
561 "metadata": {},
562 "output_type": "execute_result"
563 }
564 ],
565 "source": [
566 "final(inp), evaluate(program, inp)"
567 ]
568 },
569 {
570 "cell_type": "code",
571 "execution_count": 199,
572 "metadata": {
573 "collapsed": true
574 },
575 "outputs": [],
576 "source": [
577 "! bf -n part1.bf < 02-lifts.txt > part1.bf.out"
578 ]
579 },
580 {
581 "cell_type": "code",
582 "execution_count": null,
583 "metadata": {
584 "collapsed": true
585 },
586 "outputs": [],
587 "source": []
588 }
589 ],
590 "metadata": {
591 "kernelspec": {
592 "display_name": "Python 3",
593 "language": "python",
594 "name": "python3"
595 },
596 "language_info": {
597 "codemirror_mode": {
598 "name": "ipython",
599 "version": 3
600 },
601 "file_extension": ".py",
602 "mimetype": "text/x-python",
603 "name": "python",
604 "nbconvert_exporter": "python",
605 "pygments_lexer": "ipython3",
606 "version": "3.5.2+"
607 }
608 },
609 "nbformat": 4,
610 "nbformat_minor": 2
611 }