-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_8.py
80 lines (51 loc) · 2.08 KB
/
day_8.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import numpy as np
def read():
with open("input.txt") as file:
lines = file.readlines()
lines = list(map(lambda s: s.strip("\n"), lines))
tree_map = []
for line in lines:
tree_map.append(np.array([int(c) for c in line]))
return np.array(tree_map)
def get_num_visible_trees(tree_map: np.ndarray) -> int:
num_visible = (
tree_map.shape[0] * 2 + tree_map.shape[1] * 2 - 4
) # All trees on the edges
for i in range(1, tree_map.shape[0] - 1):
for j in range(1, tree_map.shape[1] - 1):
height = tree_map[i, j]
up = (tree_map[:i, j] < height).all()
down = (tree_map[i + 1 :, j] < height).all()
left = (tree_map[i, :j] < height).all()
right = (tree_map[i, j + 1 :] < height).all()
if up or down or left or right:
num_visible += 1
return num_visible
def get_viewing_distance(tree_heights: np.ndarray, max_height: int) -> int:
blocked = tree_heights >= max_height
if not blocked.any():
return len(tree_heights)
blocked_idx = np.argmax(blocked)
return blocked_idx + 1
def get_scenic_score(tree_map: np.ndarray, row: int, col: int):
height = tree_map[row, col]
up = get_viewing_distance(tree_map[:row, col][::-1], height)
down = get_viewing_distance(tree_map[row + 1 :, col], height)
left = get_viewing_distance(tree_map[row, :col][::-1], height)
right = get_viewing_distance(tree_map[row, col + 1 :], height)
return up * down * left * right
def get_max_scenic_score(tree_map: np.ndarray) -> int:
max_score = 0
for i in range(tree_map.shape[0]):
for j in range(tree_map.shape[1]):
score = get_scenic_score(tree_map, i, j)
if score > max_score:
max_score = score
return max_score
def main():
tree_map = read()
print(f"Num visible trees: {get_num_visible_trees(tree_map)}")
max_scenic_score = get_max_scenic_score(tree_map)
print(f"Max scenic score: {max_scenic_score}")
if __name__ == "__main__":
main()