Dnes už to bylo více tricky a musel jsem sáhnout po své Rojo knihovně, ale zvládlo se to 🙂 .

Část A i B:

@Regex("#(\\d+) @ (\\d+),(\\d+): (\\d+)x(\\d+)")
class Claim {
    @Group(1)
    var id: Int = 0

    @Group(2)
    var x: Int = 0

    @Group(3)
    var y: Int = 0

    @Group(4)
    var width: Int = 0

    @Group(5)
    var height: Int = 0
}

fun main() {
    val input = File("input3.txt").readText()
    val claims = Rojo.of(Claim::class.java).matchList(input)

    val maxWidth = claims.map { it.x + it.width }.max() ?: 0
    val maxHeight = claims.map { it.y + it.height }.max() ?: 0

    val area = Array(maxWidth) { IntArray(maxHeight) { 0 } }

    claims.forEach { area.cutOut(it) }

    val total = area.sumBy { it.count { it == 2 } }
    println(total)

    val nonOverlapping = claims.find { claim ->
        claim.run {
            (x until x + width).all { posX ->
                (y until y + height).all { posY ->
                    area.get(posX)[posY] == 1
                }
            }
        }
    }

    println(nonOverlapping?.id)
}

private fun Array<IntArray>.cutOut(claim: Claim) {
    claim.run {
        for (posX in x until x + width) {
            for (posY in y until y + height) {
                val row = get(posX)
                when (row[posY]) {
                    0 -> row[posY] = 1
                    1 -> row[posY] = 2
                }
            }
        }
    }
}