Day 16: Use two stacks instead of PQ
This commit is contained in:
@@ -16,26 +16,34 @@ object Day16 extends Solver(16):
|
|||||||
case class State(distance: Int, pose: Pose)
|
case class State(distance: Int, pose: Pose)
|
||||||
implicit def ord: Ordering[State] = Ordering.by(-1 * _.distance)
|
implicit def ord: Ordering[State] = Ordering.by(-1 * _.distance)
|
||||||
|
|
||||||
Direction.Up.ordinal
|
|
||||||
|
|
||||||
def search(start: Pose): (Map[Pose, Int], Map[Pose, List[Pose]]) =
|
def search(start: Pose): (Map[Pose, Int], Map[Pose, List[Pose]]) =
|
||||||
val distance = mutable.Map(start -> 0)
|
val distance = mutable.Map(start -> 0)
|
||||||
val ancestor = mutable.Map.empty[Pose, List[Pose]]
|
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)
|
val oldDist = distance.getOrElse(v, 1_000_000)
|
||||||
if vDist == oldDist then ancestor(v) +:= u
|
if vDist == oldDist then ancestor(v) +:= u
|
||||||
if vDist < oldDist then
|
if vDist < oldDist then
|
||||||
ancestor(v) = List(u)
|
ancestor(v) = List(u)
|
||||||
distance(v) = vDist
|
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
|
while near.nonEmpty do
|
||||||
val State(uDist, u) = heap.dequeue()
|
while near.nonEmpty do
|
||||||
|
val State(uDist, u) = near.pop()
|
||||||
if uDist == distance(u) then
|
if uDist == distance(u) then
|
||||||
if !grid(u.step.pos).contains('#') then relax(u, u.step, uDist + 1)
|
if !grid(u.step.pos).contains('#') then
|
||||||
for (v <- Seq(u.turnLeft, u.turnRight)) do relax(u, v, uDist + 1000)
|
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)
|
(distance.toMap, ancestor.toMap)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user