diff --git a/src/aoc2025/Day09.kt b/src/aoc2025/Day09.kt index 4931905..6a9044a 100644 --- a/src/aoc2025/Day09.kt +++ b/src/aoc2025/Day09.kt @@ -3,6 +3,7 @@ package aoc2025 import println import readInput import splitInts +import java.util.* import kotlin.math.abs /* @@ -27,38 +28,35 @@ fun main() { var maxArea = 0L for (i1 in 0 until coords.size step 2) { for (i2 in i1 + 2 until coords.size step 2) { - maxArea = ((abs(coords[i1][0] - coords[i2][0]) + 1).toLong() * (abs(coords[i1][1] - coords[i2][1]) + 1).toLong()).coerceAtLeast(maxArea) + maxArea = + ((abs(coords[i1][0] - coords[i2][0]) + 1).toLong() * (abs(coords[i1][1] - coords[i2][1]) + 1).toLong()).coerceAtLeast( + maxArea + ) } } return maxArea } - fun intersects(coords: List>, x1: Int, y1: Int, x2: Int, y2: Int): Boolean { - for (z1 in 0 until coords.size) { - val z2 = if (z1 != coords.size - 1) z1 + 1 else 0 - if (coords[z1][0] == coords[z2][0]) { - // vertical - val miny = coords[z1][1].coerceAtMost(coords[z2][1]) - val maxy = coords[z1][1].coerceAtLeast(coords[z2][1]) - if (coords[z1][0] > x1 && coords[z1][0] < x2 && - (miny.coerceAtLeast(y1) < maxy.coerceAtMost(y2)) - ) - return true - } else { - // horizontal - val minx = coords[z1][0].coerceAtMost(coords[z2][0]) - val maxx = coords[z1][0].coerceAtLeast(coords[z2][0]) - if (coords[z1][1] > y1 && coords[z1][1] < y2 && - (minx.coerceAtLeast(x1) < maxx.coerceAtMost(x2)) - ) - return true - } - } - return false - } + fun intersectsRanges(set: TreeMap>, x1: Int, y1: Int, x2: Int, y2: Int) = + set.subMap(y1 + 1, y2).values.any { it.any { it.first < x2 && it.last > x1 } } fun part2(input: List): Long { val coords = input.map { it.splitInts(",") } + val xSpans = TreeMap>() + val ySpans = TreeMap>() + for (i1 in 0 until coords.size) { + val i2 = if (i1 != coords.size - 1) i1 + 1 else 0 + if (coords[i1][1] == coords[i2][1]) { + xSpans.getOrPut(coords[i1][1]) { ArrayList() }.add( + IntRange(coords[i1][0].coerceAtMost(coords[i2][0]), coords[i1][0].coerceAtLeast(coords[i2][0])) + ) + } else { + ySpans.getOrPut(coords[i1][0]) { ArrayList() }.add( + IntRange(coords[i1][1].coerceAtMost(coords[i2][1]), coords[i1][1].coerceAtLeast(coords[i2][1])) + ) + } + } + var maxArea = 0L for (i1 in 0 until coords.size step 2) { for (i2 in i1 + 2 until coords.size step 2) { @@ -68,9 +66,10 @@ fun main() { val y2 = coords[i1][1].coerceAtLeast(coords[i2][1]) val area = ((x2 - x1 + 1).toLong() * (y2 - y1 + 1).toLong()) - if (area > maxArea) { - if (!intersects(coords, x1, y1, x2, y2)) - maxArea = area + if (area > maxArea && + !(intersectsRanges(xSpans, x1, y1, x2, y2) || intersectsRanges(ySpans, y1, x1, y2, x2)) + ) { + maxArea = area } } }