Solve 2024:21 p1 "Keypad Conundrum"
Early versions of the code used Manhattan distance instead of BFS to find the movements. Turns out this was covering about 80% of all cases.
This commit is contained in:
parent
72574e753f
commit
3a9a7d4994
2 changed files with 136 additions and 0 deletions
|
|
@ -23,6 +23,13 @@ DD = {
|
||||||
"L": (0, -1),
|
"L": (0, -1),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DDa = {
|
||||||
|
"^": (-1, 0),
|
||||||
|
">": (0, 1),
|
||||||
|
"v": (1, 0),
|
||||||
|
"<": (0, -1),
|
||||||
|
}
|
||||||
|
|
||||||
# Adjacent relative positions including diagonals for 2D matrices, in the order NW, N, NE, W, E, SW, S, SE
|
# Adjacent relative positions including diagonals for 2D matrices, in the order NW, N, NE, W, E, SW, S, SE
|
||||||
ADJ = [
|
ADJ = [
|
||||||
(-1, -1),
|
(-1, -1),
|
||||||
|
|
|
||||||
129
2024-python/output/day_21.py
Normal file
129
2024-python/output/day_21.py
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
import re
|
||||||
|
from collections import deque, Counter, defaultdict
|
||||||
|
from heapq import heappop, heappush
|
||||||
|
from itertools import compress, combinations, chain, permutations
|
||||||
|
from functools import cache
|
||||||
|
|
||||||
|
from output import matrix, D, DD, DDa, ADJ, ints, mhd, mdbg, vdbg, cw, ccw
|
||||||
|
|
||||||
|
DKP = {
|
||||||
|
"^": (0, 1),
|
||||||
|
"A": (0, 2),
|
||||||
|
"<": (1, 0),
|
||||||
|
"v": (1, 1),
|
||||||
|
">": (1, 2),
|
||||||
|
}
|
||||||
|
|
||||||
|
NKP = {
|
||||||
|
"7": (0, 0),
|
||||||
|
"8": (0, 1),
|
||||||
|
"9": (0, 2),
|
||||||
|
"4": (1, 0),
|
||||||
|
"5": (1, 1),
|
||||||
|
"6": (1, 2),
|
||||||
|
"1": (2, 0),
|
||||||
|
"2": (2, 1),
|
||||||
|
"3": (2, 2),
|
||||||
|
"0": (3, 1),
|
||||||
|
"A": (3, 2),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def solve(data):
|
||||||
|
codes = data.split()
|
||||||
|
p1 = 0
|
||||||
|
for code in codes:
|
||||||
|
seqlen = unwrap(code)
|
||||||
|
num = int(code[:-1])
|
||||||
|
p1 += num * seqlen
|
||||||
|
p2 = None
|
||||||
|
return p1, p2
|
||||||
|
|
||||||
|
|
||||||
|
def unwrap(dests):
|
||||||
|
seqlen = float("inf")
|
||||||
|
for num_path in press(dests, NKP):
|
||||||
|
for d0_path in press(num_path, DKP):
|
||||||
|
for d1_path in press(d0_path, DKP):
|
||||||
|
seqlen = min(seqlen, len(d1_path))
|
||||||
|
return seqlen
|
||||||
|
|
||||||
|
|
||||||
|
def press(dests, pad):
|
||||||
|
s = "A"
|
||||||
|
P = [""]
|
||||||
|
for d in dests:
|
||||||
|
paths = bfs(tuple(pad.values()), pad[s], pad[d])
|
||||||
|
ml = len(sorted(paths, key=lambda x: len(x))[0])
|
||||||
|
sp = [p for p in paths if len(p) == ml]
|
||||||
|
nP = []
|
||||||
|
for a in P:
|
||||||
|
for b in sp:
|
||||||
|
nP.append(a + b)
|
||||||
|
P = nP
|
||||||
|
s = d
|
||||||
|
P = sorted(P, key=lambda x: len(x))
|
||||||
|
psl = len(P[0])
|
||||||
|
return [p for p in P if len(p) == psl]
|
||||||
|
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def bfs(grid, S, E):
|
||||||
|
seen = set()
|
||||||
|
Q = deque([(S, "<", "")])
|
||||||
|
paths = []
|
||||||
|
while Q:
|
||||||
|
pos, dn, path = Q.popleft()
|
||||||
|
if (pos, dn) in seen:
|
||||||
|
continue
|
||||||
|
if pos == E:
|
||||||
|
paths.append(path + "A")
|
||||||
|
continue
|
||||||
|
seen.add((pos, dn))
|
||||||
|
y, x = pos
|
||||||
|
for dn, delta in DDa.items():
|
||||||
|
dy, dx = delta
|
||||||
|
if (y + dy, x + dx) in grid:
|
||||||
|
Q.append(((y + dy, x + dx), dn, path + dn))
|
||||||
|
return paths
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import os
|
||||||
|
|
||||||
|
# use dummy data
|
||||||
|
inp = """
|
||||||
|
029A
|
||||||
|
980A
|
||||||
|
179A
|
||||||
|
456A
|
||||||
|
379A
|
||||||
|
""".strip()
|
||||||
|
|
||||||
|
"""
|
||||||
|
68 * 29
|
||||||
|
60 * 980
|
||||||
|
68 * 179
|
||||||
|
64 * 456
|
||||||
|
64 * 379
|
||||||
|
"""
|
||||||
|
|
||||||
|
# uncomment to instead use stdin
|
||||||
|
# import sys; inp = sys.stdin.read().strip()
|
||||||
|
|
||||||
|
# uncomment to use AoC provided puzzle input
|
||||||
|
with open("./input/21.txt", "r") as f:
|
||||||
|
inp = f.read().strip()
|
||||||
|
|
||||||
|
# uncomment to do initial data processing shared by part 1-2
|
||||||
|
p1, p2 = solve(inp)
|
||||||
|
|
||||||
|
print(p1)
|
||||||
|
os.system(f"echo {p1} | wl-copy")
|
||||||
|
# print(p2)
|
||||||
|
# os.system(f"echo {p2} | wl-copy")
|
||||||
|
|
||||||
|
# uncomment and replace 0 with actual output to refactor code
|
||||||
|
# and ensure nonbreaking changes
|
||||||
|
# assert p1 == 0
|
||||||
|
# assert p2 == 0
|
||||||
Loading…
Add table
Reference in a new issue