Skip to content

Commit 183753e

Browse files
committed
Solution 2018-12, part 1 (Subterranean Sustainability)
1 parent 7e621a3 commit 183753e

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package de.ronny_h.aoc.year2018.day12
2+
3+
import de.ronny_h.aoc.AdventOfCode
4+
import de.ronny_h.aoc.extensions.collections.split
5+
6+
fun main() = SubterraneanSustainability().run(3798, 0)
7+
8+
class SubterraneanSustainability : AdventOfCode<Int>(2018, 12) {
9+
override fun part1(input: List<String>): Int {
10+
val pots = GameOfPlants(input, 20)
11+
pots.simulateGenerations()
12+
return pots.sumOfPlantContainingPotNumbers()
13+
}
14+
15+
override fun part2(input: List<String>): Int {
16+
return 0
17+
}
18+
}
19+
20+
class GameOfPlants(input: List<String>, val generations: Int) {
21+
private val plant = '#'
22+
private val noPlant = '.'
23+
private val initialState = input.first().substringAfter("initial state: ")
24+
25+
// a rule has the form of: LLCRR => N
26+
private val plantProducingPatterns = input.split()[1]
27+
.map { it.split(" => ") }
28+
.filter { it[1] == "$plant" }
29+
.map { it.first() }
30+
.toSet()
31+
private val patternLength = 5
32+
private val patternCenter = 2
33+
34+
// per generation the plants grow max 2 pots wider in each direction
35+
private val offset = generations * 2
36+
private val padding = "$noPlant".repeat(offset)
37+
38+
var currentGeneration = padding + initialState + padding
39+
private set
40+
41+
fun nextGeneration(): String {
42+
val nextGen = currentGeneration.toMutableList()
43+
44+
for (index in 0..nextGen.lastIndex - patternLength) {
45+
nextGen[index + patternCenter] =
46+
if (currentGeneration.substring(index, index + patternLength) in plantProducingPatterns) {
47+
plant
48+
} else {
49+
noPlant
50+
}
51+
}
52+
currentGeneration = nextGen.joinToString("")
53+
return currentGeneration
54+
}
55+
56+
fun sumOfPlantContainingPotNumbers(): Int =
57+
currentGeneration.foldIndexed(0) { i, acc, pot ->
58+
if (pot == plant) acc + i - offset else acc
59+
}
60+
61+
fun simulateGenerations() {
62+
println("generation 0:$currentGeneration")
63+
repeat(generations) {
64+
nextGeneration()
65+
println("generation ${"%2d".format(it + 1)}: $currentGeneration")
66+
}
67+
}
68+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package de.ronny_h.aoc.year2018.day12
2+
3+
import de.ronny_h.aoc.extensions.asList
4+
import io.kotest.core.spec.style.StringSpec
5+
import io.kotest.matchers.shouldBe
6+
import io.kotest.matchers.string.shouldContain
7+
8+
class SubterraneanSustainabilityTest : StringSpec({
9+
10+
val input = """
11+
initial state: #..#.#..##......###...###
12+
13+
...## => #
14+
..#.. => #
15+
.#... => #
16+
.#.#. => #
17+
.#.## => #
18+
.##.. => #
19+
.#### => #
20+
#.#.# => #
21+
#.### => #
22+
##.#. => #
23+
##.## => #
24+
###.. => #
25+
###.# => #
26+
####. => #
27+
""".asList()
28+
29+
"the first generation of the sample input" {
30+
GameOfPlants(input, 20).nextGeneration() shouldContain "...#...#....#.....#..#..#..#..........."
31+
}
32+
33+
"part 1: the sum of the numbers of plant-containing pots after the 20th generation" {
34+
SubterraneanSustainability().part1(input) shouldBe 325
35+
}
36+
37+
"part 2" {
38+
val input = listOf("")
39+
SubterraneanSustainability().part2(input) shouldBe 0
40+
}
41+
})

0 commit comments

Comments
 (0)