generated from kotlin-hands-on/advent-of-code-kotlin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay11.kt
64 lines (55 loc) Β· 2.29 KB
/
Day11.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
open class MutableGrid<T>(val values: List<MutableList<T>>) {
val rows = values.size
val cols = values[0].size
val indices = (0 until rows).flatMap { i -> (0 until cols).map { j -> i to j } }
operator fun get(coords: Pair<Int, Int>) = values[coords.first][coords.second]
operator fun set(coords: Pair<Int, Int>, value: T) {
values[coords.first][coords.second] = value
}
fun getNeighbourCoordinates(coords: Pair<Int, Int>) = coords.let { (i, j) ->
listOf(i, i - 1, i + 1).flatMap { i -> listOf(j, j - 1, j + 1).map { j -> i to j } }
.filter { (i, j) -> i != -1 && j != -1 && i != rows && j != cols && !(i == coords.first && j == coords.second) }
}
override fun toString() = buildString {
values.forEach { row -> row.forEach { append("$it ") }; append("\n") }
}
}
class OctopusGrid(energyLevels: List<MutableList<Int>>) : MutableGrid<Int>(energyLevels) {
val FLASH_POINT = 10
fun simulateStepForFlashes(): Int {
var flashes = 0
// Everyone gains one energy level
indices.forEach { this[it] += 1 }
// Let the cascade begin!
while (indices.any { this[it] >= FLASH_POINT }) {
indices.forEach {
if (this[it] >= FLASH_POINT) {
this[it] = 0
getNeighbourCoordinates(it).forEach {
if (this[it] != 0) this[it] += 1
}
}
}
}
// Light show!
flashes += indices.count { this[it] == 0 }
return flashes
}
}
fun main() {
fun readOctopusGrid(input: List<String>): OctopusGrid =
OctopusGrid(input.map { it.map { it.digitToInt() }.toMutableList() })
fun part1(input: OctopusGrid): Int {
return (1..100).sumOf { input.simulateStepForFlashes() }
}
fun part2(input: OctopusGrid): Int {
return (1..Int.MAX_VALUE).first { input.simulateStepForFlashes() == input.indices.size }
}
// test if implementation meets criteria from the description, like:
val testInput = readInput("Day11_test")
check(part1(readOctopusGrid(testInput)) == 1656)
check(part2(readOctopusGrid(testInput)) == 195)
val input = readInput("Day11")
println(part1(readOctopusGrid(input)))
println(part2(readOctopusGrid(input)))
}