Skip to content

Commit 5eb80da

Browse files
committed
day07
1 parent 48c189e commit 5eb80da

File tree

3 files changed

+1160
-1
lines changed

3 files changed

+1160
-1
lines changed

2022/07/__init__.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import functools
2+
from pprint import pformat
3+
from typing import Literal
4+
5+
6+
def cast_input(inputs: str):
7+
def parse_ls(line: str):
8+
info, name = line.split()
9+
return info if info == 'dir' else int(info), name
10+
11+
def parse_output(output: str):
12+
if not output:
13+
return []
14+
15+
return list(map(parse_ls, filter(bool, output.split('\n'))))
16+
17+
def parse_interactivity(interactivity: str):
18+
in_, out = interactivity.split('\n', maxsplit=1)
19+
return in_, parse_output(out)
20+
21+
return list(map(parse_interactivity, filter(bool, inputs.split('$ '))))
22+
23+
24+
class Pwd:
25+
def __init__(self):
26+
self._pwd: list[str] = []
27+
28+
def cd(self, d: str):
29+
if d != '..':
30+
return self._pwd.append(d)
31+
32+
self._pwd.pop()
33+
34+
@property
35+
def curr(self):
36+
return self._pwd[1:]
37+
38+
39+
class Dir:
40+
def __init__(self):
41+
self.dirs: dict[str, Dir] = {}
42+
self.files: dict[str, int] = {}
43+
44+
def read_ls(self, pwd: list[str], infos: list[tuple[int | Literal['dir'], str]]):
45+
if pwd:
46+
p, *ps = pwd
47+
self.dirs[p].read_ls(ps, infos)
48+
return
49+
50+
for info, name in infos:
51+
if info == 'dir':
52+
self.dirs[name] = Dir()
53+
continue
54+
self.files[name] = info
55+
56+
@property
57+
@functools.cache
58+
def size(self):
59+
s = sum(self.files.values())
60+
return s + sum(d.size for d in self.dirs.values()) # type: ignore
61+
62+
def size_at_most(self, n: int):
63+
s = self.size if self.size <= n else 0
64+
return s + sum(d.size_at_most(n) for d in self.dirs.values())
65+
66+
def __repr__(self):
67+
return pformat(self.files | self.dirs)
68+
69+
70+
def create_root(inputs: list[tuple[str, list[tuple[int | Literal['dir'], str]]]]):
71+
root = Dir()
72+
pwd = Pwd()
73+
for in_, out in inputs:
74+
if in_.startswith('cd '):
75+
cd, d = in_.split(maxsplit=1)
76+
pwd.cd(d)
77+
continue
78+
root.read_ls(pwd.curr, out)
79+
return root
80+
81+
82+
def part1(inputs):
83+
return create_root(inputs).size_at_most(100000)
84+
85+
86+
def part2(inputs):
87+
root = create_root(inputs)
88+
result = root.size
89+
target_size = 30000000 - (70000000 - root.size)
90+
q = root.dirs.values()
91+
while q: # bfs
92+
n = []
93+
for d in q:
94+
size = d.size
95+
if size >= target_size:
96+
result = min(result, size)
97+
n.extend(d.dirs.values())
98+
q = n
99+
return result

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy