33from . import SeparateRunner
44
55
6+ def run_program (
7+ register_a : int , register_b : int , register_c : int , program : list [int ]
8+ ) -> list [int ]:
9+ ip = 0
10+ out = []
11+
12+ def combo (index : int ) -> int :
13+ match program [index ]:
14+ case 0 :
15+ return 0
16+ case 1 :
17+ return 1
18+ case 2 :
19+ return 2
20+ case 3 :
21+ return 3
22+ case 4 :
23+ return register_a
24+ case 5 :
25+ return register_b
26+ case 6 :
27+ return register_c
28+
29+ while ip < len (program ):
30+ match program [ip ]:
31+ case 0 : # adv
32+ register_a = register_a // 2 ** combo (ip + 1 )
33+ case 1 : # bxl
34+ register_b ^= program [ip + 1 ]
35+ case 2 : # bst
36+ register_b = combo (ip + 1 ) & 0x7
37+ case 3 : # jnz
38+ if register_a != 0 :
39+ ip = program [ip + 1 ]
40+ continue
41+ case 4 : # bxc
42+ register_b ^= register_c
43+ case 5 : # out
44+ out .append (combo (ip + 1 ) & 7 )
45+ case 6 : # bdv
46+ register_b = register_a // 2 ** combo (ip + 1 )
47+ case 7 : # cdv
48+ register_c = register_a // 2 ** combo (ip + 1 )
49+ ip += 2
50+
51+ return out
52+
53+
654class DayRunner (SeparateRunner ):
755 @classmethod
856 def part1 (cls , input : str ) -> str :
@@ -11,50 +59,31 @@ def part1(cls, input: str) -> str:
1159 register_a , register_b , register_c = map (int , numbers [:3 ])
1260 program = list (map (int , numbers [3 :]))
1361
14- ip = 0
15- out = []
16-
17- def combo (index : int ) -> int :
18- match program [index ]:
19- case 0 :
20- return 0
21- case 1 :
22- return 1
23- case 2 :
24- return 2
25- case 3 :
26- return 3
27- case 4 :
28- return register_a
29- case 5 :
30- return register_b
31- case 6 :
32- return register_c
33-
34- while ip < len (program ):
35- match program [ip ]:
36- case 0 : # adv
37- register_a = register_a // 2 ** combo (ip + 1 )
38- case 1 : # bxl
39- register_b ^= program [ip + 1 ]
40- case 2 : # bst
41- register_b = combo (ip + 1 ) & 0x7
42- case 3 : # jnz
43- if register_a != 0 :
44- ip = program [ip + 1 ]
45- continue
46- case 4 : # bxc
47- register_b ^= register_c
48- case 5 : # out
49- out .append (combo (ip + 1 ) & 7 )
50- case 6 : # bdv
51- register_b = register_a // 2 ** combo (ip + 1 )
52- case 7 : # cdv
53- register_c = register_a // 2 ** combo (ip + 1 )
54- ip += 2
62+ out = run_program (register_a , register_b , register_c , program )
5563
5664 return "," .join (map (str , out ))
5765
5866 @classmethod
59- def part2 (cls , input : str ) -> str :
60- pass
67+ def part2 (cls , input : str ) -> int :
68+ numbers = re .findall (r"\d+" , input )
69+
70+ _ , register_b , register_c = map (int , numbers [:3 ])
71+ program = list (map (int , numbers [3 :]))
72+
73+ cur = [0 ]
74+
75+ # It came to me in a dream
76+ for entry in reversed (program ):
77+ next_gen = []
78+
79+ for num in cur :
80+ num *= 8
81+ for n in range (8 ):
82+ output = run_program (num + n , register_b , register_c , program )
83+ result = output [0 ]
84+ if result == entry :
85+ next_gen .append (num + n )
86+
87+ cur = next_gen
88+
89+ return cur [0 ]
0 commit comments