mirror of
https://github.com/cupcakearmy/advent-of-code.git
synced 2024-12-22 08:06:25 +00:00
79 lines
1.9 KiB
Python
79 lines
1.9 KiB
Python
#!/usr/bin/env python
|
|
|
|
from dataclasses import dataclass
|
|
from functools import reduce
|
|
from os.path import dirname, join
|
|
|
|
# Day 08
|
|
|
|
# Common
|
|
|
|
|
|
def read_input(filename):
|
|
data = join(dirname(__file__), '..', filename)
|
|
with open(data) as f:
|
|
return f.read().strip()
|
|
|
|
|
|
test = read_input('test.txt')
|
|
data = read_input('input.txt')
|
|
|
|
|
|
@dataclass
|
|
class Forest:
|
|
grid: list[list[int]]
|
|
size: int
|
|
|
|
def is_tree_visible(self, y: int, x: int) -> tuple[bool, int]:
|
|
value = self.grid[y][x]
|
|
combinations = [(0, 1), (0, -1), (1, 0), (-1, 0)]
|
|
visible = 4
|
|
views: list[int] = []
|
|
for dy, dx in combinations:
|
|
X = x
|
|
Y = y
|
|
view = 0
|
|
while True:
|
|
X += dx
|
|
Y += dy
|
|
# Gone outside the forest, so must be visible
|
|
if Y < 0 or Y == self.size or X < 0 or X == self.size:
|
|
break
|
|
view += 1
|
|
if value <= self.grid[Y][X]:
|
|
visible -= 1
|
|
break
|
|
views.append(view)
|
|
|
|
score = reduce(lambda a, b: a*b, views, 1)
|
|
return visible > 0, score
|
|
|
|
def analyze(self) -> tuple[int, int]:
|
|
visible = 0
|
|
best = 0
|
|
for y in range(self.size):
|
|
for x in range(self.size):
|
|
is_visible, score = self.is_tree_visible(y, x)
|
|
if is_visible:
|
|
visible += 1
|
|
if score > best:
|
|
best = score
|
|
return visible, best
|
|
|
|
@staticmethod
|
|
def parse(data: str):
|
|
lines = data.split()
|
|
size = len(lines)
|
|
grid = [
|
|
[int(lines[y][x]) for x in range(size)]
|
|
for y in range(size)
|
|
]
|
|
return Forest(grid, size)
|
|
|
|
|
|
forest = Forest.parse(test)
|
|
print(forest.analyze())
|
|
|
|
forest = Forest.parse(data)
|
|
print(forest.analyze())
|