From 186a70f34d2b04457ccc26ae3ad373309b4bc857 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Mon, 20 Dec 2021 10:33:22 +0100 Subject: [PATCH] day(20): add solution Signed-off-by: Matej Focko --- src/year2021/day20/Day20.kt | 77 +++++++++++++++++++++++++++++++++++ src/year2021/day20/sample.txt | 7 ++++ 2 files changed, 84 insertions(+) create mode 100644 src/year2021/day20/Day20.kt create mode 100644 src/year2021/day20/sample.txt diff --git a/src/year2021/day20/Day20.kt b/src/year2021/day20/Day20.kt new file mode 100644 index 0000000..0b1d706 --- /dev/null +++ b/src/year2021/day20/Day20.kt @@ -0,0 +1,77 @@ +package year2021.day20 + +import readInput + +data class Point(val x: Int, val y: Int) + +fun getSquare(pixel: Point): Iterable = + (pixel.y - 1..pixel.y + 1).flatMap { y -> (pixel.x - 1..pixel.x + 1).map { x -> Point(x, y) } } + +data class TrenchMap( + val algorithm: List, + val map: Map, + val default: Char = '.' +) { + fun get(key: Point): Char = map.getOrDefault(key, default) + fun get(x: Int, y: Int): Char = get(Point(x, y)) + + private val xs: IntRange + get() = (map.keys.minOf { it.x } - 2..map.keys.maxOf { it.x } + 2) + + private val ys: IntRange + get() = (map.keys.minOf { it.y } - 2..map.keys.maxOf { it.y } + 2) + + private val indices: Iterable + get() = ys.flatMap { y -> xs.map { x -> Point(x, y) } } + + fun print() { + for (y in ys) { + for (x in xs) { + print(get(x, y)) + } + println() + } + } + + private fun toIndex(square: Iterable): Int = + square.map { if (get(it) == '#') 1 else 0 }.fold(0) { acc, bit -> acc * 2 + bit } + + private fun enhancePixel(pixel: Point): Char = algorithm[toIndex(getSquare(pixel))] + + fun enhance(): TrenchMap = + TrenchMap( + algorithm, + indices.associateWith { enhancePixel(it) }, + when (default) { + '.' -> algorithm.first() + '#' -> algorithm.last() + else -> error("Invalid char found") + } + ) +} + +fun List.toTrenchMap(): TrenchMap = + TrenchMap( + this.first().toList(), + this.drop(2) + .flatMapIndexed { y, row -> + row.mapIndexed { x, cell -> Point(x, y) to cell } + }.toMap() + ) + +fun part1(input: TrenchMap): Int = + (1..2).fold(input) { acc, i -> acc.enhance() }.map.values.count { it == '#' } + +fun part2(input: TrenchMap): Int = + (1..50).fold(input) { acc, i -> acc.enhance() }.map.values.count { it == '#' } + +fun main() { + val sample = readInput(20, "sample").toTrenchMap() + val input = readInput(20, "input").toTrenchMap() + + check(part1(sample) == 35) + println(part1(input)) + + check(part2(sample) == 3351) + println(part2(input)) +} diff --git a/src/year2021/day20/sample.txt b/src/year2021/day20/sample.txt new file mode 100644 index 0000000..000a554 --- /dev/null +++ b/src/year2021/day20/sample.txt @@ -0,0 +1,7 @@ +..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..###..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#..#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#......#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#.....####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.......##..####..#...#.#.#...##..#.#..###..#####........#..####......#..# + +#..#. +#.... +##..# +..#.. +..### \ No newline at end of file