Skip to content

Commit 0127204

Browse files
committed
Optimize 2024 day 6 part 2 by starting cycle finding from previous guard
Halves runtime because it avoid rewalking the initial path until the obstacle.
1 parent 096ccf9 commit 0127204

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

src/main/scala/eu/sim642/adventofcode2024/Day6.scala

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import eu.sim642.adventofcodelib.Grid
55
import eu.sim642.adventofcodelib.GridImplicits.*
66
import eu.sim642.adventofcodelib.cycle.BrentCycleFinder
77
import eu.sim642.adventofcodelib.pos.Pos
8+
import eu.sim642.adventofcodelib.IteratorImplicits._
89

910
object Day6 {
1011

@@ -49,11 +50,19 @@ object Day6 {
4950

5051
def countObstructionPoss(input: Input): Int = { // TODO: optimize?
5152
val Input(grid, guard) = input
52-
guardPoss(input)
53-
.iterator
54-
.filter(obstructionPos => obstructionPos != guard.pos)
55-
.map(obstructionPos => Input(grid.updatedGrid(obstructionPos, true), guard))
56-
.count(isGuardCycle)
53+
iterateGuard(input) // only consider obstacles on initial path
54+
.takeWhile(guard => input.grid.containsPos(guard.pos))
55+
.scanLeft((Set.empty[Pos], Guard(Pos(-1, -1), Pos.zero)))({ case ((acc, prevGuard), guard) => (acc + prevGuard.pos, guard) }) // incrementally compute guardPoss
56+
// TODO: scanLeftMap or something
57+
.tail // ignore first scanLeft element with dummy guard
58+
.filter({ case (acc, guard) => !acc.contains(guard.pos) }) // keep only those positions that are being visited for the first time
59+
.map(_._2)
60+
.zipWithTail
61+
//.filter(obstructionPos => obstructionPos != guard.pos)
62+
.count({ case (guard, obstruction) =>
63+
val newGrid = grid.updatedGrid(obstruction.pos, true) // place obstacle in front of guard
64+
isGuardCycle(Input(newGrid, guard)) // check cycle starting from previous guard
65+
})
5766
}
5867

5968
def parseGrid(input: String): Grid[Boolean] = input.linesIterator.map(_.toVector).toVector.mapGrid({

src/test/scala/eu/sim642/adventofcode2024/Day6Test.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ class Day6Test extends AnyFunSuite {
3030
}
3131

3232
test("Part 2 input answer") {
33-
assert(countObstructionPoss(parseInput(input)) == 1719) // TODO: optimize?
33+
assert(countObstructionPoss(parseInput(input)) == 1719)
3434
}
3535
}

0 commit comments

Comments
 (0)