Skip to content

Commit cb4ce21

Browse files
committed
Add solution to 2024-12-21
1 parent 90e7bdb commit cb4ce21

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

2024/day21/solutions.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from itertools import pairwise
2+
import networkx as nx
3+
from functools import cache
4+
5+
with open("input") as f:
6+
ls = f.read().strip().split("\n")
7+
8+
9+
numpad = {
10+
0: "7",
11+
1j: "8",
12+
2j: "9",
13+
1: "4",
14+
1 + 1j: "5",
15+
1 + 2j: "6",
16+
2: "1",
17+
2 + 1j: "2",
18+
2 + 2j: "3",
19+
3: None,
20+
3 + 1j: "0",
21+
3 + 2j: "A",
22+
}
23+
24+
keypad = {
25+
0: None,
26+
1j: "^",
27+
2j: "A",
28+
1: "<",
29+
1 + 1j: "v",
30+
1 + 2j: ">",
31+
}
32+
33+
fourdir = {1: "v", -1: "^", 1j: ">", -1j: "<"}
34+
35+
36+
def shortest_paths(grid):
37+
G = nx.DiGraph((z, z + dz) for z in grid for dz in fourdir if grid.get(z + dz))
38+
39+
return {
40+
(grid[start], grid[end]): [
41+
"".join(fourdir[v - u] for u, v in pairwise(path)) for path in paths
42+
]
43+
for start, ends in nx.all_pairs_all_shortest_paths(G)
44+
for end, paths in ends.items()
45+
}
46+
47+
48+
shortest_numpad = shortest_paths(numpad)
49+
shortest_keypad = shortest_paths(keypad)
50+
51+
52+
@cache
53+
def shortest_path_length(bot, keys, target_bot):
54+
if bot == target_bot + 1:
55+
return len(keys)
56+
all_shortest = shortest_keypad if bot else shortest_numpad
57+
return sum(
58+
min(
59+
shortest_path_length(bot + 1, path + "A", target_bot)
60+
for path in all_shortest[start, end]
61+
)
62+
for start, end in pairwise("A" + keys)
63+
)
64+
65+
66+
for target_bot in 2, 25:
67+
print(
68+
sum(int(code[:-1]) * shortest_path_length(0, code, target_bot) for code in ls)
69+
)

0 commit comments

Comments
 (0)