<Advent of Code 2021 day 20> :thread:
# advent-of-code
a
i
So, did everyone get
#
in the beginning of the algorithm line and
.
in the end as opposed to the example input?
d
Yes. Ugh!
m
Yes. Neat! 🙂
d
I think my CPU hates me for doing all these loops. It was definitely a neat twist to make you think what's happening to those cells outside the boundary of the image.
e
https://github.com/ephemient/aoc2021/blob/main/kt/src/commonMain/kotlin/com/github/ephemient/aoc2021/Day20.kt Eric was evil with today's inputs, but even with the twist, this wasn't too bad
🙊 1
n
I think with '#' at the beginning and at the end of the algorithm, the answer to both parts would be "infinite". And with '#' at the beginning, every odd iteration after the first will also have "infinite" as answer. Seems we finally found the dark matter!
🤣 1
d
n
Hopefully the puzzle complexities are aligned with weekends. I don't think I will have time for Day19-level problems during work days...
🤞 2
d
There’s no easter egg in the image sadly, just noise: https://gist.github.com/dfings/b320b36160b3c937efc6c76dede15091
18 and 19 were a double whammy
☝️ 1
m
j
Why using some
#
and
.
to represent colors, when you can run Kotlin on JVM and use BufferedImage…
Copy code
val light = Color.WHITE
val dark = Color.BLACK

fun color(c: Char) = when (c) {
    '.' -> light
    '#' -> dark
    else -> error("wtf '$c'")
}

operator fun BufferedImage.get(row: Int, column: Int): Int {
    val outside = getRGB(0, 0)
    return (row - 1..row + 1).map { y ->
        if (y !in 0 until height) listOf(outside, outside, outside)
        else (column - 1..column + 1).map { x ->
            if (x !in 0 until width) outside
            else getRGB(x, y)
        }
    }
        .flatten()
        .fold(0) { acc, i -> acc * 2 + if (i == dark.rgb) 1 else 0 }
}

fun BufferedImage.enhanced(alg: List<Color>) =
    BufferedImage(width, height, type).also { result ->
        (0 until width).forEach { x ->
            (0 until height).forEach { y -> result.setRGB(x, y, alg[this[y, x]].rgb) }
        }
    }

fun BufferedImage.count(): Int = (0 until width).sumOf { x ->
    (0 until height).count { y -> getRGB(x, y) == dark.rgb }
}

val border = 50

fun renderAsBitmap(data: List<String>): BufferedImage {
    val image = BufferedImage(
        border + data[0].length + border,
        border + data.size + border,
        BufferedImage.TYPE_BYTE_INDEXED
    )
    (0 until image.width).forEach { x ->
        (0 until image.height).forEach { y -> image.setRGB(x, y, light.rgb) }
    }
    data.forEachIndexed { row, line ->
        line.forEachIndexed { col, c -> image.setRGB(col + border, row + border, color(c).rgb) }
    }

    return image
}

fun part1(input: List<String>): Int {
    val alg = input.first().map { color(it) }
    var image = renderAsBitmap(input.drop(2))
    repeat(2) { image = image.enhanced(alg) }
    return image.count()
}

fun part2(input: List<String>): Int {
    val alg = input.first().map { color(it) }

    AnimGif(File("src", "Day20.gif")).use { animGif ->

        var image = renderAsBitmap(input.drop(2))
            .also { animGif += it }

        repeat(50) { r ->
            image = image.enhanced(alg)
                .also { if ((r % 2) == 1) animGif += it }
        }
        return image.count()
    }
}
K 1
m
@Jakub Gwóźdź where picture?
😄
j

https://github.com/jakubgwozdz/advent-of-code-2021-in-kotlin/raw/main/src/Day20.gif

🙂
K 1
j
Share my solution using JetBrains template: https://github.com/Jintin/AdventCode2021/blob/main/src/Day20.kt
d
@Edgars you're close! According to the About page: "every problem has a solution that completes in at most 15 seconds on ten-year-old hardware."
e
Hah, that's brutal, since I'm on a 2015 MBP. 😄
n
@Edgars: pretty sure it's not a fair comparison, but a
./gradlew test --tests Day20
for my repo finishes in 1.2 seconds
m
I think mine is pretty concise:
p
https://github.com/tKe/aoc-21/blob/main/kotlin/src/main/kotlin/year2021/Day20.kt not as concise 🤣 but I hope it at least makes sense
@Edgars I ran yours on my PC - took 39ms to solve part1, and part2 took 8245ms
I think I spent more time working out the
toString()
for my image using the 2x2 block chars to make the output compact than I did on actually solving the problem 🙂