Passed
Push — main ( c5b7e2...73cdde )
by Yohann
01:00
created

main.get_highest_scenic_score()   A

Complexity

Conditions 3

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 16
nop 1
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
1
import functools
2
import operator
3
import pathlib
4
from typing import Final, List, Tuple
5
6
BOARD_SIZE: Final[int] = 99
7
8
9
def get_neighbours_tree(board: List[str], x: int, y: int) -> Tuple[str, str, str, str]:
10
    return (
11
        board[y][:x][::-1],
12
        board[y][x + 1:],
13
        ''.join(line[x] for line in board[:y])[::-1],
14
        ''.join(line[x] for line in board[y + 1:])
15
    )
16
17
18
def count_visible(board: List[str]) -> int:
19
    def is_visible(x, y) -> bool:
20
        return any(
21
            board[y][x] > max(trees)
22
            for trees in get_neighbours_tree(board, x, y)
23
        )
24
25
    return sum(
26
        is_visible(x, y)
27
        for x in range(1, BOARD_SIZE - 1)
28
        for y in range(1, BOARD_SIZE - 1)
29
    ) + (BOARD_SIZE - 1) * 4
30
31
32
def get_highest_scenic_score(board: List[str]) -> int:
33
    def scenic_core(x: int, y: int) -> int:
34
        return functools.reduce(
35
            operator.mul,
36
            (
37
                get_first_non_visible_from(board[y][x], trees)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable trees does not seem to be defined.
Loading history...
38
                for trees in get_neighbours_tree(board, x, y)
39
            )
40
        )
41
42
    def get_first_non_visible_from(h: str, trees: str) -> int:
43
        for idx, tree in enumerate(trees, start=1):
44
            if tree >= h:
45
                return idx
46
        return len(trees)
47
48
    return max(
49
        scenic_core(x, y)
50
        for x in range(BOARD_SIZE)
51
        for y in range(BOARD_SIZE)
52
    )
53
54
55
def main():
56
    content = pathlib.Path('./input.txt').read_text()
57
    board = [line for line in content.splitlines()]
58
59
    print('Part 1:', count_visible(board))
60
    print('Part 2:', get_highest_scenic_score(board))
61
62
63
if __name__ == '__main__':
64
    main()
65