Compare commits
No commits in common. "fc35818fd43fddd4e59996b7b75565beb7902921" and "389e5faed2b035a33e60122ff25e6a5864774d46" have entirely different histories.
fc35818fd4
...
389e5faed2
23
07/example
23
07/example
@ -1,23 +0,0 @@
|
|||||||
$ 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
|
|
77
07/parser.py
77
07/parser.py
@ -1,77 +0,0 @@
|
|||||||
|
|
||||||
import fileinput
|
|
||||||
from typing import Iterable, Optional
|
|
||||||
|
|
||||||
class Directory():
|
|
||||||
|
|
||||||
def __init__(self, parent = None):
|
|
||||||
self.dirs = {}
|
|
||||||
self.files = {}
|
|
||||||
self.parent = parent
|
|
||||||
|
|
||||||
def get_size(self) -> int:
|
|
||||||
return sum(self.files.values()) + sum([d.get_size() for d in self.dirs.values()])
|
|
||||||
|
|
||||||
def print_tree(self, depth = 0):
|
|
||||||
if depth == 0:
|
|
||||||
print("/")
|
|
||||||
for d, v in self.dirs.items():
|
|
||||||
print(" "*(depth+1) + d)
|
|
||||||
v.print_tree(depth+1)
|
|
||||||
for f, size in self.files.items():
|
|
||||||
print(" "*(depth+1) + f + " " + str(size))
|
|
||||||
|
|
||||||
def walk(self):
|
|
||||||
output = [self]
|
|
||||||
for d in self.dirs.values():
|
|
||||||
output += d.walk()
|
|
||||||
return output
|
|
||||||
|
|
||||||
def parse(lines: Iterable[str]) -> Directory:
|
|
||||||
root = None
|
|
||||||
cwd = None
|
|
||||||
for line in map(lambda x: x.strip(), lines):
|
|
||||||
if line.startswith("$ "): # command
|
|
||||||
if line == "$ cd /":
|
|
||||||
root = Directory()
|
|
||||||
cwd = root
|
|
||||||
elif line == "$ cd ..":
|
|
||||||
cwd = cwd.parent
|
|
||||||
elif line.startswith("$ cd"):
|
|
||||||
cwd = cwd.dirs[line.split(" ")[2]]
|
|
||||||
elif line.startswith("$ ls"):
|
|
||||||
pass
|
|
||||||
elif line.startswith("dir "): # dir
|
|
||||||
name = line.split(' ')[1]
|
|
||||||
cwd.dirs[name] = Directory(cwd)
|
|
||||||
else: # file
|
|
||||||
size, name = line.split(' ')
|
|
||||||
cwd.files[name] = int(size)
|
|
||||||
return root
|
|
||||||
|
|
||||||
def solve(lines: Iterable[str]) -> int:
|
|
||||||
root = parse(lines)
|
|
||||||
output = 0
|
|
||||||
for d in root.walk():
|
|
||||||
size = d.get_size()
|
|
||||||
if size <= 100000:
|
|
||||||
output += size
|
|
||||||
return output
|
|
||||||
|
|
||||||
def solveb(lines: Iterable[str]) -> int:
|
|
||||||
TOTAL = 70000000
|
|
||||||
GOAL = 30000000
|
|
||||||
|
|
||||||
root = parse(lines)
|
|
||||||
current = root.get_size()
|
|
||||||
free = TOTAL - current
|
|
||||||
to_free = GOAL - free
|
|
||||||
print(f"Current: {current}")
|
|
||||||
print(f"To free: {to_free}")
|
|
||||||
candidates = [d for d in root.walk() if d.get_size() >= to_free]
|
|
||||||
return min(map(lambda x: x.get_size(), candidates))
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parse(fileinput.input()).print_tree()
|
|
||||||
print(solve(fileinput.input()))
|
|
||||||
print(solveb(fileinput.input()))
|
|
@ -1,6 +0,0 @@
|
|||||||
30373
|
|
||||||
25512
|
|
||||||
65332
|
|
||||||
33549
|
|
||||||
35390
|
|
||||||
|
|
113
08/trees.py
113
08/trees.py
@ -1,113 +0,0 @@
|
|||||||
|
|
||||||
import fileinput
|
|
||||||
|
|
||||||
def get_row(m, idx):
|
|
||||||
return m[idx]
|
|
||||||
|
|
||||||
def get_col(m, idx):
|
|
||||||
return list(map(lambda x: x[idx], m))
|
|
||||||
|
|
||||||
class Forest:
|
|
||||||
|
|
||||||
def __init__(self, width, height):
|
|
||||||
self.visible = []
|
|
||||||
self.heightmap = []
|
|
||||||
self.score = []
|
|
||||||
self.width = width
|
|
||||||
for _ in range(height):
|
|
||||||
self.visible.append([False] * width)
|
|
||||||
self.heightmap.append([0] * width)
|
|
||||||
self.score.append([0] * width)
|
|
||||||
|
|
||||||
def print(self):
|
|
||||||
print("Heightmap:")
|
|
||||||
for r in self.heightmap:
|
|
||||||
print(''.join(map(lambda x: str(x), r)))
|
|
||||||
print("Visibility:")
|
|
||||||
for r in self.visible:
|
|
||||||
print(''.join(map(lambda x: "X" if x else "O", r)))
|
|
||||||
|
|
||||||
def solve_visibility(self):
|
|
||||||
# TOP-DOWN
|
|
||||||
limit = [-1] * self.width
|
|
||||||
for rowidx in range(self.width):
|
|
||||||
for colidx in range(self.width):
|
|
||||||
if limit[colidx] < self.heightmap[rowidx][colidx]:
|
|
||||||
self.visible[rowidx][colidx] = True
|
|
||||||
limit[colidx] = self.heightmap[rowidx][colidx]
|
|
||||||
|
|
||||||
# BOT-UP
|
|
||||||
limit = [-1] * self.width
|
|
||||||
for rowidx in range(self.width):
|
|
||||||
for colidx in range(self.width):
|
|
||||||
if limit[colidx] < self.heightmap[-rowidx-1][colidx]:
|
|
||||||
self.visible[-rowidx-1][colidx] = True
|
|
||||||
limit[colidx] = self.heightmap[-rowidx-1][colidx]
|
|
||||||
|
|
||||||
# LEFT-RIGHT
|
|
||||||
limit = [-1] * self.width
|
|
||||||
for colidx in range(self.width):
|
|
||||||
for rowidx in range(self.width):
|
|
||||||
if limit[rowidx] < self.heightmap[rowidx][colidx]:
|
|
||||||
self.visible[rowidx][colidx] = True
|
|
||||||
limit[rowidx] = self.heightmap[rowidx][colidx]
|
|
||||||
|
|
||||||
# RIGHT-LEFT
|
|
||||||
limit = [-1] * self.width
|
|
||||||
for colidx in range(self.width):
|
|
||||||
for rowidx in range(self.width):
|
|
||||||
if limit[rowidx] < self.heightmap[rowidx][-colidx-1]:
|
|
||||||
self.visible[rowidx][-colidx-1] = True
|
|
||||||
limit[rowidx] = self.heightmap[rowidx][-colidx-1]
|
|
||||||
|
|
||||||
def solve_score(self):
|
|
||||||
for rowidx in range(self.width):
|
|
||||||
for colidx in range(self.width):
|
|
||||||
current = self.heightmap[rowidx][colidx]
|
|
||||||
lscore = 0
|
|
||||||
rscore = 0
|
|
||||||
uscore = 0
|
|
||||||
dscore = 0
|
|
||||||
for idx in range(colidx): # left
|
|
||||||
lscore += 1
|
|
||||||
if self.heightmap[rowidx][colidx-idx-1] >= current:
|
|
||||||
break
|
|
||||||
for idx in range(self.width - colidx - 1): # right
|
|
||||||
rscore += 1
|
|
||||||
if self.heightmap[rowidx][colidx+idx+1] >= current:
|
|
||||||
break
|
|
||||||
for idx in range(rowidx): # up
|
|
||||||
uscore += 1
|
|
||||||
if self.heightmap[rowidx-idx-1][colidx] >= current:
|
|
||||||
break
|
|
||||||
for idx in range(self.width - rowidx - 1): # down
|
|
||||||
dscore += 1
|
|
||||||
if self.heightmap[rowidx+idx+1][colidx] >= current:
|
|
||||||
break
|
|
||||||
self.score[rowidx][colidx] = lscore*rscore*uscore*dscore
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def parse(cls, lines):
|
|
||||||
output = None
|
|
||||||
idx = 0
|
|
||||||
for line in map(lambda x: x.strip(), lines):
|
|
||||||
if line != "":
|
|
||||||
if output is None:
|
|
||||||
output = cls(len(line), len(line))
|
|
||||||
output.heightmap[idx] = list(map(lambda x: int(x), list(line)))
|
|
||||||
idx += 1
|
|
||||||
return output
|
|
||||||
|
|
||||||
def visible_count(self):
|
|
||||||
output = 0
|
|
||||||
for r in self.visible:
|
|
||||||
output += sum(r)
|
|
||||||
return output
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
forest = Forest.parse(fileinput.input())
|
|
||||||
forest.solve_visibility()
|
|
||||||
forest.solve_score()
|
|
||||||
forest.print()
|
|
||||||
print(f"Visible: {forest.visible_count()}")
|
|
||||||
print(f"Score: {max([max(row) for row in forest.score])}")
|
|
Loading…
Reference in New Issue
Block a user