{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "sophisticated-processing", "metadata": {}, "outputs": [], "source": [ "import networkx as nx\n", "import matplotlib.pyplot as plt\n", "\n", "INPUT = 'Input'\n", "\n", "def value(wires, token):\n", " try:\n", " value = int(token)\n", " except ValueError:\n", " value = wires.get(token, 0)\n", "\n", " return value\n", "\n", "mask = 0xffff\n", "\n", "def compute(wires, tokens):\n", " if len(tokens) == 1:\n", " return value(wires, tokens[0])\n", " if tokens[0] == 'NOT':\n", " return mask - value(wires, tokens[1])\n", " if tokens[1] == 'AND':\n", " return value(wires, tokens[0]) & value(wires, tokens[2])\n", " if tokens[1] == 'OR':\n", " return value(wires, tokens[0]) | value(wires, tokens[2])\n", " if tokens[1] == 'LSHIFT':\n", " return (value(wires, tokens[0]) << value(wires, tokens[2])) & mask\n", " if tokens[1] == 'RSHIFT':\n", " return value(wires, tokens[0]) >> value(wires, tokens[2])\n", " assert False\n", "\n", "def run(wires, s):\n", " if not s:\n", " return\n", " tokens = s.split()\n", " wires[tokens[-1]] = compute(wires, tokens[:-2])\n", "\n", "\n", "def add_to_graph(dg, s):\n", " if not s:\n", " return\n", " tokens = s.split()\n", " input1 = None\n", " input2 = None\n", " output = tokens[-1]\n", " tokens = tokens[:-2]\n", " if len(tokens) == 1:\n", " if tokens[0].isdigit():\n", " input1 = INPUT\n", " else:\n", " input1 = tokens[0]\n", " elif tokens[0] == 'NOT':\n", " if tokens[1].isdigit():\n", " input1 = INPUT\n", " else:\n", " input1 = tokens[1]\n", " else:\n", " input1 = tokens[0]\n", " input2 = tokens[2]\n", "\n", " if input1 and not input1.isdigit():\n", " dg.add_edge(output, input1, code = s)\n", " if input2 and not input2.isdigit():\n", " dg.add_edge(output, input2, code = s)\n", "\n", "\n", "def run_graph(wires, dg):\n", " nodes = reversed(list(nx.topological_sort(nx.line_graph(dg))))\n", " for (fn, tn) in nodes:\n", " run(wires, dg[fn][tn].get('code', ''))" ] }, { "cell_type": "code", "execution_count": 2, "id": "south-candidate", "metadata": {}, "outputs": [], "source": [ "wires = {}\n", "instructions = \"\"\"123 -> x\n", "456 -> y\n", "x AND y -> d\n", "x OR y -> e\n", "x LSHIFT 2 -> f\n", "y RSHIFT 2 -> g\n", "NOT x -> h\n", "NOT y -> i\"\"\"\n", "dg = nx.DiGraph()\n", "for s in instructions.splitlines():\n", " add_to_graph(dg, s)\n", "run_graph(wires, dg)\n", "assert value(wires, 'd') == 72\n", "assert value(wires, 'e') == 507\n", "assert value(wires, 'f') == 492\n", "assert value(wires, 'g') == 114\n", "assert value(wires, 'h') == 65412\n", "assert value(wires, 'i') == 65079\n", "assert value(wires, 'x') == 123\n", "assert value(wires, 'y') == 456" ] }, { "cell_type": "code", "execution_count": 3, "id": "difficult-wells", "metadata": {}, "outputs": [], "source": [ "import import_ipynb\n", "import helper\n", "s = helper.read_file('2015_7.txt')" ] }, { "cell_type": "code", "execution_count": 4, "id": "existing-pittsburgh", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "956\n", "40149\n" ] } ], "source": [ "wires = {}\n", "dg = nx.DiGraph()\n", "for instr in s.splitlines():\n", " add_to_graph(dg, instr)\n", "\n", "run_graph(wires, dg)\n", "print(wires['a'])\n", "\n", "wires = {'b': wires['a']}\n", "dg.remove_node(INPUT)\n", "run_graph(wires, dg)\n", "print(wires['a'])" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.2" }, "title": "Some Assembly Required" }, "nbformat": 4, "nbformat_minor": 5 }