DEV Community

Discussion on: AoC Day 11: Chronal Charge

Collapse
 
jbristow profile image
Jon Bristow • Edited

Kotlin Solution

<brag type="unseemly">I took a night off on Saturday (#9), and ceded my top spot to @tech31842. However, it looks like I'm back in business!</brag>

Part 1

Simple enough... a brute force check was fractions of a second.

fun powerLevel(serial: Int, point: Point): Int {
    return ((point.x + 10) * point.y + serial) * (point.x + 10)
}

private fun answer1(input: Int): Point {
    return (2..299).map { x ->
        (2..299).map { y ->
            Point(x - 1, y - 1) to powerLevel(input, Point(x - 1, y - 1)) +
                    powerLevel(input, Point(x - 1, y)) +
                    powerLevel(input, Point(x - 1, y + 1)) +
                    powerLevel(input, Point(x, y - 1)) +
                    powerLevel(input, Point(x, y)) +
                    powerLevel(input, Point(x, y + 1)) +
                    powerLevel(input, Point(x + 1, y - 1)) +
                    powerLevel(input, Point(x + 1, y)) +
                    powerLevel(input, Point(x + 1, y + 1))
        }.maxBy {
            it.second
        }!!
    }.maxBy { it.second }!!.first
}

Part 2

This one took some luck I think. I had it chunking through these as fast as I could, but it was still was going to take a few minutes. Luckily I had it printing out the results for each size, and I tried the point where it seemed to find the first maximum. I tried figuring out if I could detect this more easily, but I lost interest. I think I'll get some sleep tonight instead!

private tailrec fun findBox(
    size: Int,
    maxSize: Int,
    maxLoc: Point,
    maxPower: Int,
    maxPowerSize: Int,
    grid: List<List<Int>>
): List<Int> {
    if (size > maxSize) {
        return listOf(maxLoc.x, maxLoc.y, maxPowerSize, maxPower)
    }
    println("findBox: $size, $maxSize, $maxLoc, $maxPower, $maxPowerSize")
    val biggest = (1..(301 - size)).map { x ->
        (1..(301 - size)).map { y ->
            Point(x, y) to grid.drop(y - 1).take(size)
                .sumBy { it.drop(x - 1).take(size).sum() }
        }.maxBy {
            it.second
        }!!
    }.maxBy { it.second }!!
    return if (biggest.second > maxPower) {
        findBox(size + 1, maxSize, biggest.first, biggest.second, size, grid)
    } else {
        findBox(size + 1, maxSize, maxLoc, maxPower, maxPowerSize, grid)
    }
}

fun fillGrid(input: Int): List<List<Int>> {
    return (1..300).map { y ->
        (1..300).map { x ->
            powerLevel(input, Point(x, y))
        }
    }
}

private fun answer2(input: Int): List<Int> {
    return findBox(1, 300, Point(-1, -1), -6, -1, fillGrid(input))
}