{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import operator\n", "from collections import defaultdict\n", "from dataclasses import dataclass\n", "from typing import Callable\n", "\n", "operators = {\n", " \"inc\": operator.add,\n", " \"dec\": operator.sub,\n", "}\n", "\n", "comparisons = {\n", " \"<\": operator.lt,\n", " \"<=\": operator.le,\n", " \"==\": operator.eq,\n", " \"!=\": operator.ne,\n", " \">=\": operator.ge,\n", " \">\": operator.gt,\n", "}\n", "\n", "\n", "def parse_op(op):\n", " reg, op, value = op.split()\n", " value = int(value)\n", " op = operators[op]\n", " return (\n", " lambda registers: operator.setitem(registers, reg, op(registers[reg], value))\n", " or registers[reg]\n", " )\n", "\n", "\n", "def parse_cond(cond):\n", " reg, cond, target = cond.split()\n", " target = int(target)\n", " cond = comparisons[cond]\n", " return lambda registers: cond(registers[reg], target)\n", "\n", "\n", "@dataclass\n", "class Instruction(object):\n", " line: str\n", " operation: Callable[[dict], int]\n", " condition: Callable[[dict], bool]\n", "\n", " @classmethod\n", " def from_line(cls, line):\n", " line = line.strip()\n", " instr, cond = line.split(\"if\")\n", " return cls(line, parse_op(instr.strip()), parse_cond(cond.strip()))\n", "\n", " def execute(self, registers):\n", " if self.condition(registers):\n", " return self.operation(registers)\n", " return 0\n", "\n", "\n", "def read_program(lines):\n", " return [Instruction.from_line(line) for line in lines if line.strip()]\n", "\n", "\n", "def largest_register_value(program):\n", " registers = defaultdict(int)\n", " return (max(instr.execute(registers) for instr in program), max(registers.values()))\n", "\n", "\n", "test_program = read_program(\n", " \"\"\"\\\n", "b inc 5 if a > 1\n", "a inc 1 if b < 5\n", "c dec -10 if a >= 1\n", "c inc -20 if c == 10\n", "\"\"\".splitlines()\n", ")\n", "\n", "assert largest_register_value(test_program) == (10, 1)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import aocd\n", "\n", "data = aocd.get_data(day=8, year=2017)\n", "program = read_program(data.splitlines())" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Part 1: 5946\n", "Part 2: 6026\n" ] } ], "source": [ "high_water_line, final_max = largest_register_value(program)\n", "print(\"Part 1:\", final_max)\n", "print(\"Part 2:\", high_water_line)" ] } ], "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.12.0" } }, "nbformat": 4, "nbformat_minor": 2 }