72 lines
2.3 KiB
Python
Raw Permalink Normal View History

2022-12-07 19:51:29 +01:00
# SPDX-License-Identifier: MIT
# Copyright (c) 2022 Akumatic
#
# https://adventofcode.com/2022/day/7
class Node:
def __init__(self, name, parent = None, size = None) -> None:
self.name = name
self.parent = parent
if parent:
parent.children[name] = self
self.size = size
self.children = dict()
def get_size(self) -> int:
if self.size:
return self.size
return sum(self.children[child].get_size() for child in self.children)
def build_dir_tree(terminal_output: list) -> Node:
root = Node("/")
cur_dir = root
for line in terminal_output:
if line.startswith("$ ls"):
continue # 'else' will deal with output
elif line.startswith("$ cd"):
dir = line[5:]
match dir:
case "/":
cur_dir = root
case "..":
cur_dir = cur_dir.parent
case _:
cur_dir = cur_dir.children[dir]
else: # line not starting with "$" => output of ls
type, name = line.split(" ")
match type:
case "dir":
new_node = Node(name=name, parent=cur_dir)
case _:
new_node = Node(name=name, parent=cur_dir, size=int(type))
return root
def read_file(filename: str = "input.txt") -> Node:
with open(f"{__file__.rstrip('code.py')}{filename}", "r") as f:
lines = [line.strip() for line in f.readlines()]
return build_dir_tree(lines)
def get_possible_folder_sizes(node: Node, target_size: int, size_up_to: bool, sizes: list) -> None:
if len(node.children) == 0:
return
size = node.get_size()
if not size_up_to and size >= target_size or size_up_to and size <= target_size:
sizes.append(size)
for child in node.children:
get_possible_folder_sizes(node.children[child], target_size, size_up_to, sizes)
def part1(node: Node) -> int:
sizes = []
get_possible_folder_sizes(node, 100000, True, sizes)
return sum(sizes)
def part2(node: Node) -> int:
sizes = []
get_possible_folder_sizes(node, node.get_size() - 40000000, False, sizes)
return min(sizes)
if __name__ == "__main__":
vals = read_file()
print(f"Part 1: {part1(vals)}")
print(f"Part 2: {part2(vals)}")