X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=07-interpreter%2Fmachine-code-4-reg.ipynb;fp=07-interpreter%2Fmachine-code-4-reg.ipynb;h=3d000c680b6344f206666891898f50585ccfa669;hb=e405461a789315af95c5ae0e90d63d9fd7d81d37;hp=0000000000000000000000000000000000000000;hpb=08e0c316beac066037ece028bf687379819fc409;p=ou-summer-of-code-2017.git diff --git a/07-interpreter/machine-code-4-reg.ipynb b/07-interpreter/machine-code-4-reg.ipynb new file mode 100644 index 0000000..3d000c6 --- /dev/null +++ b/07-interpreter/machine-code-4-reg.ipynb @@ -0,0 +1,1189 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Machine interpreter\n", + "\n", + "## Instructions\n", + "\n", + "Four registers, `a`, `b`, `c`, and `d`.\n", + "Program counter, `pc`.\n", + "\n", + "Each register can hold 8-byte integers (Java `long`s).\n", + "\n", + "Machine carries out the instruction at location `pc`. After it's executed, `pc` increments by 1.\n", + "\n", + "`jmp` and `jpz` override this normal change in `pc`.\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", + "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." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "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": 5, + "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": 6, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def inc(reg, machine):\n", + " machine[reg] += 1\n", + " machine['pc'] += 1" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def dec(reg, machine):\n", + " machine[reg] -= 1\n", + " machine['pc'] += 1" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def jmp(addr, machine):\n", + " machine['pc'] += addr" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "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": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def set_literal(reg, literal, machine):\n", + " machine[reg] = literal\n", + " machine['pc'] += 1" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "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": 12, + "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": 13, + "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": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a': 2, 'b': 1, 'c': 0, 'd': 0, 'instructions': [], 'pc': 3}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "m = new_machine()\n", + "inc('a', m)\n", + "cargs = ['a', 'b']\n", + "cpy(*cargs, m)\n", + "inc('a', m)\n", + "m" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "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": 16, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def program_from_listing(listing, machine):\n", + " labelled_instructions = [i.strip() for i in listing.split('\\n') \n", + " if i.strip() \n", + " if not i.strip().startswith('#')]\n", + " instructions = replace_labels(labelled_instructions)\n", + " program_from_instructions(instructions, machine)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "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": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['inc', 'a']" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "'fred: inc a'.split(':')[1].split()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "set a 10\n", + "dec a\n", + "inc b\n", + "jpz a 2\n", + "jmp -3\n" + ] + } + ], + "source": [ + "program = \"\"\"\n", + " set a 10\n", + " # comment line\n", + " \n", + "loop: dec a\n", + " inc b\n", + " jpz a 2\n", + " jmp loop\n", + "\"\"\"\n", + "labelled_instructions = [i.strip() for i in program.split('\\n') if i.strip() if not i.strip().startswith('#')]\n", + "instructions = replace_labels(labelled_instructions)\n", + "print('\\n'.join(instructions))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "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": 21, + "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': 3,\n", + " 'b': 2,\n", + " 'c': 0,\n", + " 'd': 0,\n", + " 'instructions': [(, ['a']),\n", + " (, ['a']),\n", + " (, ['a', 'b']),\n", + " (, ['a'])],\n", + " 'pc': 4}" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "program = \"\"\"\n", + "inc a\n", + "inc a\n", + "cpy a b\n", + "inc a\n", + "\"\"\"\n", + "execute(program)" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a': 0,\n", + " 'b': 10,\n", + " 'c': 20,\n", + " 'd': 0,\n", + " 'instructions': [(, ['a', 10]),\n", + " (, ['a']),\n", + " (, ['b']),\n", + " (, ['a', 2]),\n", + " (, [-3])],\n", + " 'pc': 5}" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "program = \"\"\"\n", + "set a 10\n", + "dec a\n", + "inc b\n", + "jpz a 2\n", + "jmp -3\n", + "\"\"\"\n", + "# m = new_machine()\n", + "# program_from_listing(program, m)\n", + "# run(m)\n", + "execute(program, initial_state={'c': 20})" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a': 0,\n", + " 'b': 10,\n", + " 'c': 20,\n", + " 'd': 0,\n", + " 'instructions': [(, ['a', 10]),\n", + " (, ['a']),\n", + " (, ['b']),\n", + " (, ['a', 2]),\n", + " (, [-3])],\n", + " 'pc': 5}" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "program = \"\"\"\n", + " set a 10\n", + "loop: dec a\n", + " inc b\n", + " jpz a 2\n", + " jmp loop\n", + "\"\"\"\n", + "execute(program, initial_state={'c': 20})" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a': 0,\n", + " 'b': 1,\n", + " 'c': 5,\n", + " 'd': 0,\n", + " 'instructions': [(, ['c', 'a']),\n", + " (, ['b', 0]),\n", + " (, ['a']),\n", + " (, ['b', 3]),\n", + " (, ['b']),\n", + " (, [2]),\n", + " (, ['b']),\n", + " (, ['a', 3]),\n", + " (, [-6])],\n", + " 'pc': 10}" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "program = \"\"\"\n", + "cpy c a\n", + "set b 0\n", + "dec a\n", + "jpz b 3\n", + "dec b\n", + "jmp 2\n", + "inc b\n", + "jpz a 3\n", + "jmp -6\n", + "\"\"\"\n", + "# m = new_machine()\n", + "# program_from_listing(program, m)\n", + "# run(m)\n", + "execute(program, initial_state={'c': 5})" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a': 0,\n", + " 'b': 1,\n", + " 'c': 5,\n", + " 'd': 0,\n", + " 'instructions': [(, ['c', 'a']),\n", + " (, ['b', 0]),\n", + " (, ['a']),\n", + " (, ['b', 3]),\n", + " (, ['b']),\n", + " (, [2]),\n", + " (, ['b']),\n", + " (, ['a', 2]),\n", + " (, [-6])],\n", + " 'pc': 9}" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# b holds parity of number in c: (c % 2)\n", + "program = \"\"\"\n", + " cpy c a\n", + " set b 0\n", + "loop: dec a\n", + " jpz b odd\n", + " dec b\n", + " jmp end\n", + "odd: inc b\n", + "end: jpz a 2\n", + " jmp loop\n", + "\"\"\"\n", + "# m = new_machine()\n", + "# program_from_listing(program, m)\n", + "# run(m)\n", + "execute(program, initial_state={'c': 5})" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'a: 0, b: 1, c: 8, d: 0, pc: 10'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# c holds floor(a/2)\n", + "program = \"\"\"\n", + " set c 0\n", + " set b 0\n", + "loop: dec a\n", + " jpz b odd\n", + " dec b\n", + " inc c\n", + " jmp end\n", + "odd: inc b\n", + "end: jpz a 2\n", + " jmp loop\n", + "\"\"\"\n", + "# m = new_machine()\n", + "# program_from_listing(program, m)\n", + "# run(m)\n", + "show_machine(execute(program, initial_state={'a': 17}))" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'a: 4, b: 0, c: 12, d: 0, pc: 9'" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# c holds a * 3\n", + "program = \"\"\"\n", + " set c 0\n", + " cpy a b\n", + " # start of main loop\n", + "loop: jpz b end\n", + " dec b\n", + " inc c\n", + " inc c\n", + " inc c\n", + " jmp loop\n", + " \n", + " # end of program \n", + " \n", + "end: jmp 1\n", + "\"\"\"\n", + "# m = new_machine()\n", + "# program_from_listing(program, m)\n", + "# run(m)\n", + "show_machine(execute(program, initial_state={'a': 4}))" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'a: 0, b: 0, c: 27, d: 0, pc: 11'" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# c holds a * b\n", + "program = \"\"\"\n", + " set c 0\n", + " cpy a d\n", + "loop: jpz b end \n", + " dec b\n", + " cpy d a\n", + "smul: jpz a emul\n", + " inc c\n", + " dec a\n", + " jmp smul\n", + "emul: jmp loop \n", + " \n", + "end: set d 0\n", + "\"\"\"\n", + "m = new_machine()\n", + "program_from_listing(program, m)\n", + "run(m)\n", + "show_machine(execute(program, initial_state={'a': 9, 'b': 3}))" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "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" + ] + } + ], + "source": [ + "labelled_instructions = [i.strip() for i in program.split('\\n') if i.strip() if not i.strip().startswith('#')]\n", + "instructions = replace_labels(labelled_instructions)\n", + "print('\\n'.join(instructions))" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'a: 2, b: 0, c: 10, d: 2, pc: 13'" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# c holds a * b\n", + "program = \"\"\"\n", + " set a 2\n", + " set b 5\n", + " set c 0\n", + " cpy a d\n", + "loop: jpz b end \n", + " dec b\n", + " cpy d a\n", + "smul: jpz a emul\n", + " inc c\n", + " dec a\n", + " jmp smul\n", + "emul: jmp loop \n", + " \n", + "end: cpy d a\n", + "\"\"\"\n", + "m = new_machine()\n", + "program_from_listing(program, m)\n", + "run(m)\n", + "show_machine(execute(program, initial_state={'a': 9, 'b': 3}))" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "set a 2\n", + "set b 5\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", + "cpy d a\n" + ] + } + ], + "source": [ + "labelled_instructions = [i.strip() for i in program.split('\\n') \n", + " if i.strip() \n", + " if not i.strip().startswith('#')]\n", + "instructions = replace_labels(labelled_instructions)\n", + "print('\\n'.join(instructions))" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'a: 52, b: 0, c: 0, d: 0, pc: 48'" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Collatz. a initially holds value, but location 1 is used to store the current value as we're going along.\n", + "# Location 2 holds number of steps taken\n", + "# Location 3 holds max value reached\n", + "program = \"\"\"\n", + " cpy a d\n", + " \n", + " set b 0\n", + " \n", + " # if a is one, finish, \n", + "main: dec a\n", + " jpz a end\n", + " inc a\n", + " \n", + " # find parity of a\n", + " cpy a c\n", + " set b 0\n", + "prty: dec c\n", + " jpz b odd\n", + " dec b\n", + " jmp prte\n", + "odd: inc b\n", + "prte: jpz c 2\n", + " jmp prty\n", + " \n", + " # b == 0 means a even; b == 1 means a odd\n", + " jpz b isev\n", + "\n", + " # c holds a * 3 + 1\n", + " cpy a b\n", + "mul: jpz b emul\n", + " dec b\n", + " inc c\n", + " inc c\n", + " inc c\n", + " jmp mul\n", + "emul: inc c\n", + " cpy c a\n", + " jmp fin\n", + " \n", + " \n", + "isev: set c 0\n", + " set b 0\n", + "hlvl: dec a\n", + " jpz b oddh\n", + " dec b\n", + " inc c\n", + " jmp endh\n", + "oddh: inc b\n", + "endh: jpz a 2\n", + " jmp hlvl\n", + " cpy c a\n", + "\n", + "fin: cpy a b\n", + " cpy d c\n", + "maxc: jpz c this\n", + " jpz b othr\n", + " dec b\n", + " dec c\n", + " jmp maxc\n", + "this: cpy a d\n", + "othr: jmp main\n", + " \n", + " # end of program \n", + " \n", + "end: cpy d a\n", + " set c 0\n", + " set d 0\n", + "\"\"\"\n", + "# m = new_machine()\n", + "# program_from_listing(program, m)\n", + "# run(m)\n", + "show_machine(execute(program, initial_state={'a': 7}))" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "40" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "13*3+1" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def max_collatz(start):\n", + " mc = start\n", + " i = start\n", + " while i != 1:\n", + " if i % 2 == 0:\n", + " i = i // 2\n", + " else:\n", + " i = 3 * i + 1\n", + " if i > mc:\n", + " mc = i\n", + " return mc" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "52" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max_collatz(7)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(250504, 937)" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "max([(max_collatz(i), i) for i in range(1, 1000)])" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[(1, 0, 1),\n", + " (2, 0, 2),\n", + " (3, 0, 16),\n", + " (4, 0, 4),\n", + " (5, 0, 16),\n", + " (6, 0, 16),\n", + " (7, 0, 52),\n", + " (8, 0, 8),\n", + " (9, 0, 52),\n", + " (10, 0, 16),\n", + " (11, 0, 52),\n", + " (12, 0, 16),\n", + " (13, 0, 40),\n", + " (14, 0, 52),\n", + " (15, 0, 160),\n", + " (16, 0, 16),\n", + " (17, 0, 52),\n", + " (18, 0, 52),\n", + " (19, 0, 88),\n", + " (20, 0, 20),\n", + " (21, 0, 64),\n", + " (22, 0, 52),\n", + " (23, 0, 160),\n", + " (24, 0, 24),\n", + " (25, 0, 88),\n", + " (26, 0, 40),\n", + " (27, 0, 9232),\n", + " (28, 0, 52),\n", + " (29, 0, 88),\n", + " (30, 0, 160),\n", + " (31, 0, 9232),\n", + " (32, 0, 32),\n", + " (33, 0, 100),\n", + " (34, 0, 52),\n", + " (35, 0, 160),\n", + " (36, 0, 52),\n", + " (37, 0, 112),\n", + " (38, 0, 88),\n", + " (39, 0, 304),\n", + " (40, 0, 40),\n", + " (41, 0, 9232),\n", + " (42, 0, 64),\n", + " (43, 0, 196),\n", + " (44, 0, 52),\n", + " (45, 0, 136),\n", + " (46, 0, 160),\n", + " (47, 0, 9232),\n", + " (48, 0, 48),\n", + " (49, 0, 148),\n", + " (50, 0, 88),\n", + " (51, 0, 232),\n", + " (52, 0, 52),\n", + " (53, 0, 160),\n", + " (54, 0, 9232),\n", + " (55, 0, 9232),\n", + " (56, 0, 56),\n", + " (57, 0, 196),\n", + " (58, 0, 88),\n", + " (59, 0, 304),\n", + " (60, 0, 160),\n", + " (61, 0, 184),\n", + " (62, 0, 9232),\n", + " (63, 0, 9232),\n", + " (64, 0, 64),\n", + " (65, 0, 196),\n", + " (66, 0, 100),\n", + " (67, 0, 304),\n", + " (68, 0, 68),\n", + " (69, 0, 208),\n", + " (70, 0, 160),\n", + " (71, 0, 9232),\n", + " (72, 0, 72),\n", + " (73, 0, 9232),\n", + " (74, 0, 112),\n", + " (75, 0, 340),\n", + " (76, 0, 88),\n", + " (77, 0, 232),\n", + " (78, 0, 304),\n", + " (79, 0, 808),\n", + " (80, 0, 80),\n", + " (81, 0, 244),\n", + " (82, 0, 9232),\n", + " (83, 0, 9232),\n", + " (84, 0, 84),\n", + " (85, 0, 256),\n", + " (86, 0, 196),\n", + " (87, 0, 592),\n", + " (88, 0, 88),\n", + " (89, 0, 304),\n", + " (90, 0, 136),\n", + " (91, 0, 9232),\n", + " (92, 0, 160),\n", + " (93, 0, 280),\n", + " (94, 0, 9232),\n", + " (95, 0, 9232),\n", + " (96, 0, 96),\n", + " (97, 0, 9232),\n", + " (98, 0, 148),\n", + " (99, 0, 448)]" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ans = []\n", + "for i in range(1, 100):\n", + " m = execute(program, initial_state={'a': i})\n", + " c = max_collatz(i)\n", + " if m[1] != c:\n", + " ans += [(i, m[1], c)]\n", + "ans" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'a: 250504, b: 0, c: 0, d: 0, pc: 48'" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "show_machine(execute(program, initial_state={'a': 937}))" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cpy a d\n", + "set b 0\n", + "dec a\n", + "jpz a 42\n", + "inc a\n", + "cpy a c\n", + "set b 0\n", + "dec c\n", + "jpz b 3\n", + "dec b\n", + "jmp 2\n", + "inc b\n", + "jpz c 2\n", + "jmp -6\n", + "jpz b 11\n", + "cpy a b\n", + "jpz b 6\n", + "dec b\n", + "inc c\n", + "inc c\n", + "inc c\n", + "jmp -5\n", + "inc c\n", + "cpy c a\n", + "jmp 12\n", + "set c 0\n", + "set b 0\n", + "dec a\n", + "jpz b 4\n", + "dec b\n", + "inc c\n", + "jmp 2\n", + "inc b\n", + "jpz a 2\n", + "jmp -7\n", + "cpy c a\n", + "cpy a b\n", + "cpy d c\n", + "jpz c 5\n", + "jpz b 5\n", + "dec b\n", + "dec c\n", + "jmp -4\n", + "cpy a d\n", + "jmp -42\n", + "cpy d a\n", + "set c 0\n", + "set d 0\n" + ] + }, + { + "data": { + "text/plain": [ + "344" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "labelled_instructions = [i.strip() for i in program.split('\\n') \n", + " if i.strip() \n", + " if not i.strip().startswith('#')]\n", + "instructions = replace_labels(labelled_instructions)\n", + "print('\\n'.join(instructions))\n", + "open('07-program.txt', 'w').write('\\n'.join(instructions))" + ] + }, + { + "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 +}