Advertisement
Guest User

Untitled

a guest
Dec 14th, 2023
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 3.78 KB | Source Code | 0 0
  1. class Platform(private val rocks: List<String>) {
  2.     fun rollNorthAndCalculateLoad() = calculateLoad(rollNorth(rocks))
  3.  
  4.     fun spinAndCalculateLoad(times: Int): Long {
  5.         var spinningRocks = rocks
  6.         val knownFormations = mutableListOf<List<String>>()
  7.        
  8.         var cyclesUpToRepeat = 0
  9.         while (!knownFormations.contains(spinningRocks)) {
  10.             cyclesUpToRepeat ++
  11.             knownFormations.add(spinningRocks)
  12.             spinningRocks = rollEast(rollSouth(rollWest(rollNorth(spinningRocks))))
  13.         }
  14.  
  15.         var cycleLength = 0
  16.         val cycleFormations = mutableListOf<List<String>>()
  17.         while (!cycleFormations.contains(spinningRocks)) {
  18.             cycleLength ++
  19.             cycleFormations.add(spinningRocks)
  20.             spinningRocks = rollEast(rollSouth(rollWest(rollNorth(spinningRocks))))
  21.         }
  22.  
  23.         val leftOverSteps = (times - cyclesUpToRepeat) % cycleLength
  24.  
  25.         repeat(leftOverSteps) {
  26.             spinningRocks = rollEast(rollSouth(rollWest(rollNorth(spinningRocks))))
  27.         }
  28.  
  29.         return calculateLoad(spinningRocks)
  30.     }
  31.  
  32.     private fun calculateLoad(rolledNorth: List<String>) = rolledNorth.mapIndexed { y, rockLine ->
  33.         rockLine.count { it == 'O' } * (rolledNorth.size - y).toLong()
  34.     }.sum()
  35.  
  36.     private fun rollNorth(rocks: List<String>): List<String> {
  37.         val northRocks = rocks.map { it.toMutableList() }.toMutableList()
  38.         (1 until rocks.size).forEach { y ->
  39.             rocks[y].forEachIndexed { x, rock ->
  40.                 if (rock == 'O' && northRocks[y - 1][x] == '.') {
  41.                     var step = y - 1
  42.                     while (step >= 0 && northRocks[step][x] == '.') step--
  43.                     northRocks[step + 1][x] = 'O'
  44.                     northRocks[y][x] = '.'
  45.                 }
  46.             }
  47.         }
  48.         return northRocks.map { it.joinToString("") }.toList()
  49.     }
  50.  
  51.     private fun rollWest(rocks: List<String>): List<String> {
  52.         val westRocks = rocks.map { it.toMutableList() }.toMutableList()
  53.         (1 until rocks[0].length).forEach { x ->
  54.             (0 until rocks.size).forEach { y ->
  55.                 if (rocks[y][x] == 'O' && westRocks[y][x - 1] == '.') {
  56.                     var step = x - 1
  57.                     while (step >= 0 && westRocks[y][step] == '.') step--
  58.                     westRocks[y][step + 1] = 'O'
  59.                     westRocks[y][x] = '.'
  60.                 }
  61.             }
  62.         }
  63.         return westRocks.map { it.joinToString("") }.toList()
  64.     }
  65.  
  66.     private fun rollSouth(rocks: List<String>): List<String> {
  67.         val southRocks = rocks.map { it.toMutableList() }.toMutableList()
  68.         (rocks.size - 2 downTo 0).forEach { y ->
  69.             rocks[y].forEachIndexed { x, rock ->
  70.                 if (rock == 'O' && southRocks[y + 1][x] == '.') {
  71.                     var step = y + 1
  72.                     while (step < rocks.size && southRocks[step][x] == '.') step++
  73.                     southRocks[step - 1][x] = 'O'
  74.                     southRocks[y][x] = '.'
  75.                 }
  76.             }
  77.         }
  78.         return southRocks.map { it.joinToString("") }.toList()
  79.     }
  80.  
  81.     private fun rollEast(rocks: List<String>): List<String> {
  82.         val eastRocks = rocks.map { it.toMutableList() }.toMutableList()
  83.         (rocks[0].length - 2 downTo 0).forEach { x ->
  84.             (0 until rocks.size).forEach { y ->
  85.                 if (rocks[y][x] == 'O' && eastRocks[y][x + 1] == '.') {
  86.                     var step = x + 1
  87.                     while (step < rocks[0].length && eastRocks[y][step] == '.') step++
  88.                     eastRocks[y][step - 1] = 'O'
  89.                     eastRocks[y][x] = '.'
  90.                 }
  91.             }
  92.         }
  93.         return eastRocks.map { it.joinToString("") }.toList()
  94.     }
  95. }
Tags: adventofcode
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement