Skip to content

Commit b23676b

Browse files
committed
Implement 2024 day 21 part 2
Invent a unit test for it too, because why not, it's Christmas
1 parent 40632c8 commit b23676b

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

2024/src/aoc/days/day21.py

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import functools
2+
from collections import Counter, defaultdict
23

34
from . import SeparateRunner
45

@@ -114,6 +115,18 @@ def decode(code: str, pad: dict[str, tuple[int, int]]) -> str:
114115
return result
115116

116117

118+
def count_steps(path: str, count: int) -> dict[str, int]:
119+
cur = "A"
120+
counts = defaultdict(int)
121+
122+
for c in path:
123+
step = shortest_dirpad(cur, c)
124+
cur = c
125+
counts[step] += count
126+
127+
return counts
128+
129+
117130
class DayRunner(SeparateRunner):
118131
@classmethod
119132
def part1(cls, input: str) -> int:
@@ -128,5 +141,19 @@ def part1(cls, input: str) -> int:
128141
return result
129142

130143
@classmethod
131-
def part2(cls, input: str) -> int:
132-
pass
144+
def part2(cls, input: str, robots=25) -> int:
145+
result = 0
146+
for code in input.strip().split("\n"):
147+
numpad = encode_shortest_numpad(code)
148+
keypresses = Counter([numpad])
149+
150+
for _ in range(robots + 1):
151+
new_presses = Counter()
152+
for subroute, count in keypresses.items():
153+
new_presses.update(count_steps(subroute, count))
154+
155+
keypresses = new_presses
156+
157+
result += int(code[:-1]) * keypresses.total()
158+
159+
return result

2024/tests/test_day21.py

+4
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,7 @@ def test_encode_shortest_dirpad_twice(code: str, answer: str) -> None:
4949

5050
def test_sample_part1() -> None:
5151
assert DayRunner.part1(get_data(21)) == 126384
52+
53+
54+
def test_sample_part2() -> None:
55+
assert DayRunner.part2(get_data(21), robots=2) == 126384

0 commit comments

Comments
 (0)