Skip to content

Commit 1ae5065

Browse files
committed
Day 14
1 parent 8ab2a82 commit 1ae5065

File tree

4 files changed

+242
-15
lines changed

4 files changed

+242
-15
lines changed

src/day14/Day14.kt

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package day14
2+
3+
import utils.verify
4+
import java.io.File
5+
6+
/** https://adventofcode.com/2021/day/14 */
7+
8+
fun main() {
9+
10+
val rootDir = File("src/day14/")
11+
12+
data class Insertion(val a: Char, val b: Char, val input: Char)
13+
data class Data(val polymer: String, val rules: List<Insertion>)
14+
15+
fun Data.allPosibilities(): Set<Char> =
16+
(this.polymer.toCharArray() + rules.map { it.a.toString() + it.b + it.input }
17+
.joinToString(separator = "") { it }.toCharArray()).toSet()
18+
19+
fun Data.polymerization(steps: Int): String {
20+
var polymer = this.polymer
21+
for (i in 0 until steps) {
22+
val array = CharArray(polymer.length * 2 - 1)
23+
polymer.windowed(2).forEachIndexed { pos, value ->
24+
array[pos * 2] = value[0]
25+
array[pos * 2 + 1] = this.rules.first { value[0] == it.a && value[1] == it.b }.input
26+
}
27+
array[array.size - 1] = polymer.last()
28+
polymer = array.concatToString()
29+
}
30+
return polymer
31+
}
32+
33+
34+
fun part1(data: Data): Int {
35+
val grouped = data.polymerization(10).groupBy { it }
36+
return grouped.maxOf { it.value.size } - grouped.minOf { it.value.size }
37+
}
38+
39+
fun MutableMap<String, Long>.append(pair: String, times: Long = 1) {
40+
this[pair] = (this[pair] ?: 0) + times
41+
}
42+
43+
fun MutableMap<String, Long>.drop(pair: String, times: Long = 1) {
44+
this[pair] = (this[pair] ?: 0) - times
45+
}
46+
47+
fun part2(data: Data): Long {
48+
val counts: MutableMap<String, Long> = mutableMapOf()
49+
val countsPlus: MutableMap<String, Long> = mutableMapOf()
50+
51+
data.polymer.windowed(2).forEach { counts.append(it) }
52+
53+
// print("0: ")
54+
// counts.forEach { (key, value) -> print("$key: $value, ") }
55+
// println()
56+
57+
for (i in 0 until 40) {
58+
counts.forEach { count ->
59+
data.rules.first { it.a == count.key[0] && it.b == count.key[1] }.let { insertion ->
60+
countsPlus.append(insertion.a.toString() + insertion.input.toString(), count.value)
61+
countsPlus.append(insertion.input.toString() + insertion.b.toString(), count.value)
62+
countsPlus.drop(count.key, count.value)
63+
}
64+
}
65+
countsPlus.forEach { (key, value) -> counts[key] = (counts[key] ?: 0) + value }
66+
countsPlus.clear()
67+
counts.filter { it.value == 0L }.forEach { counts.remove(it.key) }
68+
// print("${i + 1}: ")
69+
// counts.forEach { (key, value) -> print("$key: $value, ") }
70+
// println()
71+
}
72+
73+
val result: MutableMap<Char, Long> = mutableMapOf()
74+
data.allPosibilities().forEach {
75+
result[it] = 0
76+
}
77+
78+
counts.map { it.key[0] to it.value }.forEach { result[it.first] = (result[it.first] ?: 0) + it.second }
79+
result[data.polymer.last()] = (result[data.polymer.last()] ?: 0) + 1
80+
81+
return result.maxOf { it.value } - result.minOf { it.value }
82+
}
83+
84+
// ---- RUN
85+
86+
fun File.read(): Data {
87+
var polymer = ""
88+
val rules = mutableListOf<Insertion>()
89+
readLines().forEachIndexed { id, value ->
90+
when (id) {
91+
0 -> polymer = value
92+
1 -> {}
93+
else -> rules.add(Insertion(value[0], value[1], value[6]))
94+
}
95+
}
96+
rules.sortBy { it.a }
97+
return Data(polymer, rules)
98+
}
99+
100+
val testData = File(rootDir, "input_test.txt").read()
101+
val data = File(rootDir, "input.txt").read()
102+
103+
verify(1588, part1(testData))
104+
verify(3306, part1(data))
105+
106+
verify(2188189693529, part2(testData))
107+
verify(3760312702877, part2(data))
108+
}

