From ded5c4f28c984a2452e8dc2205c3b833c3f2a7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Engl=C3=B6f=20Ytterstr=C3=B6m?= Date: Thu, 19 Dec 2024 10:10:44 +0100 Subject: [PATCH] Solve 2024:19 p1-2 "Linen Layout" Initial tries to use a while loop instead of recursion gave a classic AoC situation: test cases worked, but not actual AoC puzzle input. Turns out I only considererd removing the longest pattern form the design, rather than consider all possible removals. Some Python goodies in here: - `"abcdefgh".startswith("abc")` instead of regexp. - removeprefix() is nice, and in some cases more readable. `"abcdefgh".removeprefix("abc")` vs `"abcdefgh[3:]" - To speed things up for pt 2, functools is used which requires a dict to be hashed as a tuple. If one wish to solve this without recursion, a BFS solution is most likely the way to go. def ispossible(design, patterns): Q = [design] possible = 0 while Q: remaining = Q.pop(0) if not remaining: possible += 1 continue for pattern in patterns[remaining[0]]: if remaining.startswith(pattern): Q.append(remaining.removeprefix(pattern)) return possible --- 2024-python/output/day_19.py | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 2024-python/output/day_19.py diff --git a/2024-python/output/day_19.py b/2024-python/output/day_19.py new file mode 100644 index 0000000..77e8688 --- /dev/null +++ b/2024-python/output/day_19.py @@ -0,0 +1,39 @@ +from functools import cache +from collections import defaultdict + + +def solve(data): + patterns, designs = data.split("\n\n") + patterns = sorted(patterns.split(", "), key=lambda s: -len(s)) + designs = designs.split() + + hashed = defaultdict(list) + for p in patterns: + hashed[p[0]].append(p) + hashed = tuple([(k, tuple(v)) for k, v in hashed.items()]) + + possible = sum(ispossible(d, hashed) > 0 for d in designs) + every_possibility = sum(ispossible(d, hashed) for d in designs) + return possible, every_possibility + + +@cache +def ispossible(remaining, patterns): + if not remaining: + return 1 + selected = dict(patterns).get(remaining[0], []) + return sum( + ispossible(remaining.removeprefix(pattern), patterns) + for pattern in selected + if remaining.startswith(pattern) + ) + + +if __name__ == "__main__": + with open("./input/19.txt", "r") as f: + inp = f.read().strip() + + p1, p2 = solve(inp) + + print(p1) + print(p2)