Files
advent-of-code-2021/day-15/day-15.py
Pascal Lais d16807f80d
All checks were successful
continuous-integration/drone/push Build is passing
Optimize day 15 solution by using priority queue
2021-12-16 16:48:45 +01:00

82 lines
2.4 KiB
Python

#!/usr/bin/env python3
from pathlib import Path
from heapq import heappush, heappop
def part_1(input):
result = 0
x_size = len(input[0].strip())
y_size = len(input)
nodes = {(x, y): int(v) for y, line in enumerate(input)
for x, v in enumerate(line.strip())}
start = (0, 0)
end = (x_size - 1, y_size - 1)
cost = {start: 0}
queue = [(0, start)]
done = set()
neighbors = set([(-1, 0), (0, -1), (0, 1), (1, 0)])
while len(queue):
cur_cost, current = heappop(queue)
if current in done:
continue
(xc, yc) = current
next = set()
for (xn, yn) in neighbors:
nbr = (xc + xn, yc + yn)
if nbr in nodes and not nbr in done:
next.add(nbr)
for n in next:
next_cost = cur_cost + nodes[n]
if not n in cost or next_cost < cost[n]:
cost[n] = next_cost
heappush(queue, (next_cost, n))
done.add(current)
result = cost[end]
print("Part 1 result:", result)
def part_2(input):
result = 0
x_size = len(input[0].strip())
y_size = len(input)
repeat = 5
nodes = {(x, y): int(v) for y, line in enumerate(input)
for x, v in enumerate(line.strip())}
start = (0, 0)
end = ((x_size * repeat) - 1, (y_size * repeat) - 1)
cost = {start: 0}
queue = [(0, start)]
done = set()
neighbors = set([(-1, 0), (0, -1), (0, 1), (1, 0)])
while len(queue):
cur_cost, current = heappop(queue)
if current in done:
continue
(xc, yc) = current
next = set()
for (xn, yn) in neighbors:
x = xc + xn
y = yc + yn
if 0 <= x < (x_size * repeat) and 0 <= y < (y_size * repeat):
if not (x, y) in done:
next.add((x, y))
for (x, y) in next:
next_cost = nodes[(x % x_size, y % y_size)] + \
(x // x_size) + (y // y_size)
if next_cost > 9:
next_cost -= 9
if not (x, y) in cost or (cur_cost + next_cost) < cost[(x, y)]:
cost[(x, y)] = cur_cost + next_cost
heappush(queue, (cur_cost + next_cost, (x, y)))
done.add(current)
result = cost[end]
print("Part 2 result:", result)
input = list()
p = Path(__file__).with_name('input.txt')
with open(p) as f:
input = f.readlines()
part_1(input)
part_2(input)