src/day14/input.txt

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
CBNBOKHVBONCPPBBCKVH
2+
3+
FK -> O
4+
BK -> B
5+
PB -> N
6+
VS -> P
7+
OF -> H
8+
KP -> K
9+
PS -> K
10+
OV -> N
11+
FO -> H
12+
KN -> P
13+
HF -> K
14+
BV -> N
15+
OO -> B
16+
KC -> V
17+
CK -> H
18+
BC -> P
19+
VV -> S
20+
NS -> C
21+
SF -> O
22+
BN -> V
23+
NH -> N
24+
VP -> F
25+
KH -> S
26+
BO -> N
27+
VN -> K
28+
BB -> H
29+
CH -> H
30+
HP -> O
31+
KK -> O
32+
CB -> S
33+
VC -> P
34+
FH -> B
35+
SP -> C
36+
NF -> O
37+
HN -> N
38+
PO -> P
39+
PP -> C
40+
SO -> F
41+
FB -> B
42+
SB -> B
43+
SC -> B
44+
HK -> O
45+
BF -> V
46+
OB -> B
47+
NC -> V
48+
HC -> F
49+
KO -> C
50+
NV -> C
51+
HB -> H
52+
FP -> S
53+
OS -> O
54+
HH -> K
55+
OK -> B
56+
OH -> C
57+
NP -> V
58+
SN -> H
59+
SK -> B
60+
HV -> F
61+
VF -> P
62+
CP -> H
63+
FN -> H
64+
FV -> B
65+
CN -> H
66+
OC -> O
67+
KV -> P
68+
CF -> B
69+
OP -> B
70+
FC -> O
71+
PC -> B
72+
CV -> S
73+
PV -> H
74+
VK -> N
75+
SS -> C
76+
HO -> F
77+
VH -> C
78+
NB -> S
79+
NN -> F
80+
FF -> K
81+
CC -> H
82+
SV -> H
83+
CO -> K
84+
BP -> O
85+
SH -> H
86+
KS -> K
87+
FS -> F
88+
PF -> S
89+
BS -> H
90+
VO -> H
91+
NK -> F
92+
PK -> B
93+
KB -> K
94+
CS -> C
95+
VB -> V
96+
BH -> O
97+
KF -> N
98+
HS -> H
99+
PH -> K
100+
ON -> H
101+
PN -> K
102+
NO -> S

src/day14/input_test.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
NNCB
2+
3+
CH -> B
4+
HH -> N
5+
CB -> H
6+
NH -> C
7+
HB -> C
8+
HC -> B
9+
HN -> C
10+
NN -> C
11+
BH -> H
12+
NC -> B
13+
NB -> B
14+
BN -> B
15+
BB -> N
16+
BC -> B
17+
CC -> N
18+
CN -> C

src/dayXX/DayXX.kt

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,29 @@ package dayXX
33
import utils.verify
44
import java.io.File
55

6-
/** https://adventofcode.com/2021/day/TODO */
6+
/** https://adventofcode.com/2021/day/XX */
77

88
fun main() {
99

10-
fun part1(numbers: List<String>): Int {
11-
return TODO()
12-
}
13-
10+
val rootDir = File("src/dayXX/")
1411

15-
fun part2(numbers: List<String>): Int {
16-
return TODO()
12+
fun part1(data: List<String>): Int {
13+
return -1
1714
}
1815

19-
// ---- TEST
20-
21-
val testNumbers = File("src/dayXX/input_test.txt").readLines()
2216

23-
verify(TODO(), part1(testNumbers))
24-
verify(TODO(), part2(testNumbers))
17+
fun part2(data: List<String>): Int {
18+
return -1
19+
}
2520

2621
// ---- RUN
2722

28-
val numbers = File("src/dayXX/input.txt").readLines()
23+
val testData = File(rootDir, "input_test.txt").readLines()
24+
val data = File(rootDir, "input.txt").readLines()
25+
26+
verify(0, part1(testData))
27+
verify(0, part1(data))
2928

30-
verify(TODO(), part1(numbers))
31-
verify(TODO(), part2(numbers))
29+
verify(0, part2(testData))
30+
verify(0, part2(data))
3231
}

0 commit comments

Comments
 (0)