aoc2022/day07.py

94 lines
2.5 KiB
Python

from collections import deque
from tools.aoc import AOCDay
from typing import Any
class File:
def __init__(self, name: str, size: int):
self.name = name
self.size = size
class Dir:
def __init__(self, name: str, parent: 'Dir' = None):
self.name = name
self.parent = parent
self.dirs = []
self.files = []
def getSize(self):
files = sum(x.size for x in self.files)
return files + sum(x.getSize() for x in self.dirs)
class Day(AOCDay):
inputs = [
[
(95437, "input7_test"),
(1844187, "input7_dennis"),
(1367870, "input7"),
],
[
(24933642, "input7_test"),
(4978279, "input7_dennis"),
(549173, "input7"),
]
]
def get_dir_struct(self) -> Dir:
current_dir = None
for line in self.getInput():
if line.startswith("$"): # command
cmd = line[2:].split(" ")
if cmd[0] == 'cd':
if cmd[1] == "..":
current_dir = current_dir.parent
else:
current_dir = Dir(cmd[1], current_dir)
if current_dir.parent is not None:
current_dir.parent.dirs.append(current_dir)
continue
file = line.split(" ")
if file[0] != 'dir':
file_size = int(file[0])
current_dir.files.append(File(file[1], file_size))
while current_dir.parent:
current_dir = current_dir.parent
return current_dir
def get_sizes(self) -> (int, int):
root = self.get_dir_struct()
need_free = 30_000_000 - (70_000_000 - root.getSize())
smallest = 1e20
queue = deque()
queue.append(root)
sum_size = 0
while queue:
current_dir = queue.popleft()
dir_size = current_dir.getSize()
if dir_size <= 100_000:
sum_size += dir_size
if need_free <= dir_size < smallest:
smallest = dir_size
for sub_dir in current_dir.dirs:
queue.append(sub_dir)
return sum_size, smallest
def part1(self) -> Any:
ret, _ = self.get_sizes()
return ret
def part2(self) -> Any:
_, ret = self.get_sizes()
return ret
if __name__ == '__main__':
day = Day(2022, 7)
day.run(verbose=True)