day23 - unoptimized

This commit is contained in:
Stefan Harmuth 2025-03-16 11:34:37 +01:00
parent 015a2cd884
commit dbf1a23640
5 changed files with 153 additions and 59 deletions

87
asembunny.py Normal file
View File

@ -0,0 +1,87 @@
from enum import Enum
class Command(str, Enum):
COPY = "cpy"
INCREASE = "inc"
DECREASE = "dec"
JUMP_NON_ZERO = "jnz"
TOGGLE = "tgl"
class Computer:
def __init__(
self, code: list[tuple[Command, str | int, ...]], reg_a: int = 0, reg_b: int = 0, reg_c: int = 0, reg_d: int = 0
):
self.reg = {
"a": reg_a,
"b": reg_b,
"c": reg_c,
"d": reg_d,
}
self.code = code
self.instr_ptr = 0
def get_value(self, source: int | str) -> int:
if isinstance(source, int):
return source
if source not in "abcd":
raise ValueError(f"Invalid source: {source}")
return self.reg[source]
def run(self):
while self.instr_ptr < len(self.code):
cmd, *args = self.code[self.instr_ptr]
if cmd == Command.COPY:
if isinstance(args[0], int):
self.reg[args[1]] = args[0]
else:
self.reg[args[1]] = self.reg[args[0]]
self.instr_ptr += 1
elif cmd == Command.INCREASE:
self.reg[args[0]] += 1
self.instr_ptr += 1
elif cmd == Command.DECREASE:
self.reg[args[0]] -= 1
self.instr_ptr += 1
elif cmd == Command.JUMP_NON_ZERO:
if isinstance(args[0], int):
check = args[0]
else:
check = self.reg[args[0]]
if check:
self.instr_ptr += self.get_value(args[1])
else:
self.instr_ptr += 1
elif cmd == Command.TOGGLE:
target = self.instr_ptr + self.reg[args[0]]
if target >= len(self.code) or target < 0:
self.instr_ptr += 1
continue
target_instr = self.code[target]
if len(target_instr) == 2:
if target_instr[0] != Command.INCREASE:
self.code[target] = (Command.INCREASE, target_instr[1])
else:
self.code[target] = (Command.DECREASE, target_instr[1])
else:
if target_instr[0] != Command.JUMP_NON_ZERO:
self.code[target] = (Command.JUMP_NON_ZERO, *target_instr[1:])
else:
self.code[target] = (Command.COPY, *target_instr[1:])
self.instr_ptr += 1
def parse_assembunny_code(code_lines: list[str]) -> list[tuple[Command, str | int, ...]]:
code = []
for line in code_lines:
args = line.split()
cmd = Command(args[0])
args = [int(arg) if arg not in "abcd" else arg for arg in args[1:]]
code.append((cmd, *args))
return code

View File

@ -1,52 +1,6 @@
from enum import Enum
from tools.aoc import AOCDay
from typing import Any
class Command(str, Enum):
COPY = "cpy"
INCREASE = "inc"
DECREASE = "dec"
JUMP_NON_ZERO = "jnz"
class Computer:
def __init__(
self, code: list[tuple[Command, str | int, ...]], reg_a: int = 0, reg_b: int = 0, reg_c: int = 0, reg_d: int = 0
):
self.reg = {
"a": reg_a,
"b": reg_b,
"c": reg_c,
"d": reg_d,
}
self.code = code
self.instr_ptr = 0
def run(self):
while self.instr_ptr < len(self.code):
cmd, *args = self.code[self.instr_ptr]
if cmd == Command.COPY:
if isinstance(args[0], int):
self.reg[args[1]] = args[0]
else:
self.reg[args[1]] = self.reg[args[0]]
self.instr_ptr += 1
elif cmd == Command.INCREASE:
self.reg[args[0]] += 1
self.instr_ptr += 1
elif cmd == Command.DECREASE:
self.reg[args[0]] -= 1
self.instr_ptr += 1
elif cmd == Command.JUMP_NON_ZERO:
if isinstance(args[0], int):
check = args[0]
else:
check = self.reg[args[0]]
if check:
self.instr_ptr += args[1]
else:
self.instr_ptr += 1
from asembunny import parse_assembunny_code, Computer
class Day(AOCDay):
@ -60,23 +14,13 @@ class Day(AOCDay):
],
]
def parse_input(self) -> list[tuple[Command, str | int, ...]]:
code = []
for line in self.getInput():
args = line.split()
cmd = Command(args[0])
args = [int(arg) if arg not in "abcd" else arg for arg in args[1:]]
code.append((cmd, *args))
return code
def part1(self) -> Any:
computer = Computer(code=self.parse_input())
computer = Computer(code=parse_assembunny_code(self.getInput()))
computer.run()
return computer.reg["a"]
def part2(self) -> Any:
computer = Computer(code=self.parse_input(), reg_c=1)
computer = Computer(code=parse_assembunny_code(self.getInput()), reg_a=1)
computer.run()
return computer.reg["a"]

30
day23.py Normal file
View File

@ -0,0 +1,30 @@
from asembunny import Computer, parse_assembunny_code
from tools.aoc import AOCDay
from typing import Any
class Day(AOCDay):
inputs = [
[
(3, "input23_test"),
(11004, "input23"),
],
[
(479007564, "input23"),
],
]
def part1(self) -> Any:
computer = Computer(parse_assembunny_code(self.getInput()), reg_a=7 if not self.is_test() else 0)
computer.run()
return computer.reg["a"]
def part2(self) -> Any:
computer = Computer(parse_assembunny_code(self.getInput()), reg_a=12)
computer.run()
return computer.reg["a"]
if __name__ == "__main__":
day = Day(2016, 23)
day.run(verbose=True)

26
inputs/input23 Normal file
View File

@ -0,0 +1,26 @@
cpy a b
dec b
cpy a d
cpy 0 a
cpy b c
inc a
dec c
jnz c -2
dec d
jnz d -5
dec b
cpy b c
cpy c d
dec d
inc c
jnz d -2
tgl c
cpy -16 c
jnz 1 c
cpy 84 c
jnz 71 d
inc a
inc d
jnz d -2
inc c
jnz c -5

7
inputs/input23_test Normal file
View File

@ -0,0 +1,7 @@
cpy 2 a
tgl a
tgl a
tgl a
cpy 1 a
dec a
dec a