Day 16: Early exit search loop

This commit is contained in:
Christian
2025-01-24 22:48:14 +01:00
parent 9654c59bfd
commit 1d9dc696a8

View File

@@ -3,6 +3,8 @@ package dev.ctsk.aoc.days
import dev.ctsk.aoc.{Direction, *} import dev.ctsk.aoc.{Direction, *}
import scala.collection.mutable import scala.collection.mutable
import scala.util.boundary
import scala.util.boundary.break
object Day16 extends Solver(16): object Day16 extends Solver(16):
override def run(input_ : os.ReadablePath): (Timings, Solution) = override def run(input_ : os.ReadablePath): (Timings, Solution) =
@@ -14,7 +16,6 @@ object Day16 extends Solver(16):
val end = grid.findFirst(_ == 'E').get val end = grid.findFirst(_ == 'E').get
case class State(distance: Int, pose: Pose) case class State(distance: Int, pose: Pose)
implicit def ord: Ordering[State] = Ordering.by(-1 * _.distance)
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)
@@ -32,18 +33,23 @@ object Day16 extends Solver(16):
then far.push(State(vDist, v)) then far.push(State(vDist, v))
else near.push(State(vDist, v)) else near.push(State(vDist, v))
while near.nonEmpty do boundary:
while near.nonEmpty do while near.nonEmpty do
val State(uDist, u) = near.pop() var atEnd = false;
if uDist == distance(u) then while near.nonEmpty do
if !grid(u.step.pos).contains('#') then val State(uDist, u) = near.pop()
relax(u, u.step, uDist + 1, false) atEnd |= u.pos == end
for (v <- Seq(u.turnLeft, u.turnRight)) do if uDist == distance(u) then
relax(u, v, uDist + 1000, true) 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 if atEnd then break()
near = far
far = tmp val tmp = near
near = far
far = tmp
(distance.toMap, ancestor.toMap) (distance.toMap, ancestor.toMap)
@@ -51,7 +57,7 @@ object Day16 extends Solver(16):
search(Pose(start, Direction.Right)) search(Pose(start, Direction.Right))
} }
val endPose = DIRS.map(Pose(end, _)).minBy(distance(_)) val endPose = DIRS.map(Pose(end, _)).minBy(distance.getOrElse(_, 1_000_000))
val p1 = distance(endPose) val p1 = distance(endPose)