-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday_17.py
74 lines (62 loc) · 2.7 KB
/
day_17.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
import time
from heapq import heappop, heappush
def read_data(file_path):
"""
Read data from the input file and return a list of stripped lines.
"""
try:
with open(file_path, "r", encoding="utf8") as file:
return [[int(city_block) for city_block in line.strip()] for line in file]
except FileNotFoundError:
raise FileNotFoundError(f"Error: Input file {file_path} not found.")
DIRS = [(0, 1), (1, 0), (0, -1), (-1, 0)]
def in_bounds(position, grid):
# check if position is within bounds
return position[0] in range(len(grid)) and position[1] in range(len(grid[0]))
def find_min_heat_loss(grid, min_distance, max_distance):
# return the minimum heat loss value using Dijkstra's algorithm
q = [(0, 0, 0, -1)]
visited = set()
values = {}
destination = (len(grid) - 1, len(grid[0]) - 1)
while q:
value, x, y, invalid = heappop(q)
if (x, y) == destination:
return value
if (x, y, invalid) in visited:
continue
visited.add((x, y, invalid))
for direction in range(4):
increased_value = 0
if direction == invalid or (direction + 2) % 4 == invalid:
continue
for distance in range(1, max_distance + 1):
current_x = x + DIRS[direction][0] * distance
current_y = y + DIRS[direction][1] * distance
if current_x in range(len(grid)) and current_y in range(len(grid[0])):
increased_value += grid[current_x][current_y]
if distance < min_distance:
continue
new_value = value + increased_value
if (
values.get((current_x, current_y, direction), 1e100)
<= new_value
):
continue
values[(current_x, current_y, direction)] = new_value
heappush(q, (new_value, current_x, current_y, direction))
if __name__ == "__main__":
grid = read_data("input.txt")
# Measure time for part1
start_time = time.time()
result_part1 = find_min_heat_loss(grid, 1, 3)
end_time = time.time()
time_part1 = end_time - start_time
# Measure time for part2
start_time = time.time()
result_part2 = find_min_heat_loss(grid, 4, 10)
end_time = time.time()
time_part2 = end_time - start_time
print(f"The solution for part 1 is {result_part1} and part 2 is {result_part2}")
print(f"Time taken to execute part 1: {time_part1:.6f} seconds")
print(f"Time taken to execute part 2: {time_part2:.6f} seconds")