Skip to content

Commit 254da9a

Browse files
committed
Day 14
1 parent 244205c commit 254da9a

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

src/Day14.kt

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
fun main() {
2+
3+
val symbolsCount = 26
4+
val pairsCount = symbolsCount * symbolsCount
5+
6+
fun List<String>.parse(): Pair<List<Int>, Map<Int, Int>> {
7+
val template = first().map { it - 'A' }
8+
val rules = drop(2)
9+
.map { it.split(" -> ") }
10+
.associate { pair ->
11+
val leftChar = pair.first().first() - 'A'
12+
val rightChar = pair.first().last() - 'A'
13+
val middleChar = pair.last().first() - 'A'
14+
leftChar * symbolsCount + rightChar to middleChar
15+
}
16+
return Pair(template, rules)
17+
}
18+
19+
fun solve(template: List<Int>, rules: Map<Int, Int>, steps: Int): Long {
20+
val symbolsRange = 0 until symbolsCount
21+
val pairsRange = 0 until pairsCount
22+
23+
val d = Array(steps + 1) { Array(pairsCount) { LongArray(symbolsCount) { 0L } } }
24+
25+
for (i in pairsRange) {
26+
for (j in symbolsRange) {
27+
d[0][i][j] += if (j == i / symbolsCount) 1L else 0L
28+
d[0][i][j] += if (j == i % symbolsCount) 1L else 0L
29+
}
30+
}
31+
32+
for (step in 1..steps) {
33+
for (i in pairsRange) {
34+
val leftChar = i / symbolsCount
35+
val rightChar = i % symbolsCount
36+
val middleChar = rules[i] ?: continue
37+
38+
val leftPair = leftChar * symbolsCount + middleChar
39+
val rightPair = middleChar * symbolsCount + rightChar
40+
41+
for (j in symbolsRange) {
42+
d[step][i][j] = d[step - 1][leftPair][j] + d[step - 1][rightPair][j]
43+
}
44+
45+
d[step][i][middleChar] -= 1L
46+
}
47+
}
48+
49+
val result = LongArray(symbolsCount) { 0L }
50+
template.dropLast(1).forEachIndexed { index, value ->
51+
val pair = value * symbolsCount + template[index + 1]
52+
for (i in symbolsRange) {
53+
result[i] += d[steps][pair][i]
54+
}
55+
}
56+
template.drop(1).dropLast(1).forEach { result[it] -= 1L }
57+
58+
return result.filterNot { it == 0L }.maxOf { it } - result.filterNot { it == 0L }.minOf { it }
59+
}
60+
61+
fun part1(
62+
input: List<String>
63+
) = input.parse().let { (template, rules) -> solve(template, rules, 10) }
64+
65+
fun part2(
66+
input: List<String>
67+
) = input.parse().let { (template, rules) -> solve(template, rules, 40) }
68+
69+
val input = readInput("Day14")
70+
println(part1(input))
71+
println(part2(input))
72+
}

0 commit comments

Comments
 (0)