-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day12.kt
52 lines (48 loc) · 2.05 KB
/
Day12.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
package com.github.ephemient.aoc2023
class Day12(input: String) {
private val input = input.lines().mapNotNull { line ->
val (lhs, rhs) = line.split(' ', limit = 2).takeIf { it.size == 2 }
?: return@mapNotNull null
lhs to rhs.split(',').map { it.toIntOrNull() ?: return@mapNotNull null }
}
suspend fun part1(): Long = input.parSum { (string, runs) -> calculate(string, runs).toLong() }
suspend fun part2(): Long = input.parSum { (string, runs) ->
calculate(List(5) { string }.joinToString(","), List(5) { runs }.flatten()).toLong()
}
companion object {
@Suppress("ComplexCondition")
private fun calculate(string: String, runs: List<Int>): Int {
val arr = runs.subList(0, runs.lastIndex).asReversed().fold(
IntArray(string.length) { i ->
if (
i + runs.last() > string.length ||
string.getOrElse(i - 1) { '.' } == '#' ||
(i until i + runs.last()).any { string[it] == '.' } ||
(i + runs.last() until string.length).any { string[it] == '#' }
) {
0
} else {
1
}
}
) { arr, run ->
IntArray(string.length) { i ->
if (i + run > string.length ||
string.getOrElse(i - 1) { '.' } == '#' ||
(i until (i + run).coerceAtMost(string.length)).any { string[it] == '.' } ||
string.getOrElse(i + run) { '.' } == '#'
) {
return@IntArray 0
}
var acc = 0
for (j in i + run + 1 until string.length) {
acc += arr[j]
if (string[j] == '#') break
}
acc
}
}
return arr.take(string.indexOf('#') + 1).sum()
}
}
}