-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDay16ReindeerMaze.kt
More file actions
56 lines (44 loc) · 2.12 KB
/
Day16ReindeerMaze.kt
File metadata and controls
56 lines (44 loc) · 2.12 KB
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
package adventofcode.year2024
import adventofcode.Puzzle
import adventofcode.PuzzleInput
import adventofcode.common.spatial.Grid2d
import adventofcode.common.spatial.Point2d
import adventofcode.common.spatial.Point2d.Companion.EAST
import adventofcode.common.spatial.Point2d.Companion.NORTH
import adventofcode.common.spatial.Point2d.Companion.SOUTH
import adventofcode.common.spatial.Point2d.Companion.WEST
class Day16ReindeerMaze(
customInput: PuzzleInput? = null,
) : Puzzle(customInput) {
private val maze by lazy { Grid2d(input) }
override fun partOne() = maze.shortestPath(maze['S'], maze['E'])
companion object {
private const val STEP_SCORE = 1
private const val TURN_SCORE = 1000
private val clockwiseTurns = mapOf(NORTH to EAST, EAST to SOUTH, SOUTH to WEST, WEST to NORTH)
private val counterClockwiseTurns = clockwiseTurns.entries.associate { (from, to) -> to to from }
private fun Grid2d<Char>.shortestPath(
start: Point2d,
end: Point2d,
): Int {
val scores = mutableMapOf<Point2d, Int>()
val queue = ArrayDeque(setOf(Triple(start, EAST, 0)))
while (queue.isNotEmpty()) {
val (position, direction, score) = queue.removeFirst()
if (scores.getOrDefault(position, Integer.MAX_VALUE) > score) {
scores[position] = score
val clockwiseTurn = clockwiseTurns[direction]!!
val counterClockwiseTurn = counterClockwiseTurns[direction]!!
val neighbors =
setOf(
Triple(position + direction, direction, score + STEP_SCORE),
Triple(position + clockwiseTurn, clockwiseTurn, score + TURN_SCORE + STEP_SCORE),
Triple(position + counterClockwiseTurn, counterClockwiseTurn, score + TURN_SCORE + STEP_SCORE),
).filterNot { (position) -> this[position] == '#' }
queue.addAll(neighbors)
}
}
return scores.getValue(end)
}
}
}