Day 16 part 1
This commit is contained in:
parent
9d8ff39832
commit
cfdd6bcde4
1 changed files with 62 additions and 1 deletions
|
@ -1,3 +1,64 @@
|
|||
fun main() {
|
||||
import java.util.PriorityQueue
|
||||
|
||||
data class Position(val coordinate: Grid.Coordinate, val direction: Direction)
|
||||
|
||||
fun main() {
|
||||
val grid = CharGrid.read("day16.txt")
|
||||
val start = grid.find('S')!!
|
||||
val goal = grid.find('E')!!
|
||||
|
||||
val startPosition = Position(start, Direction.East)
|
||||
|
||||
val part1 = dijkstra(startPosition, goal = { it.coordinate == goal }) { current ->
|
||||
Direction.entries
|
||||
.asSequence()
|
||||
.map { Position(current.coordinate.step(it), it) }
|
||||
.filter { grid[it.coordinate] != '#' }
|
||||
.map { it to 1 + current.direction.turns(it.direction) * 1000 }
|
||||
}
|
||||
println("Part 1: $part1")
|
||||
}
|
||||
|
||||
fun Direction.turns(to: Direction): Int = when {
|
||||
this == to -> 0
|
||||
this == Direction.North && (to == Direction.East || to == Direction.West) -> 1
|
||||
this == Direction.North && to == Direction.South -> 2
|
||||
this == Direction.East && (to == Direction.North || to == Direction.South) -> 1
|
||||
this == Direction.East && to == Direction.West -> 2
|
||||
this == Direction.South && (to == Direction.West || to == Direction.East) -> 1
|
||||
this == Direction.South && to == Direction.North -> 2
|
||||
this == Direction.West && (to == Direction.North || to == Direction.South) -> 1
|
||||
this == Direction.West && to == Direction.East -> 2
|
||||
else -> error("Missing directions")
|
||||
}
|
||||
|
||||
fun <T> dijkstra(start: T, goal: (T) -> Boolean, neighbors: (T) -> Sequence<Pair<T, Int>>): Int? {
|
||||
val distanceFromStart = mutableMapOf(start to 0)
|
||||
val visited = mutableSetOf<T>()
|
||||
val queue = PriorityQueue<Pair<T, Int>> { a, b -> a.second.compareTo(b.second) }
|
||||
|
||||
queue.add(start to 0)
|
||||
|
||||
while (true) {
|
||||
val (current, totalDistance) = queue.poll() ?: break
|
||||
if (goal(current)) {
|
||||
return totalDistance
|
||||
}
|
||||
|
||||
visited.add(start)
|
||||
|
||||
for ((neighbor, distance) in neighbors(current)) {
|
||||
if (neighbor in visited) continue;
|
||||
|
||||
val newDistance = totalDistance + distance
|
||||
|
||||
val currentDistance = distanceFromStart[neighbor]
|
||||
if (currentDistance == null || newDistance < currentDistance) {
|
||||
distanceFromStart[neighbor] = newDistance
|
||||
queue.add(neighbor to newDistance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
Loading…
Add table
Reference in a new issue