Skip to content

Commit 3f84a4f

Browse files
committed
feat: 2024 day 21
1 parent 6c76d7c commit 3f84a4f

File tree

2 files changed

+150
-21
lines changed

2 files changed

+150
-21
lines changed

2024/21ab.py

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
from aoc import *
2+
from itertools import pairwise, product
3+
from functools import cache
4+
5+
numkey = {
6+
7: (0, 0),
7+
8: (0, 1),
8+
9: (0, 2),
9+
4: (1, 0),
10+
5: (1, 1),
11+
6: (1, 2),
12+
1: (2, 0),
13+
2: (2, 1),
14+
3: (2, 2),
15+
0: (3, 1),
16+
'A': (3, 2),
17+
}
18+
numkey_positions = set(numkey.values())
19+
20+
dirkey = {
21+
'^': (0, 1),
22+
'A': (0, 2),
23+
'<': (1, 0),
24+
'v': (1, 1),
25+
'>': (1, 2),
26+
}
27+
dirkey_positions = set(dirkey.values())
28+
29+
DIRS = ((-1, 0), (0, 1), (1, 0), (0, -1))
30+
KEY_TO_DIR = {
31+
'^': (-1, 0),
32+
'>': (0, 1),
33+
'v': (1, 0),
34+
'<': (0, -1),
35+
}
36+
37+
38+
def is_ok(start, sequence, keypad_positions):
39+
positions = [start]
40+
for press in sequence:
41+
positions.append(
42+
(
43+
positions[-1][0] + KEY_TO_DIR[press][0],
44+
positions[-1][1] + KEY_TO_DIR[press][1],
45+
)
46+
)
47+
return all(pos in keypad_positions for pos in positions)
48+
49+
50+
def find_shortest(f, t, postrans, keypad_positions):
51+
fpos = postrans[f]
52+
tpos = postrans[t]
53+
diff = fpos[0] - tpos[0], fpos[1] - tpos[1]
54+
charh = '<' if diff[1] > 0 else '>'
55+
charv = '^' if diff[0] > 0 else 'v'
56+
possible = {
57+
tuple(charh * abs(diff[1])) + tuple(charv * abs(diff[0])),
58+
tuple(charv * abs(diff[0])) + tuple(charh * abs(diff[1])),
59+
}
60+
possible = list(
61+
filter(lambda x: is_ok(fpos, x, keypad_positions), possible)
62+
)
63+
return possible
64+
65+
66+
@cache
67+
def shortest_numpad(src: int | str, dest: int | str, depth: int):
68+
seq = []
69+
for path in numkey_paths[src, dest]:
70+
# path = numkey_paths[src, dest][0]
71+
# seq = ''
72+
s = 0
73+
for nsrc, ndest in pairwise(('A',) + path + ('A',)):
74+
s += shortest_dir(nsrc, ndest, depth)
75+
seq.append(s)
76+
return min(seq)
77+
78+
79+
@cache
80+
def shortest_dir(src: str, dest: str, depth: int):
81+
if not depth:
82+
return 1
83+
return dest
84+
seq = []
85+
for path in dirkey_paths[src, dest]:
86+
# seq = ''
87+
s = 0
88+
for nsrc, ndest in pairwise(('A',) + path + ('A',)):
89+
s += shortest_dir(nsrc, ndest, depth - 1)
90+
seq.append(s)
91+
return min(seq)
92+
93+
94+
def main(infi: str, depth: int):
95+
inp = lines_stripped(infi)
96+
global numkey_paths
97+
global dirkey_paths
98+
numkey_paths = {
99+
(fromto[0], fromto[1]): find_shortest(*fromto, numkey, numkey_positions)
100+
for fromto in product(numkey.keys(), repeat=2)
101+
}
102+
dirkey_paths = {
103+
(fromto[0], fromto[1]): find_shortest(*fromto, dirkey, dirkey_positions)
104+
for fromto in product(dirkey.keys(), repeat=2)
105+
}
106+
107+
s = 0
108+
for l in inp:
109+
numbers = list(map(int, l[:-1]))
110+
path = tuple(numbers + list(l[-1]))
111+
seq = 0
112+
for nsrc, ndest in pairwise(('A',) + path):
113+
adding = shortest_numpad(nsrc, ndest, depth)
114+
seq += adding
115+
s += seq * int(l[:-1])
116+
117+
return s
118+
119+
120+
DAY = 21
121+
FILE_TEST = f"{DAY}_testa.txt"
122+
# FILE_TEST = f"{DAY}_testb.txt"
123+
FILE_EXP = f"{DAY}_exp.txt"
124+
FILE = f"{DAY}.txt"
125+
# test_and_submit(main, FILE_TEST, FILE_EXP, FILE, DAY)
126+
# print(main(FILE_TEST))
127+
print(main(FILE, 2))
128+
print(main(FILE, 25))

