2022/day7/common.py
2024-12-01 19:53:34 +01:00

72 lines
2.2 KiB
Python

from __future__ import annotations
import re
from dataclasses import dataclass
@dataclass
class File:
name: str
size: int
def __equals__(self, other):
return self.name == other.name and self.size == other.size
@dataclass
class Folder:
name: str
parent: Folder | None
children: list[Folder | File]
def __equals__(self, other):
return self.name == other.name and self.parent == other.parent
@property
def full_name(self):
if self.parent is None:
return "/"
else:
return self.parent.full_name + f"/{self.name}"
@property
def size(self):
return sum(map(lambda x: x.size, self.children))
def __lt__(self, other):
return self.size < other.size
def pretty_print(folder: Folder, depth: int = 0) -> None:
print("".join([" " for i in range(depth + 1)]), end="- ")
print(f"{folder.name} (dir)")
for object in folder.children:
if type(object) is Folder:
pretty_print(object, depth + 1)
else:
print("".join([" " for i in range(depth + 2)]), end="- ")
print(f"{object.name} (file, size={object.size})")
def parse(filename: str) -> Folder:
filesystem = Folder(name="/", parent=None, children=[])
with open(filename) as f:
f.readline()
current = filesystem
while line := f.readline()[:-1]:
if line[0] == "$":
if match := re.match(r"\$ cd (.+)", line):
folder_name = match.group(1)
if folder_name != "..":
current = filter(lambda x: x.name == folder_name, current.children).__next__()
else:
current = current.parent
else:
if match := re.match(r"(\d+) ((?:\w|.)+)", line):
fichier = File(name=match.group(2), size=int(match.group(1)))
current.children.append(fichier)
elif match := re.match(r"dir (\w+)", line):
folder = Folder(name=match.group(1), parent=current, children=[])
current.children.append(folder)
return filesystem