A day07/day07.py => day07/day07.py +89 -0
@@ 0,0 1,89 @@
+#! /usr/bin/env python3
+# vim:fenc=utf-8
+#
+# Copyright © 2022 Adrian Perez de Castro <aperez@igalia.com>
+#
+# Distributed under terms of the MIT license.
+
+from dataclasses import dataclass, field
+from pathlib import PosixPath as Path
+
+@dataclass
+class Entry:
+ name: str
+
+@dataclass
+class File(Entry):
+ size: int
+
+@dataclass
+class Directory(Entry):
+ entries: list[Entry] = field(default_factory=list)
+
+ def walk(self, p: Path):
+ return self.__walk(p.parts)
+
+ def __walk(self, p: tuple[str]):
+ if len(p) == 0:
+ return self
+ elif p[0] == "/":
+ return top.__walk(p[1:])
+ else:
+ for item in self.entries:
+ if item.name == p[0]:
+ if len(p) == 1:
+ return item
+ else:
+ assert isinstance(item, Directory)
+ return item.__walk(p[1:])
+ raise KeyError(p[0])
+
+ @property
+ def size(self):
+ return sum(item.size for item in self.entries)
+
+ def find(self, predicate):
+ if predicate(self):
+ yield self
+ for item in self.entries:
+ if isinstance(item, Directory):
+ yield from item.find(predicate)
+
+
+pwd = Path("/")
+top = Directory(name="/")
+cur = top
+
+import sys
+
+for line in sys.stdin.readlines():
+ items = line.strip().split()
+ assert len(items) >= 2
+ if items[0] == "$":
+ if items[1] == "cd":
+ assert len(items) == 3
+ if items[2] == "/":
+ pwd = Path("/")
+ elif items[2] == "..":
+ pwd = pwd.parent
+ else:
+ pwd = pwd / items[2]
+ elif items[1] == "ls":
+ assert len(items) == 2
+ cur = top.walk(pwd)
+ else:
+ assert False, "Unreachable"
+ else:
+ assert len(items) == 2
+ if items[0] == "dir":
+ cur.entries.append(Directory(items[1]))
+ else:
+ cur.entries.append(File(items[1], int(items[0])))
+
+if len(sys.argv) > 1:
+ for item in sys.argv[1:]:
+ print(top.walk(Path(item)).size)
+ raise SystemExit
+
+# Find all directories with a size at most 100000
+print(sum(item.size for item in top.find(lambda item: item.size <= 100000)))
A day07/day07.test => day07/day07.test +23 -0
@@ 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