3
3
from . import SeparateRunner
4
4
5
5
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
+
6
54
class DayRunner (SeparateRunner ):
7
55
@classmethod
8
56
def part1 (cls , input : str ) -> str :
@@ -11,50 +59,31 @@ def part1(cls, input: str) -> str:
11
59
register_a , register_b , register_c = map (int , numbers [:3 ])
12
60
program = list (map (int , numbers [3 :]))
13
61
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 )
55
63
56
64
return "," .join (map (str , out ))
57
65
58
66
@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