From 90d5ab203d85beb0c4eb8979bef880351e6c8e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Engl=C3=B6f=20Ytterstr=C3=B6m?= Date: Sun, 23 Nov 2025 23:39:37 +0100 Subject: [PATCH] Solve 2022 day 7 pt 1-2 Funny that I did not mention the problem with recurring directory names in the first run of this puzzle in Elixir, back in 2022 and bb708a5e58. Most likely, the insight flew over my head that time. This time, I realized I could just add the size to the size of each parent. I struggled to find a graph traversal for it, until I realized I did not need the graph. The key rewrite was this: for p in path: fs[p] += size fs["/"] += size ... to this: p = "/" fs[p] += size for dir_name in path: p += f"/{dir_name}" fs[p] += size This solved my issues for 3 hours by acknowledge that - a directory name "a" can accour on multiple places, example: /a, /b/a, /c/a - a directory name "a" can have a parent directory named "a", example: /a/b/a, /a/c/d/a And as always, example input is the devil. Look at the reak input as soon as possible. --- 2022-python/output/day_07.py | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 2022-python/output/day_07.py diff --git a/2022-python/output/day_07.py b/2022-python/output/day_07.py new file mode 100644 index 0000000..60f30c8 --- /dev/null +++ b/2022-python/output/day_07.py @@ -0,0 +1,54 @@ +from collections import defaultdict + +from output import ints + + +def solve(data): + fs = defaultdict(int) + pwd = [] + for cmd in data.splitlines(): + if cmd.startswith("$ ls") or cmd.startswith("dir "): + continue + if cmd.startswith("$ cd"): + d = cmd.split()[-1] + match d: + case "/": + pwd = [] + case "..": + pwd.pop() + case _: + pwd.append(d) + continue + a = "" + w = sum(ints(cmd)) + # in example input, all directories have distinct names. + # + # the puzzle input have repeated directory names, e.g. both + # /d/a and /c/b/a (a subfolder named "a") exists. + # + # Furthermore, puzzle input also has cases of /a/b/a, + # e.g. a recurring across directory path. + # + # Lost several hours due to this. + fs[a] += w + for p in pwd: + a += f"/{p}" + fs[a] += w + p1 = sum(i for i in fs.values() if i <= 100_000) + free = 70_000_000 - fs[""] + needed = 30_000_000 - free + p2 = min(i for i in fs.values() if i >= needed) + return p1, p2 + + +if __name__ == "__main__": + with open("./input/07.txt", "r") as f: + inp = f.read().strip() + + p1, p2 = solve(inp) + + print(p1) + print(p2) + + assert p1 == 1644735 + assert p2 == 1300850