### Kotlin Solution

This one was similar to a previous year's problem, but it's thankfully in 2d.

#### Part 1

"Just" make a map of the rules, chunk the input into 5 char seedlings and map them to the rules.

Oh wait... it can grow left and right... better add some padding.

``````private fun answer1(initial: String, rules: Map<String, String>): Int {
val final = step(0, 20, initial, rules)
return calculatePlants(final)

}

private fun calculatePlants(final: String) =
final.mapIndexed { a, b -> a to b }
.filter { (a, b) -> b == '#' }.sumBy { (first) ->
first + -3
}

private tailrec fun step(
n: Int,
max: Int,
current: String,
rules: Map<String, String>
): String =
if (n >= max) {
current
} else {
step(
n + 1,
max,
"..\$current..."
.windowed(5, 1)
.joinToString("") { rules[it] ?: "." },
rules
)
}
``````

#### Part 2

This one seemed like it might be hard, but then I realized that part1 was fast enough that I could just do the first couple hundred and watch for loops.

I didn't get a loop, but I did see a consistency! I made a quick function to seek for that and voila! (That's French, for 'voila!')

``````private fun answer2(initial: String, rules: Map<String, String>) =
generateSequence(0L) { it + 1 }
.mapIndexed { i, it ->
calculatePlants(
step(0, it.toInt(), initial, rules)
).let { plants ->
plants + (50000000000L - it) * 86
}
}
.windowed(2, 1)
.dropWhile { it[0] != it[1] }
.first()
.first()
``````

#### Bonus Content

Single line:

Multi line:

Actual GIF output from AWT:

EDIT: FORGOT PLANT PUNS:
Um... hopefully this one isn't leaving you out in the weeds?

Er... put the petal to the metal?

Uh... Orange you glad I didn't say banana? (Does fruit count?)

Haha, love your visualisations! Always fascinating how such simple things can create such complexity.

(Slightly off-topic, but I once came across these "meta-pixel" in Conway's Game of Life which literally gave me goose bumps: youtube.com/watch?v=xP5-iIeKXE8)

GET. OUT. This is amazing. Thank you.

Full marks + animations + bonus plant puns! Checking for loops was a good idea. I didn't think of that until I cheated and looked at the discussion here :/

code of conduct - report abuse