Skip to content

Commit 4a8b9f9

Browse files
committed
Implement 2024 day 17 part 2
1 parent 6c0a49a commit 4a8b9f9

File tree

4 files changed

+82
-44
lines changed

4 files changed

+82
-44
lines changed

2024/src/aoc/days/day17.py

Lines changed: 72 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,54 @@
33
from . 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+
654
class 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]
File renamed without changes.

2024/tests/samples/17.2.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Register A: 2024
2+
Register B: 0
3+
Register C: 0
4+
5+
Program: 0,3,5,4,3,0

2024/tests/test_day17.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@
44

55

66
def test_sample_part1() -> None:
7-
assert DayRunner.part1(get_data(17)) == "4,6,3,5,6,3,5,2,1,0"
7+
assert DayRunner.part1(get_data(17, 1)) == "4,6,3,5,6,3,5,2,1,0"
8+
9+
10+
def test_sample_part2() -> None:
11+
assert DayRunner.part2(get_data(17, 2)) == 117440

0 commit comments

Comments
 (0)