Advertisement
Guest User

AOC - 2024 day 20

a guest
Dec 20th, 2024
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.20 KB | Software | 0 0
  1. package Y2024.D20
  2.  
  3. import kotlin.math.abs
  4.  
  5. class RaceCondition(val lines: List<String>) {
  6.     private val width = lines[0].length
  7.     private val height = lines.size
  8.     private val startY= lines.indexOfFirst { it.contains("S") }
  9.     private val startX = lines[startY].indexOf('S')
  10.     private val stepOnPositions = mutableMapOf<Pair<Int, Int>, Int>()
  11.  
  12.     fun runWhileCheating(distance: Int, minimalGain: Int): Int {
  13.         var cheatCount = 0
  14.         var step = 0
  15.         var pos: Pair<Int, Int>? = startY to startX
  16.         var prevPos = -1 to -1
  17.         do {
  18.             pos!!
  19.             stepOnPositions[pos] = step
  20.             cheatCount += pos.neighboursADistance(step, distance, minimalGain)
  21.  
  22.             step ++
  23.             val previous = pos
  24.             pos = pos.next(prevPos)
  25.             prevPos = previous
  26.         } while (pos != null)
  27.         return cheatCount
  28.     }
  29.  
  30.     private fun Pair<Int, Int>.next(prevPos: Pair<Int, Int>): Pair<Int, Int>? {
  31.         return when {
  32.             isValidTile(this + (1 to 0), prevPos) -> this + (1 to 0)
  33.             isValidTile(this + (0 to 1), prevPos) -> this + (0 to 1)
  34.             isValidTile(this + (-1 to 0), prevPos) -> this + (-1 to 0)
  35.             isValidTile(this + (0 to -1), prevPos) -> this + (0 to -1)
  36.             else -> null
  37.         }
  38.     }
  39.  
  40.     private fun Pair<Int, Int>.neighboursADistance(step: Int, distance: Int, minimalGain: Int): Int {
  41.         var count = 0
  42.         (-distance..distance).forEach { yOffset ->
  43.             val xDistance = distance - abs(yOffset)
  44.             (-xDistance..xDistance).forEach { xOffset ->
  45.                 stepOnPositions[this.first + yOffset to this.second + xOffset]?.let { otherStep ->
  46.                     val savedSteps = step - otherStep - abs(yOffset) - abs(xOffset)
  47.                     if (savedSteps >= minimalGain) count++
  48.                 }
  49.             }
  50.         }
  51.         return count
  52.     }
  53.  
  54.     private fun isValidTile(tile: Pair<Int, Int>, prevPos: Pair<Int, Int>) =
  55.         prevPos != tile && lines[tile.first][tile.second] != '#'
  56.  
  57.     private operator fun Pair<Int, Int>.plus(other: Pair<Int, Int>): Pair<Int, Int> {
  58.         return first + other.first to second + other.second
  59.     }
  60. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement