diff --git a/2024-python/aoc.py b/2024-python/aoc.py index 11e1df3..dd867ee 100644 --- a/2024-python/aoc.py +++ b/2024-python/aoc.py @@ -29,7 +29,7 @@ from collections import deque, Counter, defaultdict from heapq import heappop, heappush from itertools import compress, combinations, chain, permutations -from output import matrix, D, DD, ADJ, ints, mhd, mdbg, vdbg, cw, ccw +from output import matrix, D, DD, ADJ, ints, mhd, mdbg, vdbg, cw, ccw, bk def solve(data): diff --git a/2024-python/output/day_21.py b/2024-python/output/day_21.py index 5fa1a51..a9efe8c 100644 --- a/2024-python/output/day_21.py +++ b/2024-python/output/day_21.py @@ -1,11 +1,5 @@ -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), @@ -32,98 +26,42 @@ NKP = { def solve(data): codes = data.split() p1 = 0 + p2 = 0 for code in codes: - seqlen = unwrap(code) num = int(code[:-1]) - p1 += num * seqlen - p2 = None + p1 += num * unfold(code, 1 + 2, num=True) + p2 += num * unfold(code, 1 + 25, num=True) 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): +@cache +def unfold(sequence, iterations, num=False): + if iterations == 0: + return len(sequence) 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 + total = 0 + pad, invalid = (NKP, (3, 0)) if num else (DKP, (0, 0)) + for d in sequence: + total += unfold(seq(pad[s], pad[d], invalid), iterations - 1) s = d - P = sorted(P, key=lambda x: len(x)) - psl = len(P[0]) - return [p for p in P if len(p) == psl] + return total @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 +def seq(S, E, invalid): + y1, x1 = S + y2, x2 = E + seq = "<" * (x1 - x2) + "v" * (y2 - y1) + "^" * (y1 - y2) + ">" * (x2 - x1) + if (y2, x1) == invalid or (y1, x2) == invalid: + seq = seq[::-1] + return seq + "A" 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 + print(p2)