Advertisement
Guest User

AOC - 2024 day 16

a guest
Dec 16th, 2024
431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 3.62 KB | Software | 0 0
  1. class ReindeerGames(lines: List<String>) {
  2.     private val width = lines[0].length
  3.     private val height = lines.size
  4.     private val walls = mutableSetOf<Pair<Int, Int>>()
  5.     private val startPos: Pair<Int, Int>
  6.     private val endPos: Pair<Int, Int>
  7.  
  8.     init {
  9.         var theStartPos = 0 to 0
  10.         var theEndPos = 0 to 0
  11.         lines.indices.forEach { y ->
  12.             lines[y].indices.forEach { x ->
  13.                 if (lines[y][x] == '#') {
  14.                     walls.add(y to x)
  15.                 }
  16.                 if (lines[y][x] == 'S') {
  17.                     theStartPos = y to x
  18.                 }
  19.                 if (lines[y][x] == 'E') {
  20.                     theEndPos = y to x
  21.                 }
  22.             }
  23.         }
  24.  
  25.         startPos = theStartPos
  26.         endPos = theEndPos
  27.     }
  28.  
  29.     fun runRudolphRun(): Pair<Int, Int> {
  30.         val deerList = mutableListOf(
  31.             Deer(startPos, 0 to 1, 0, mutableSetOf()),
  32.             Deer(startPos, -1 to 0, 1000, mutableSetOf())
  33.         )
  34.  
  35.         val scores = mutableMapOf<Pair<Int, Int>, Int>()
  36.         val deerAtEnd = mutableListOf<Deer>()
  37.  
  38.         while (deerList.isNotEmpty()) {
  39.             val deer = deerList.removeAt(0)
  40.             while(true) {
  41.                 deer.forward()
  42.                 if (walls.contains(deer.pos)) break
  43.                 if (deer.visited.contains(deer.pos)) break
  44.                 if ((scores[deer.pos] ?: Int.MAX_VALUE) < deer.score - 1000) break
  45.                 if (!walls.contains(deer.pos + deer.direction.turnRight()))
  46.                     deerList.add(Deer(deer.pos, deer.direction.turnRight(), deer.score + 1000, deer.visited.toMutableSet()))
  47.                 if (!walls.contains(deer.pos + deer.direction.turnLeft()))
  48.                     deerList.add(Deer(deer.pos, deer.direction.turnLeft(), deer.score + 1000, deer.visited.toMutableSet()))
  49.                 if ((scores[deer.pos] ?: Int.MAX_VALUE) > deer.score) {
  50.                     scores[deer.pos] = deer.score
  51.                 }
  52.                 if (deer.pos == endPos) {
  53.                     deerAtEnd.add(deer)
  54.                     break
  55.                 }
  56.             }
  57.             if (deer.pos == endPos) {
  58.                 Thread.sleep(250)
  59.                 printVisited(deer.visited)
  60.             }
  61.         }
  62.         val part1 = scores[endPos]!!
  63.         val part2 = deerAtEnd.asSequence().filter { it.score == scores[endPos] }.map { it.visited }.flatten().toSet().count() + 1
  64.         return part1 to part2
  65.     }
  66.  
  67.     private class Deer(var pos: Pair<Int, Int>, val direction: Pair<Int, Int>, var score: Int, val visited: MutableSet<Pair<Int, Int>>) {
  68.         fun forward() {
  69.             visited.add(pos)
  70.             pos += direction
  71.             score += 1
  72.         }
  73.     }
  74.  
  75.     private fun printVisited(visited: MutableSet<Pair<Int, Int>>) {
  76.         repeat(height) { y ->
  77.             repeat(width) { x ->
  78.                 if (visited.contains(y to x)) print("#")
  79.                 else if (walls.contains(y to x)) print("|")
  80.                 else print(" ")
  81.             }
  82.             println()
  83.         }
  84.     }
  85.  
  86.     private operator fun Pair<Int, Int>.minus(other: Pair<Int, Int>): Pair<Int, Int> {
  87.         return first - other.first to second - other.second
  88.     }
  89.  
  90.     private fun Pair<Int, Int>.turnRight() = when (this) {
  91.         0 to 1 -> 1 to 0
  92.         1 to 0 -> 0 to -1
  93.         0 to -1 -> -1 to 0
  94.         else -> 0 to 1
  95.     }
  96.  
  97.     private fun Pair<Int, Int>.turnLeft() = this.turnRight().turnRight().turnRight()
  98. }
  99.  
  100.  
  101. private operator fun Pair<Int, Int>.plus(other: Pair<Int, Int>): Pair<Int, Int> {
  102.     return first + other.first to second + other.second
  103. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement