-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpart_2.py
67 lines (45 loc) · 1.99 KB
/
part_2.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
from pathlib import Path
def parse_input(file_path: Path) -> list[list[int]]:
"""Parses the input topographic map from a file into a 2D list of integers."""
with file_path.open() as f:
return [list(map(int, line.strip())) for line in f]
def find_trailheads(grid: list[list[int]]) -> list[tuple[int, int]]:
"""Finds all trailhead positions (positions with height 0) in the grid."""
trailheads = []
for r, row in enumerate(grid):
for c, value in enumerate(row):
if value == 0:
trailheads.append((r, c))
return trailheads
def count_distinct_trails(grid: list[list[int]], start: tuple[int, int]) -> int:
"""Counts the number of distinct hiking trails starting from a given trailhead. Uses DFS."""
rows, cols = len(grid), len(grid[0])
memo: dict[tuple[int, int], int] = {}
def dfs(r: int, c: int) -> int:
"""Recursively explores all valid paths from the current position. Memoization is used here too."""
if (r, c) in memo:
return memo[(r, c)]
if grid[r][c] == 9: # NOQA: PLR2004
return 1
total_trails = 0
for dr, dc in ((-1, 0), (1, 0), (0, -1), (0, 1)):
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] == grid[r][c] + 1:
total_trails += dfs(nr, nc)
memo[(r, c)] = total_trails
return total_trails
return dfs(*start)
def calculate_total_rating(grid: list[list[int]]) -> int:
"""Calculates the sum of ratings for all trailheads in the grid."""
trailheads = find_trailheads(grid)
total_rating = 0
for trailhead in trailheads:
total_rating += count_distinct_trails(grid, trailhead)
return total_rating
def main(file_path: str) -> int: # NOQA: D103
grid = parse_input(Path(file_path))
return calculate_total_rating(grid)
if __name__ == '__main__':
input_file = 'input.txt'
result = main(input_file)
print(f'Total Rating: {result}')