55 lines
1.4 KiB
Python
55 lines
1.4 KiB
Python
|
|
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
|