Skip to content

Commit

Permalink
Deduplicate graph search in 2024 day 18
Browse files Browse the repository at this point in the history
  • Loading branch information
sim642 committed Dec 18, 2024
1 parent d59d7e6 commit 635e1c4
Showing 1 changed file with 11 additions and 25 deletions.
36 changes: 11 additions & 25 deletions src/main/scala/eu/sim642/adventofcode2024/Day18.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import eu.sim642.adventofcodelib.pos.Pos

object Day18 {

def exitSteps(bytes: Seq[Pos], max: Pos = Pos(70, 70), after: Int = 1024): Int = {
def bytesGraphSearch(bytes: Seq[Pos], max: Pos = Pos(70, 70), after: Int = 1024): GraphSearch[Pos] & UnitNeighbors[Pos] & TargetNode[Pos] = {
val fallenBytes = bytes.take(after).toSet

val graphSearch = new GraphSearch[Pos] with UnitNeighbors[Pos] with TargetNode[Pos] {
new GraphSearch[Pos] with UnitNeighbors[Pos] with TargetNode[Pos] {
override val startNode: Pos = Pos.zero

override def unitNeighbors(pos: Pos): IterableOnce[Pos] = {
Expand All @@ -23,37 +23,23 @@ object Day18 {

override val targetNode: Pos = max
}
}

def exitSteps(bytes: Seq[Pos], max: Pos = Pos(70, 70), after: Int = 1024): Int = {
val graphSearch = bytesGraphSearch(bytes, max, after)
BFS.search(graphSearch).target.get._2
}

// TODO: deduplicate
def exitSteps2(bytes: Seq[Pos], max: Pos = Pos(70, 70), after: Int = 1024): Boolean = {
val fallenBytes = bytes.take(after).toSet

val graphSearch = new GraphSearch[Pos] with UnitNeighbors[Pos] with TargetNode[Pos] {
override val startNode: Pos = Pos.zero

override def unitNeighbors(pos: Pos): IterableOnce[Pos] = {
for {
offset <- Pos.axisOffsets
newPos = pos + offset
if Pos.zero <= newPos && newPos <= max
if !fallenBytes(newPos)
} yield newPos
}

override val targetNode: Pos = max
}

def exitReachable(bytes: Seq[Pos], max: Pos, after: Int): Boolean = {
val graphSearch = bytesGraphSearch(bytes, max, after)
BFS.search(graphSearch).target.isDefined
}

def findBlockingByte(bytes: Seq[Pos], max: Pos = Pos(70, 70)): String = {
def f(after: Int): Boolean = !exitSteps2(bytes, max, after)
val after = OrderedSearch.binaryLower(f, 0, bytes.size + 1)(true)
val afterPos = bytes(after - 1)
s"${afterPos.x},${afterPos.y}"
def f(after: Int): Boolean = !exitReachable(bytes, max, after)
val blockingAfter = OrderedSearch.binaryLower(f, 0, bytes.size + 1)(true)
val blockingByte = bytes(blockingAfter - 1)
s"${blockingByte.x},${blockingByte.y}"
}

def parseByte(s: String): Pos = s match {
Expand Down

0 comments on commit 635e1c4

Please sign in to comment.