133 lines
2.9 KiB
Python
133 lines
2.9 KiB
Python
|
import re
|
||
|
from string import ascii_lowercase, ascii_uppercase
|
||
|
|
||
|
EXAMPLE = """
|
||
|
30373
|
||
|
25512
|
||
|
65332
|
||
|
33549
|
||
|
35390
|
||
|
"""
|
||
|
|
||
|
def clean(text: str) -> list[str]:
|
||
|
return list(filter(lambda l: l.strip() != "", text.splitlines()))
|
||
|
|
||
|
|
||
|
def is_visible(trees, y_tree, x_tree):
|
||
|
y_max = len(trees)
|
||
|
x_max = len(trees[0])
|
||
|
tree_height = trees[y_tree][x_tree]
|
||
|
|
||
|
for x in range(0, x_tree):
|
||
|
if trees[y_tree][x] >= tree_height:
|
||
|
break
|
||
|
else:
|
||
|
return True
|
||
|
|
||
|
for x in range(x_tree + 1, x_max):
|
||
|
if trees[y_tree][x] >= tree_height:
|
||
|
break
|
||
|
else:
|
||
|
return True
|
||
|
|
||
|
for y in range(0, y_tree):
|
||
|
if trees[y][x_tree] >= tree_height:
|
||
|
break
|
||
|
else:
|
||
|
return True
|
||
|
|
||
|
for y in range(y_tree + 1, y_max):
|
||
|
if trees[y][x_tree] >= tree_height:
|
||
|
break
|
||
|
else:
|
||
|
return True
|
||
|
return False
|
||
|
|
||
|
def solve(lines: list[str]):
|
||
|
res = 0
|
||
|
trees = []
|
||
|
for i in range(len(lines)):
|
||
|
line = lines[i]
|
||
|
trees.append(list(map(int, line)))
|
||
|
|
||
|
for y in range(len(trees)):
|
||
|
for x in range(len(trees)):
|
||
|
if is_visible(trees, y, x):
|
||
|
res += 1
|
||
|
else:
|
||
|
pass
|
||
|
return res
|
||
|
|
||
|
|
||
|
def scenic_score(trees, y_tree, x_tree):
|
||
|
y_max = len(trees)
|
||
|
x_max = len(trees[0])
|
||
|
|
||
|
if x_tree == 0 or y_tree == 0 or x_tree == x_max - 1 or y_tree == y_max - 1:
|
||
|
return 0
|
||
|
|
||
|
tree_height = trees[y_tree][x_tree]
|
||
|
left, right, up, down = 0, 0, 0, 0
|
||
|
|
||
|
for x in range(x_tree - 1, -1, -1):
|
||
|
if trees[y_tree][x] < tree_height:
|
||
|
left += 1
|
||
|
else:
|
||
|
left += 1
|
||
|
break
|
||
|
|
||
|
for x in range(x_tree + 1, x_max):
|
||
|
if trees[y_tree][x] < tree_height:
|
||
|
right += 1
|
||
|
else:
|
||
|
right += 1
|
||
|
break
|
||
|
|
||
|
for y in range(y_tree - 1, -1, -1):
|
||
|
if trees[y][x_tree] < tree_height:
|
||
|
up += 1
|
||
|
else:
|
||
|
up += 1
|
||
|
break
|
||
|
|
||
|
for y in range(y_tree + 1, y_max):
|
||
|
if trees[y][x_tree] < tree_height:
|
||
|
down += 1
|
||
|
else:
|
||
|
down += 1
|
||
|
break
|
||
|
|
||
|
score = up * down * left * right
|
||
|
# print(f"{y_tree=} {x_tree=} {left=} {right=} {up=} {down=} {score=}")
|
||
|
return score
|
||
|
|
||
|
def solve2(lines: list[str]):
|
||
|
trees = []
|
||
|
for i in range(len(lines)):
|
||
|
line = lines[i]
|
||
|
trees.append(list(map(int, line)))
|
||
|
|
||
|
max_score = 0
|
||
|
for y in range(len(trees)):
|
||
|
for x in range(len(trees)):
|
||
|
score = scenic_score(trees, y, x)
|
||
|
if score > max_score:
|
||
|
max_score = score
|
||
|
return max_score
|
||
|
|
||
|
def main():
|
||
|
example = clean(EXAMPLE)
|
||
|
print("Example 1:", solve(example))
|
||
|
|
||
|
data = clean(open("i8.txt").read())
|
||
|
print("Solution 1:", solve(data))
|
||
|
|
||
|
example = clean(EXAMPLE)
|
||
|
print("Example 2:", solve2(example))
|
||
|
|
||
|
data = clean(open("i8.txt").read())
|
||
|
print("Solution 2:", solve2(data))
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|