-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay06GuardGallivant.kt
75 lines (62 loc) · 2.34 KB
/
Day06GuardGallivant.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package adventofcode.year2024
import adventofcode.Puzzle
import adventofcode.PuzzleInput
import adventofcode.common.spatial.Grid2d
import adventofcode.common.spatial.Point2d
import adventofcode.year2024.Day06GuardGallivant.Companion.Direction.UP
class Day06GuardGallivant(customInput: PuzzleInput? = null) : Puzzle(customInput) {
private val grid by lazy { Grid2d(input) }
private val obstructions by lazy { grid.findAll('#') }
private val guard by lazy { grid['^'] to UP }
override fun partOne() = grid.guardPath(obstructions, guard).size
override fun partTwo() =
grid
.guardPath(obstructions, guard)
.filterNot { position -> position == guard.first }
.mapNotNull { position ->
try {
grid.guardPath(obstructions + position, guard)
null
} catch (e: LoopException) {
position
}
}
.size
companion object {
private enum class Direction(val direction: Point2d) {
UP(Point2d(0, -1)),
RIGHT(Point2d(1, 0)),
DOWN(Point2d(0, 1)),
LEFT(Point2d(-1, 0)),
;
fun turnRight() =
when (this) {
UP -> RIGHT
RIGHT -> DOWN
DOWN -> LEFT
LEFT -> UP
}
}
private class LoopException(position: Point2d) : Exception("Loop detected at $position")
private fun Grid2d<Char>.guardPath(
obstructions: Set<Point2d>,
guard: Pair<Point2d, Direction>,
): Set<Point2d> {
val seen = mutableSetOf<Pair<Point2d, Direction>>()
var position = guard
while (position.first in this) {
if (seen.contains(position)) {
throw LoopException(position.first)
}
seen.add(position)
val nextPosition = position.first + position.second.direction
position =
when {
nextPosition in obstructions -> position.first to position.second.turnRight()
else -> nextPosition to position.second
}
}
return seen.map { it.first }.toSet()
}
}
}