mirror of
https://github.com/Crocmagnon/advent-of-code.git
synced 2024-06-17 14:32:56 +02:00
76 lines
1.9 KiB
Python
76 lines
1.9 KiB
Python
|
import copy
|
||
|
from collections.abc import Iterable
|
||
|
|
||
|
|
||
|
def main(filename: str, expected_part_1: int = None, expected_part_2: int = None):
|
||
|
print(f"\n+ Running on {filename}")
|
||
|
with open(filename) as f:
|
||
|
data = f.read().strip().split("\n")
|
||
|
|
||
|
data = parse_data(data)
|
||
|
solution_part_1 = solve_part_1(data)
|
||
|
|
||
|
print(f"1. Found {solution_part_1}")
|
||
|
if expected_part_1:
|
||
|
assert expected_part_1 == solution_part_1
|
||
|
|
||
|
solution_part_2 = solve_part_2(data)
|
||
|
print(f"2. Found {solution_part_2}")
|
||
|
if expected_part_2:
|
||
|
assert expected_part_2 == solution_part_2
|
||
|
|
||
|
|
||
|
DataType = list[list[int]]
|
||
|
|
||
|
|
||
|
def parse_data(data: list[str]) -> DataType:
|
||
|
grid = []
|
||
|
for row in data:
|
||
|
grid.append(list(map(int, row)))
|
||
|
return grid
|
||
|
|
||
|
|
||
|
def solve_part_1(grid: DataType) -> int:
|
||
|
visible = set()
|
||
|
grid = copy.deepcopy(grid)
|
||
|
visible.update(find_visible_in_rows(grid))
|
||
|
|
||
|
grid = map(list, zip(*grid)) # transpose grid so cols become rows
|
||
|
visible.update(find_visible_in_rows(grid, swap=True))
|
||
|
return len(visible)
|
||
|
|
||
|
|
||
|
def find_visible_in_rows(
|
||
|
grid: Iterable[list[int]], swap: bool = False
|
||
|
) -> set[tuple[int, int]]:
|
||
|
visible = set()
|
||
|
for row, trees in enumerate(grid):
|
||
|
max_height = -1
|
||
|
for col, tree in enumerate(trees):
|
||
|
if tree > max_height:
|
||
|
max_height = tree
|
||
|
visible.add(visible_tree(row, col, swap))
|
||
|
max_height = -1
|
||
|
for col, tree in enumerate(reversed(trees)):
|
||
|
col = len(trees) - col - 1
|
||
|
if tree > max_height:
|
||
|
max_height = tree
|
||
|
visible.add(visible_tree(row, col, swap))
|
||
|
return visible
|
||
|
|
||
|
|
||
|
def visible_tree(row, col, swap):
|
||
|
if swap:
|
||
|
return col, row
|
||
|
else:
|
||
|
return row, col
|
||
|
|
||
|
|
||
|
def solve_part_2(data: DataType) -> int:
|
||
|
return 0
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main("inputs/day08-test1", expected_part_1=21)
|
||
|
main("inputs/day08", expected_part_1=1690)
|