Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Platform(private val rocks: List<String>) {
- fun rollNorthAndCalculateLoad() = calculateLoad(rollNorth(rocks))
- fun spinAndCalculateLoad(times: Int): Long {
- var spinningRocks = rocks
- val knownFormations = mutableListOf<List<String>>()
- var cyclesUpToRepeat = 0
- while (!knownFormations.contains(spinningRocks)) {
- cyclesUpToRepeat ++
- knownFormations.add(spinningRocks)
- spinningRocks = rollEast(rollSouth(rollWest(rollNorth(spinningRocks))))
- }
- var cycleLength = 0
- val cycleFormations = mutableListOf<List<String>>()
- while (!cycleFormations.contains(spinningRocks)) {
- cycleLength ++
- cycleFormations.add(spinningRocks)
- spinningRocks = rollEast(rollSouth(rollWest(rollNorth(spinningRocks))))
- }
- val leftOverSteps = (times - cyclesUpToRepeat) % cycleLength
- repeat(leftOverSteps) {
- spinningRocks = rollEast(rollSouth(rollWest(rollNorth(spinningRocks))))
- }
- return calculateLoad(spinningRocks)
- }
- private fun calculateLoad(rolledNorth: List<String>) = rolledNorth.mapIndexed { y, rockLine ->
- rockLine.count { it == 'O' } * (rolledNorth.size - y).toLong()
- }.sum()
- private fun rollNorth(rocks: List<String>): List<String> {
- val northRocks = rocks.map { it.toMutableList() }.toMutableList()
- (1 until rocks.size).forEach { y ->
- rocks[y].forEachIndexed { x, rock ->
- if (rock == 'O' && northRocks[y - 1][x] == '.') {
- var step = y - 1
- while (step >= 0 && northRocks[step][x] == '.') step--
- northRocks[step + 1][x] = 'O'
- northRocks[y][x] = '.'
- }
- }
- }
- return northRocks.map { it.joinToString("") }.toList()
- }
- private fun rollWest(rocks: List<String>): List<String> {
- val westRocks = rocks.map { it.toMutableList() }.toMutableList()
- (1 until rocks[0].length).forEach { x ->
- (0 until rocks.size).forEach { y ->
- if (rocks[y][x] == 'O' && westRocks[y][x - 1] == '.') {
- var step = x - 1
- while (step >= 0 && westRocks[y][step] == '.') step--
- westRocks[y][step + 1] = 'O'
- westRocks[y][x] = '.'
- }
- }
- }
- return westRocks.map { it.joinToString("") }.toList()
- }
- private fun rollSouth(rocks: List<String>): List<String> {
- val southRocks = rocks.map { it.toMutableList() }.toMutableList()
- (rocks.size - 2 downTo 0).forEach { y ->
- rocks[y].forEachIndexed { x, rock ->
- if (rock == 'O' && southRocks[y + 1][x] == '.') {
- var step = y + 1
- while (step < rocks.size && southRocks[step][x] == '.') step++
- southRocks[step - 1][x] = 'O'
- southRocks[y][x] = '.'
- }
- }
- }
- return southRocks.map { it.joinToString("") }.toList()
- }
- private fun rollEast(rocks: List<String>): List<String> {
- val eastRocks = rocks.map { it.toMutableList() }.toMutableList()
- (rocks[0].length - 2 downTo 0).forEach { x ->
- (0 until rocks.size).forEach { y ->
- if (rocks[y][x] == 'O' && eastRocks[y][x + 1] == '.') {
- var step = x + 1
- while (step < rocks[0].length && eastRocks[y][step] == '.') step++
- eastRocks[y][step - 1] = 'O'
- eastRocks[y][x] = '.'
- }
- }
- }
- return eastRocks.map { it.joinToString("") }.toList()
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement