day12 - some slight optimizations

This commit is contained in:
Stefan Harmuth 2022-12-12 08:12:01 +01:00
parent f1109d71a7
commit a11cefa083

View File

@ -1,16 +1,16 @@
from heapq import heappush, heappop from heapq import heappush, heappop
from tools.aoc import AOCDay from tools.aoc import AOCDay
from tools.coordinate import Coordinate from tools.coordinate import Coordinate, DistanceAlgorithm
from tools.grid import Grid from tools.grid import Grid
from typing import Any from typing import Any
def get_dijkstra_path(height_map: Grid, start: Coordinate, end: Coordinate) -> list | None: def get_dijkstra_path(height_map: Grid, start: Coordinate, end: Coordinate) -> int | None:
f_costs = [] f_costs = []
openNodes = {} openNodes = {}
closedNodes = {} closedNodes = {}
openNodes[start] = (0, start.getDistanceTo(end), None) openNodes[start] = (0, start.getDistanceTo(end, algorithm=DistanceAlgorithm.MANHATTAN), None)
heappush(f_costs, (0, start)) heappush(f_costs, (0, start))
while f_costs: while f_costs:
@ -28,25 +28,23 @@ def get_dijkstra_path(height_map: Grid, start: Coordinate, end: Coordinate) -> l
if neighbour in closedNodes or height_map.get(neighbour) - 1 > height_map.get(currentCoord): if neighbour in closedNodes or height_map.get(neighbour) - 1 > height_map.get(currentCoord):
continue continue
neighbourDist = 1 targetDist = neighbour.getDistanceTo(end, algorithm=DistanceAlgorithm.MANHATTAN)
f_cost = targetDist + 1 + currentNode[1]
targetDist = neighbour.getDistanceTo(end)
f_cost = targetDist + neighbourDist + currentNode[1]
if neighbour not in openNodes or f_cost < openNodes[neighbour][0]: if neighbour not in openNodes or f_cost < openNodes[neighbour][0]:
openNodes[neighbour] = (f_cost, currentNode[1] + neighbourDist, currentCoord) openNodes[neighbour] = (f_cost, currentNode[1] + 1, currentCoord)
heappush(f_costs, (f_cost, neighbour)) heappush(f_costs, (f_cost, neighbour))
if end not in closedNodes: if end not in closedNodes:
return None return None
else: else:
steps = 0
currentNode = closedNodes[end] currentNode = closedNodes[end]
pathCoords = [end]
while currentNode[2]: while currentNode[2]:
pathCoords.append(currentNode[2]) steps += 1
currentNode = closedNodes[currentNode[2]] currentNode = closedNodes[currentNode[2]]
return pathCoords return steps
class Day(AOCDay): class Day(AOCDay):
@ -79,7 +77,7 @@ class Day(AOCDay):
return grid, start, end return grid, start, end
def part1(self) -> Any: def part1(self) -> Any:
return len(get_dijkstra_path(*self.get_map())) - 1 return get_dijkstra_path(*self.get_map())
def part2(self) -> Any: def part2(self) -> Any:
min_steps = float("inf") min_steps = float("inf")
@ -87,8 +85,8 @@ class Day(AOCDay):
for c in height_map.getActiveCells(): for c in height_map.getActiveCells():
if height_map.get(c) == 0: if height_map.get(c) == 0:
steps_from_here = get_dijkstra_path(height_map, c, end) steps_from_here = get_dijkstra_path(height_map, c, end)
if steps_from_here is not None and len(steps_from_here) < min_steps: if steps_from_here is not None and steps_from_here + 1 < min_steps:
min_steps = len(steps_from_here) min_steps = steps_from_here + 1
return min_steps - 1 return min_steps - 1