-
Notifications
You must be signed in to change notification settings - Fork 0
/
2022_7_filesystem.py
74 lines (60 loc) · 2.18 KB
/
2022_7_filesystem.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
import re
from functools import cached_property
from itertools import chain
class Directory:
def __init__(self, parent):
self.parent = parent
self.subdirectories = {}
self.files = {}
def get_relative_directory(self, path):
if path == '/':
return base_directory
if path == '..':
return self.parent
return self.subdirectories[path]
def add_subdirectory(self, name):
self.subdirectories[name] = self.subdirectories.get(
name, Directory(self))
def add_file(self, name, size):
self.files[name] = size
@cached_property
def size(self):
total_file_size = sum(self.files.values())
total_subdirectory_size = sum(dir.size
for dir in self.subdirectories.values())
return total_file_size + total_subdirectory_size
def get_directories(self):
return chain([self], *[dir.get_directories() for dir in self.subdirectories.values()])
cd_pattern = re.compile(r"\$ cd (.+)")
ls_pattern = re.compile(r"\$ ls")
dir_pattern = re.compile(r"dir (.+)")
file_pattern = re.compile(r"(\d+) (.+)")
base_directory = Directory(None)
lines = (line.strip() for line in open("2022_7_filesystem_input.txt"))
current_directory = base_directory
for line in lines:
match = cd_pattern.match(line)
if match:
current_directory = current_directory.get_relative_directory(
match.group(1))
continue
match = ls_pattern.match(line)
if match:
continue
match = dir_pattern.match(line)
if match:
current_directory.add_subdirectory(match.group(1))
continue
match = file_pattern.match(line)
if match:
current_directory.add_file(match.group(2), int(match.group(1)))
continue
raise Exception("Unexpected line type")
print(sum(dir.size for dir in base_directory.get_directories() if dir.size <= 100000))
total_space = 70000000
needed_space = 30000000
space_used = base_directory.size
free_space = total_space - space_used
extra_space_needed = needed_space - free_space
print(min(dir.size for dir in base_directory.get_directories()
if dir.size >= extra_space_needed))