aoc2022/07/parser.py
2022-12-10 18:09:57 +01:00

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()))