day(14): add solution
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
03a4ebbdca
commit
bd4b174df9
2 changed files with 107 additions and 0 deletions
89
src/year2021/day14/Day14.kt
Normal file
89
src/year2021/day14/Day14.kt
Normal file
|
@ -0,0 +1,89 @@
|
|||
package year2021.day14
|
||||
|
||||
import readInput
|
||||
|
||||
typealias PolymerPair = String
|
||||
typealias PolymerRules = Map<PolymerPair, Char>
|
||||
typealias PolymerTemplate = Map<PolymerPair, Long>
|
||||
|
||||
data class Polymer(
|
||||
val rules: PolymerRules,
|
||||
val template: MutableMap<Char, Long>,
|
||||
val pairsInTemplate: MutableMap<PolymerPair, Long>
|
||||
) {
|
||||
constructor(rules: PolymerRules, template: String) : this(rules, template.associate {
|
||||
it to template.count { it2 -> it == it2 }.toLong()
|
||||
}.toMutableMap(), template.toPolymerTemplate().toMutableMap())
|
||||
|
||||
fun step() {
|
||||
val addedPairs = mutableMapOf<PolymerPair, Long>()
|
||||
|
||||
for ((pair, count) in pairsInTemplate) {
|
||||
if (!rules.contains(pair) || count == 0.toLong()) {
|
||||
continue
|
||||
}
|
||||
|
||||
val addedElement = rules[pair]!!
|
||||
val leftPair = pair[0].toString() + addedElement
|
||||
val rightPair = addedElement + pair[1].toString()
|
||||
|
||||
addedPairs[leftPair] = (addedPairs[leftPair] ?: 0) + count
|
||||
addedPairs[rightPair] = (addedPairs[rightPair] ?: 0) + count
|
||||
addedPairs[pair] = (addedPairs[pair] ?: 0) - count
|
||||
|
||||
// update frequency counter
|
||||
template[addedElement] = (template[addedElement] ?: 0) + count
|
||||
}
|
||||
|
||||
for ((pair, change) in addedPairs) {
|
||||
pairsInTemplate[pair] = (pairsInTemplate[pair] ?: 0) + change
|
||||
}
|
||||
}
|
||||
|
||||
val elements: Map<Char, Long>
|
||||
get() = template
|
||||
}
|
||||
|
||||
fun List<String>.toPolymerRules(): PolymerRules = this.associate {
|
||||
val (polymerPair, insertedElement) = it.split(" -> ")
|
||||
polymerPair to insertedElement[0]
|
||||
}
|
||||
|
||||
fun String.toPolymerTemplate(): PolymerTemplate =
|
||||
this.windowed(2)
|
||||
.fold(mapOf()) { template, it ->
|
||||
template + (it to template.getOrDefault(it, 0) + 1)
|
||||
}
|
||||
|
||||
fun part1(input: List<String>): Long {
|
||||
val polymer = Polymer(input.drop(2).toPolymerRules(), input.first())
|
||||
|
||||
repeat(10) {
|
||||
polymer.step()
|
||||
}
|
||||
|
||||
val elements = polymer.elements
|
||||
return elements.maxOf { it.value } - elements.minOf { it.value }
|
||||
}
|
||||
|
||||
fun part2(input: List<String>): Long {
|
||||
val polymer = Polymer(input.drop(2).toPolymerRules(), input.first())
|
||||
|
||||
repeat(40) {
|
||||
polymer.step()
|
||||
}
|
||||
|
||||
val elements = polymer.elements
|
||||
return elements.maxOf { it.value } - elements.minOf { it.value }
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val sample = readInput(14, "sample")
|
||||
val input = readInput(14, "input")
|
||||
|
||||
check(part1(sample) == 1588.toLong())
|
||||
println(part1(input))
|
||||
|
||||
check(part2(sample) == 2188189693529)
|
||||
println(part2(input))
|
||||
}
|
18
src/year2021/day14/sample.txt
Normal file
18
src/year2021/day14/sample.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
NNCB
|
||||
|
||||
CH -> B
|
||||
HH -> N
|
||||
CB -> H
|
||||
NH -> C
|
||||
HB -> C
|
||||
HC -> B
|
||||
HN -> C
|
||||
NN -> C
|
||||
BH -> H
|
||||
NC -> B
|
||||
NB -> B
|
||||
BN -> B
|
||||
BB -> N
|
||||
BC -> B
|
||||
CC -> N
|
||||
CN -> C
|
Loading…
Reference in a new issue