From 786be99a7ab360de987ec1e53399005f1e264dd3 Mon Sep 17 00:00:00 2001 From: Michal Kunc Date: Sat, 10 Dec 2022 18:09:57 +0100 Subject: [PATCH] Add day 7 solution --- 07/example | 23 ++++++++++++++++ 07/parser.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 07/example create mode 100644 07/parser.py diff --git a/07/example b/07/example new file mode 100644 index 0000000..09a921e --- /dev/null +++ b/07/example @@ -0,0 +1,23 @@ +$ cd / +$ ls +dir a +14848514 b.txt +8504156 c.dat +dir d +$ cd a +$ ls +dir e +29116 f +2557 g +62596 h.lst +$ cd e +$ ls +584 i +$ cd .. +$ cd .. +$ cd d +$ ls +4060174 j +8033020 d.log +5626152 d.ext +7214296 k diff --git a/07/parser.py b/07/parser.py new file mode 100644 index 0000000..5fb98b8 --- /dev/null +++ b/07/parser.py @@ -0,0 +1,77 @@ + +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())) \ No newline at end of file