-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay14.kt
83 lines (64 loc) · 2.54 KB
/
Day14.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package adventofcode2023
import java.io.File
object Day14 {
private const val ROUNDED_ROCK = 'O'
private const val EMPTY = '.'
private val inputs = File("resources/adventofcode2023/Day14.txt").readLines()
private fun rollAll(rocks: List<String>, direction: Pair<Int, Int>): List<String> {
val rolled = rocks.map { it.toMutableList() }
val yIndices = if (direction.second < 0) rolled.indices else rolled.indices.reversed()
val xIndices = if (direction.first < 0) rolled[0].indices else rolled[0].indices.reversed()
for (y in yIndices) {
for (x in xIndices) {
if (rolled[y][x] == ROUNDED_ROCK) {
var nextX = x + direction.first
var nextY = y + direction.second
while (
nextY >= 0 && nextX >= 0 && nextY < rolled.size && nextX < rolled[nextY].size &&
rolled[nextY][nextX] == EMPTY
) {
rolled[nextY - direction.second][nextX - direction.first] = EMPTY
rolled[nextY][nextX] = ROUNDED_ROCK
nextX += direction.first
nextY += direction.second
}
}
}
}
return rolled.map { it.joinToString(separator = "") }
}
private fun spinCycle(rocks: List<String>): List<String> =
rollAll(rollAll(rollAll(rollAll(rocks, Pair(0, -1)), Pair(-1, 0)), Pair(0, 1)), Pair(1, 0))
private fun runSpinCycles(rocks: List<String>, cycles: Int): List<String> {
var current = rocks
val history = mutableListOf<List<String>>()
var cycle = 0
while (cycle < cycles) {
current = spinCycle(current)
val lastAppearedIndex = history.indexOf(current)
if (lastAppearedIndex > -1) {
val toAdd = cycle - lastAppearedIndex
cycle += ((cycles - cycle) / toAdd) * toAdd
}
history.add(current)
cycle++
}
return current
}
private fun calculateNorthLoad(rocks: List<String>): Int =
rocks.withIndex().sumOf { line ->
line.value.sumOf {
if (it == ROUNDED_ROCK) rocks.size - line.index else 0
}
}
fun part1() = println(
calculateNorthLoad(rollAll(inputs, Pair(0, -1)))
)
fun part2() = println(
calculateNorthLoad(runSpinCycles(inputs, 1000000000))
)
}
fun main() {
Day14.part1()
Day14.part2()
}