-
Notifications
You must be signed in to change notification settings - Fork 0
/
07.py
93 lines (69 loc) · 2.52 KB
/
07.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from pathlib import Path
from typing import Optional, cast
class DirectoryElement:
name: str
size: int
class File(DirectoryElement):
def __init__(self, name: str, size: int):
self.name = name
self.size = size
class Directory(DirectoryElement):
def __init__(self, name: str, contents: dict[str, DirectoryElement], parent_dir: Optional["Directory"]):
self.name = name
self.contents = contents
self.parent_dir = parent_dir
@property
def size(self):
return sum([item.size for item in self.contents.values()])
def get_dir_sizes(root_dir: Directory) -> list[int]:
result = [root_dir.size]
for content in root_dir.contents.values():
if isinstance(content, Directory):
result.extend(get_dir_sizes(content))
return result
def part_a(contents: str):
root_dir = parse_directory_tree(contents)
return sum([
size
for size in get_dir_sizes(root_dir)
if size <= 100000
])
def part_b(contents: str):
root_dir = parse_directory_tree(contents)
update_size = 30_000_000
total_size = 70_000_000
used_space = root_dir.size
free_space = total_size - used_space
space_to_delete = update_size - free_space
return min(size for size in get_dir_sizes(root_dir) if size >= space_to_delete)
def parse_directory_tree(contents: str) -> Directory:
root_dir = Directory("/", {}, None)
current_directory: Directory = root_dir
for line in contents.split("\n"):
if line.startswith("$ "):
# $ cd /
if line.startswith("$ cd "):
_, cmd, arg = line.split(" ")
if cmd == "cd":
if arg == "/":
current_directory = root_dir
elif arg == "..":
current_directory = current_directory.parent_dir
else:
current_directory = cast(Directory, current_directory.contents[arg])
else:
if line.startswith("dir "):
# dir potato
_, name = line.split(" ")
current_directory.contents[name] = Directory(name, {}, current_directory)
else:
# 123 potato
size, name = line.split(" ")
current_directory.contents[name] = File(name, int(size))
return root_dir
def main():
contents = Path("07_input.txt").read_text().strip()
print(part_a(contents))
print(part_b(contents))
if __name__ == "__main__":
main()