Skip to content

Instantly share code, notes, and snippets.

@bartoszm
Created December 14, 2021 15:41
Show Gist options
  • Save bartoszm/bfbb6a46bc11700ad4271a3bb11e9111 to your computer and use it in GitHub Desktop.
Save bartoszm/bfbb6a46bc11700ad4271a3bb11e9111 to your computer and use it in GitHub Desktop.
package day14
import java.nio.file.Files
import java.nio.file.Path
class Day14_Part2(val input: Input) {
val rules = input.rules.map { it.first to it.second }.toMap()
private fun find(s: String) = rules[s]
private fun sumUp(i: List<Pair<String, Long>>): Map<String, Long> = i.groupBy({ it.first }, {it.second})
.mapValues { it.value.sum() }
private fun sumUp(first: List<Pair<String, Long>>, second: List<Pair<String, Long>>) : Map<String, Long> {
return sumUp(first + second)
}
private fun step(chunks: Map<String, Long>, letters: Map<String,Long>) : Pair<Map<String, Long>, Map<String, Long>> {
val stepValues = chunks.map {c ->
val prevCount = c.value
find(c.key)?.let { l ->
c.key
val newChunks = listOf(
Pair(c.key[0] + l, prevCount),
Pair(l + c.key[1], prevCount),
Pair(c.key, -prevCount),
)
val letter = Pair(l, prevCount)
Pair(letter, newChunks)
}
}.filterNotNull()
val additionalChunks = stepValues.flatMap { it.second }
val additionalLetters = stepValues.map { it.first }
val newChunks = sumUp(chunks.map { it.toPair() }, additionalChunks)
val newLetters = sumUp(letters.map { it.toPair() }, additionalLetters)
return newChunks to newLetters
}
fun solve(times: Int = 40) : Long {
var letters = sumUp(input.template.map { it.toString() to 1L })
var chunks = sumUp(input.template.zipWithNext().map { cs -> cs.toList().joinToString("") to 1L })
(0 until times).forEach {
val result = step(chunks, letters)
chunks = result.first
letters = result.second
}
val min = letters.values.minOrNull() ?: 0
val max = letters.values.maxOrNull() ?: 0
return max - min
}
}
data class Input(val template: String, val rules: List<Pair<String, String>>)
fun parse(lines: List<String>) : Input {
val template = lines[0]
fun parse(line: String): Pair<String, String> = line.split("->").map { it.trim() }.toPair()
val rules = lines.drop(2).map { parse(it) }
return Input(template, rules)
}
fun main(args: Array<String>) {
val input = parse(Files.readAllLines(Path.of(args[0])))
println(Day14_Part2(input).solve())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment