Skip to content

Instantly share code, notes, and snippets.

@michaldobisek
Created December 6, 2024 19:48
Show Gist options
  • Save michaldobisek/95c4cc0c72292245f06da44bec357e65 to your computer and use it in GitHub Desktop.
Save michaldobisek/95c4cc0c72292245f06da44bec357e65 to your computer and use it in GitHub Desktop.
package name.mido.aoc.y2024
import name.mido.aoc.y2023.Direction
import name.mido.aoc.y2023.Point
import name.mido.aoc.y2023.StringScreen
import java.io.File
import kotlin.time.measureTime
fun main() {
val screen = StringScreen(File("src/inputs/2024/day06.txt").readLines())
val start = screen.collectPoints('^').first()
val guard = Guard(Direction.NORTH, start, screen)
val solA = guard.walk().second.size
println("SolutionA is $solA")
val bTime = measureTime {
val solB = guard.findLoops()
println("SolutionB is $solB")
}
println("SolutionB took $bTime")
}
class Guard(
val baseDir: Direction,
val basePos: Point,
var screen: StringScreen,
) {
var dir = baseDir
var pos = basePos
fun reset() {
dir = baseDir
pos = basePos
}
fun step(obstacles: Set<Point>): Boolean {
val newPos = pos.move(dir)
return if(screen.contains(newPos)) {
if(screen[newPos] == '#' || obstacles.contains(newPos)) {
dir = dir.right()
} else {
pos = newPos
}
true
} else {
false
}
}
fun walk(obstacles: Set<Point> = emptySet()): Pair<Boolean, Set<Point>> {
reset()
val moveHistory = mutableSetOf(Pair(dir, pos))
while(step(obstacles)) {
val state = Pair(dir, pos)
if(moveHistory.contains(state)) {
return Pair(true, emptySet())
}
moveHistory.add(state)
}
return Pair(false, moveHistory.map { it.second }.toSet())
}
fun findLoops(): Int {
val candidates = walk().second
return candidates.filter { walk(setOf(it)).first }.size
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment