From 9654c59bfd4143b4506e28a2f252d3a45f14e62f Mon Sep 17 00:00:00 2001 From: Christian Date: Fri, 24 Jan 2025 17:22:19 +0100 Subject: [PATCH] Day 16: Use two stacks instead of PQ --- aoc/src/dev/ctsk/aoc/days/Day16.scala | 28 +++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/aoc/src/dev/ctsk/aoc/days/Day16.scala b/aoc/src/dev/ctsk/aoc/days/Day16.scala index 60990e4..8b81030 100644 --- a/aoc/src/dev/ctsk/aoc/days/Day16.scala +++ b/aoc/src/dev/ctsk/aoc/days/Day16.scala @@ -16,26 +16,34 @@ object Day16 extends Solver(16): case class State(distance: Int, pose: Pose) implicit def ord: Ordering[State] = Ordering.by(-1 * _.distance) - Direction.Up.ordinal - def search(start: Pose): (Map[Pose, Int], Map[Pose, List[Pose]]) = val distance = mutable.Map(start -> 0) val ancestor = mutable.Map.empty[Pose, List[Pose]] - val heap = mutable.PriorityQueue(State(0, start)) + var near = mutable.Stack(State(0, start)) + var far = mutable.Stack.empty[State] - inline def relax(u: Pose, v: Pose, vDist: Int): Unit = + inline def relax(u: Pose, v: Pose, vDist: Int, isFar: Boolean): Unit = val oldDist = distance.getOrElse(v, 1_000_000) if vDist == oldDist then ancestor(v) +:= u if vDist < oldDist then ancestor(v) = List(u) distance(v) = vDist - heap.enqueue(State(vDist, v)) + if isFar + then far.push(State(vDist, v)) + else near.push(State(vDist, v)) - while heap.nonEmpty do - val State(uDist, u) = heap.dequeue() - if uDist == distance(u) then - if !grid(u.step.pos).contains('#') then relax(u, u.step, uDist + 1) - for (v <- Seq(u.turnLeft, u.turnRight)) do relax(u, v, uDist + 1000) + while near.nonEmpty do + while near.nonEmpty do + val State(uDist, u) = near.pop() + if uDist == distance(u) then + if !grid(u.step.pos).contains('#') then + relax(u, u.step, uDist + 1, false) + for (v <- Seq(u.turnLeft, u.turnRight)) do + relax(u, v, uDist + 1000, true) + + val tmp = near + near = far + far = tmp (distance.toMap, ancestor.toMap)