diff options
author | tchojnacki <tomaszchojnacki2001@gmail.com> | 2022-08-13 12:25:41 +0200 |
---|---|---|
committer | tchojnacki <tomaszchojnacki2001@gmail.com> | 2022-08-13 12:25:41 +0200 |
commit | 992d24939100a6adb466b23449a62c36736b4249 (patch) | |
tree | 778ff441bb0a14ac64aca2d6dde67b4133e566a0 /aoc-2021-kotlin/src/Day20.kt | |
parent | 2ef3cacc7766c55f3e40803e37864acc4bd4c918 (diff) | |
download | gleam_aoc2020-992d24939100a6adb466b23449a62c36736b4249.tar.gz gleam_aoc2020-992d24939100a6adb466b23449a62c36736b4249.zip |
Finish day 20
Diffstat (limited to 'aoc-2021-kotlin/src/Day20.kt')
-rw-r--r-- | aoc-2021-kotlin/src/Day20.kt | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/aoc-2021-kotlin/src/Day20.kt b/aoc-2021-kotlin/src/Day20.kt new file mode 100644 index 0000000..9bc3b01 --- /dev/null +++ b/aoc-2021-kotlin/src/Day20.kt @@ -0,0 +1,60 @@ +object Day20 { + private class Enhancement private constructor( + private val algorithm: BooleanArray, + private val initialImage: Set<Pos2D> + ) { + companion object { + fun fromString(string: String) = string.split("\n\n").let { (algorithm, image) -> + Enhancement( + algorithm.map { it == '#' }.toBooleanArray(), + image + .split("\n") + .withIndex() + .flatMap { (y, row) -> + row.withIndex().mapNotNull { (x, char) -> if (char == '#') Pos2D(x, y) else null } + } + .toSet() + ) + } + } + + private fun nextStateFor(currentImage: Set<Pos2D>, pos: Pos2D) = combinations(1 downTo -1) + .map { (dy, dx) -> if (currentImage.contains(pos + Pos2D(dx, dy))) 1 else 0 } + .withIndex() + .sumOf { (index, value) -> value shl index } + .let { algorithm[it] } + + fun enhance(times: Int): Int { + return generateSequence(StepState.initial(initialImage)) { (image, topLeft, bottomRight) -> + StepState( + combinations(topLeft.y..bottomRight.y, topLeft.x..bottomRight.x) + .mapNotNull { (y, x) -> + Pos2D(x, y).let { if (nextStateFor(image, it)) it else null } + }.toSet(), + topLeft + Pos2D(1, 1), + bottomRight - Pos2D(1, 1) + ) + }.drop(times).first().image.size + } + } + + private data class StepState(val image: Set<Pos2D>, val topLeft: Pos2D, val bottomRight: Pos2D) { + companion object { + fun initial(image: Set<Pos2D>) = StepState(image, Pos2D(-100, -100), Pos2D(200, 200)) + } + } + + fun part1(input: String) = Enhancement.fromString(input).enhance(2) + + fun part2(input: String) = Enhancement.fromString(input).enhance(50) +} + +fun main() { + val testInput = readInputAsString("Day20_test") + check(Day20.part1(testInput) == 35) + check(Day20.part2(testInput) == 3351) + + val input = readInputAsString("Day20") + println(Day20.part1(input)) + println(Day20.part2(input)) +} |