generated from Jadarma/advent-of-code-kotlin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathY2016D09.kt
39 lines (33 loc) · 1.49 KB
/
Y2016D09.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
package aockt.y2016
import io.github.jadarma.aockt.core.Solution
object Y2016D09 : Solution {
/** The expression that parses a compression marker, denoting how many characters to repeat how many times. */
private val repeatRegex = Regex("""\((\d+)x(\d+)\)""")
/**
* Returns the unpacked length of the [input] if it would be decompressed. Use along with [allowRecursion] to check
* for final length and check for fork bombs.
*/
private fun unpackedLengthOf(input: String, allowRecursion: Boolean = false): Long {
var index = 0
var decodedLength = 0L
while (index < input.length) {
val match = repeatRegex.find(input, index)
if (match == null || match.range.first != index) {
decodedLength++
index++
continue
}
val markerSize = match.value.length
val size = match.destructured.component1().toInt()
val repeats = match.destructured.component2().toInt()
decodedLength += repeats * when (allowRecursion) {
true -> unpackedLengthOf(input.substring(index + markerSize, index + markerSize + size), true)
else -> size.toLong()
}
index += size + markerSize
}
return decodedLength
}
override fun partOne(input: String) = unpackedLengthOf(input, allowRecursion = false)
override fun partTwo(input: String) = unpackedLengthOf(input, allowRecursion = true)
}