77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
|
|
import fileinput
|
|
from typing import Iterable, Optional
|
|
|
|
class Directory():
|
|
|
|
def __init__(self, parent = None):
|
|
self.dirs = {}
|
|
self.files = {}
|
|
self.parent = parent
|
|
|
|
def get_size(self) -> int:
|
|
return sum(self.files.values()) + sum([d.get_size() for d in self.dirs.values()])
|
|
|
|
def print_tree(self, depth = 0):
|
|
if depth == 0:
|
|
print("/")
|
|
for d, v in self.dirs.items():
|
|
print(" "*(depth+1) + d)
|
|
v.print_tree(depth+1)
|
|
for f, size in self.files.items():
|
|
print(" "*(depth+1) + f + " " + str(size))
|
|
|
|
def walk(self):
|
|
output = [self]
|
|
for d in self.dirs.values():
|
|
output += d.walk()
|
|
return output
|
|
|
|
def parse(lines: Iterable[str]) -> Directory:
|
|
root = None
|
|
cwd = None
|
|
for line in map(lambda x: x.strip(), lines):
|
|
if line.startswith("$ "): # command
|
|
if line == "$ cd /":
|
|
root = Directory()
|
|
cwd = root
|
|
elif line == "$ cd ..":
|
|
cwd = cwd.parent
|
|
elif line.startswith("$ cd"):
|
|
cwd = cwd.dirs[line.split(" ")[2]]
|
|
elif line.startswith("$ ls"):
|
|
pass
|
|
elif line.startswith("dir "): # dir
|
|
name = line.split(' ')[1]
|
|
cwd.dirs[name] = Directory(cwd)
|
|
else: # file
|
|
size, name = line.split(' ')
|
|
cwd.files[name] = int(size)
|
|
return root
|
|
|
|
def solve(lines: Iterable[str]) -> int:
|
|
root = parse(lines)
|
|
output = 0
|
|
for d in root.walk():
|
|
size = d.get_size()
|
|
if size <= 100000:
|
|
output += size
|
|
return output
|
|
|
|
def solveb(lines: Iterable[str]) -> int:
|
|
TOTAL = 70000000
|
|
GOAL = 30000000
|
|
|
|
root = parse(lines)
|
|
current = root.get_size()
|
|
free = TOTAL - current
|
|
to_free = GOAL - free
|
|
print(f"Current: {current}")
|
|
print(f"To free: {to_free}")
|
|
candidates = [d for d in root.walk() if d.get_size() >= to_free]
|
|
return min(map(lambda x: x.get_size(), candidates))
|
|
|
|
if __name__ == "__main__":
|
|
parse(fileinput.input()).print_tree()
|
|
print(solve(fileinput.input()))
|
|
print(solveb(fileinput.input())) |