-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.py
82 lines (66 loc) · 2.41 KB
/
script.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
from GhostyUtils import aoc
from dataclasses import dataclass
import operator
from typing import Callable
@dataclass
class Registers:
A: int
B: int
C: int
def combo(operand: int, regs: Registers) -> int:
match operand:
case 0: return 0
case 1: return 1
case 2: return 2
case 3: return 3
case 4: return regs.A
case 5: return regs.B
case 6: return regs.C
case 7: assert False
def process(program: list[int], regs: Registers, output: Callable):
i_ptr = 0
while True:
if i_ptr >= len(program):
break
instr = program[i_ptr]
operand = program[i_ptr+1]
match instr:
case 0: # adv (A division by combo operand, store in A)
regs.A = regs.A // (2 ** combo(operand, regs))
i_ptr += 2
case 1: # bxl (bitwise xor of B and literal operand, store in B)
regs.B = operator.xor(regs.B, operand)
i_ptr += 2
case 2: # bst (combo operand modulo 8, store in B)
regs.B = combo(operand, regs) % 8
i_ptr += 2
case 3: # jnz (jump to literal operand if A non-zero)
if regs.A == 0:
i_ptr += 2
else:
i_ptr = operand
case 4: # bxc (bitwise xor of B and C, store in B)
regs.B = operator.xor(regs.B, regs.C)
i_ptr += 2
case 5: # out (output combo operand modulo 8)
output(combo(operand, regs) % 8)
i_ptr += 2
case 6: # bdv (A division by combo operand, store in B)
regs.B = regs.A // (2 ** combo(operand, regs))
i_ptr += 2
case 7: # cdv (A division by combo operand, store in C)
regs.C = regs.A // (2 ** combo(operand, regs))
i_ptr += 2
def read_regs(registers: str) -> Registers:
a, b, c = (r.split(': ') for r in registers.splitlines())
regs = Registers(int(a[1]), int(b[1]), int(c[1]))
return regs
def main():
registers, program = (section.strip() for section in aoc.read_sections())
regs = read_regs(registers)
program = list(map(int, program.split(': ')[1].split(',')))
output = []
process(program, regs, output=output.append)
print(f"p1: {','.join(map(str, output))}")
if __name__ == "__main__":
main()