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