README.org

+22-21
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,28 @@
22
Solutions in *Python*. I'm using the =advent-of-code-data= package to submit
33
my answers.
44
* Personal Stats 2024
5-
| Day | Time | Rank | Score | Time | Rank | Score |
6-
|-----+----------+------+-------+----------+-------+-------|
7-
| 23 | 00:24:26 | 2632 | 0 | 01:09:24 | 2938 | 0 |
8-
| 22 | 00:07:06 | 766 | 0 | 05:23:29 | 7143 | 0 |
9-
| 19 | 01:44:22 | 6641 | 0 | 01:50:06 | 5444 | 0 |
10-
| 17 | 00:27:08 | 1748 | 0 | 07:06:10 | 5688 | 0 |
11-
| 15 | 00:32:17 | 2397 | 0 | 02:59:49 | 4379 | 0 |
12-
| 14 | 00:19:09 | 1902 | 0 | 01:13:46 | 3551 | 0 |
13-
| 13 | 00:39:23 | 4308 | 0 | 12:34:52 | 21706 | 0 |
14-
| 12 | 00:43:21 | 4911 | 0 | >24h | 27971 | 0 |
15-
| 11 | 00:16:43 | 4574 | 0 | 04:24:24 | 13605 | 0 |
16-
| 10 | 00:54:16 | 7416 | 0 | 00:56:37 | 6784 | 0 |
17-
| 9 | 00:39:02 | 4986 | 0 | 10:22:50 | 20801 | 0 |
18-
| 8 | 00:20:56 | 2671 | 0 | 00:32:01 | 2868 | 0 |
19-
| 7 | 00:12:12 | 1988 | 0 | 00:14:41 | 1405 | 0 |
20-
| 6 | 00:14:23 | 2159 | 0 | 05:31:24 | 15698 | 0 |
21-
| 5 | 00:14:31 | 2554 | 0 | 00:26:53 | 2592 | 0 |
22-
| 4 | 00:21:24 | 4410 | 0 | 00:42:23 | 5290 | 0 |
23-
| 3 | 00:08:31 | 3378 | 0 | 00:16:11 | 2633 | 0 |
24-
| 2 | 00:10:49 | 3106 | 0 | 00:39:31 | 6052 | 0 |
25-
| 1 | 00:04:51 | 1876 | 0 | 00:08:59 | 2365 | 0 |
5+
| Day | Time | Rank | Score | Time | Rank | Score |
6+
|-----+----------+-------+-------+----------+-------+-------|
7+
| 23 | 00:24:26 | 2632 | 0 | 01:09:24 | 2938 | 0 |
8+
| 22 | 00:07:06 | 766 | 0 | 05:23:29 | 7143 | 0 |
9+
| 21 | >24h | 15115 | 0 | >24h | 11364 | 0 |
10+
| 19 | 01:44:22 | 6641 | 0 | 01:50:06 | 5444 | 0 |
11+
| 17 | 00:27:08 | 1748 | 0 | 07:06:10 | 5688 | 0 |
12+
| 15 | 00:32:17 | 2397 | 0 | 02:59:49 | 4379 | 0 |
13+
| 14 | 00:19:09 | 1902 | 0 | 01:13:46 | 3551 | 0 |
14+
| 13 | 00:39:23 | 4308 | 0 | 12:34:52 | 21706 | 0 |
15+
| 12 | 00:43:21 | 4911 | 0 | >24h | 27971 | 0 |
16+
| 11 | 00:16:43 | 4574 | 0 | 04:24:24 | 13605 | 0 |
17+
| 10 | 00:54:16 | 7416 | 0 | 00:56:37 | 6784 | 0 |
18+
| 9 | 00:39:02 | 4986 | 0 | 10:22:50 | 20801 | 0 |
19+
| 8 | 00:20:56 | 2671 | 0 | 00:32:01 | 2868 | 0 |
20+
| 7 | 00:12:12 | 1988 | 0 | 00:14:41 | 1405 | 0 |
21+
| 6 | 00:14:23 | 2159 | 0 | 05:31:24 | 15698 | 0 |
22+
| 5 | 00:14:31 | 2554 | 0 | 00:26:53 | 2592 | 0 |
23+
| 4 | 00:21:24 | 4410 | 0 | 00:42:23 | 5290 | 0 |
24+
| 3 | 00:08:31 | 3378 | 0 | 00:16:11 | 2633 | 0 |
25+
| 2 | 00:10:49 | 3106 | 0 | 00:39:31 | 6052 | 0 |
26+
| 1 | 00:04:51 | 1876 | 0 | 00:08:59 | 2365 | 0 |
2627
* Personal Stats 2023
2728
| Day | Time | Rank | Score | Time | Rank | Score |
2829
| 25 | 00:45:17 | 1080 | 0 | 00:45:20 | 937 | 0 |

0 commit comments

Comments
 (0)