Created
December 14, 2021 15:41
-
-
Save bartoszm/bfbb6a46bc11700ad4271a3bb11e9111 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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