Skip to content

Commit 4309926

Browse files
authored
Day 09 2025 (#303)
* Day 09 2025 * Sorting by size and finding the first that fits
1 parent a56395f commit 4309926

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package me.peckb.aoc._2025.calendar.day09
2+
3+
import me.peckb.aoc.generators.InputGenerator.InputGeneratorFactory
4+
import org.apache.commons.math3.geometry.euclidean.twod.PolygonsSet
5+
import org.apache.commons.math3.geometry.euclidean.twod.Vector2D
6+
import org.apache.commons.math3.geometry.euclidean.twod.hull.ConvexHullGenerator2D
7+
import org.apache.commons.math3.geometry.euclidean.twod.hull.MonotoneChain
8+
import javax.inject.Inject
9+
import kotlin.math.abs
10+
import kotlin.math.max
11+
12+
13+
class Day09 @Inject constructor(
14+
private val generatorFactory: InputGeneratorFactory,
15+
) {
16+
fun partOne(filename: String) = generatorFactory.forFile(filename).readAs(::day09) { redTileLocations ->
17+
val tiles = redTileLocations.toList()
18+
19+
var largestArea = -1.0
20+
21+
tiles.indices.forEach { ti1 ->
22+
((ti1 + 1) until tiles.size).forEach { ti2 ->
23+
val t1 = tiles[ti1]
24+
val t2 = tiles[ti2]
25+
26+
val area = (abs(t1.x - t2.x) + 1) * (abs(t1.y - t2.y) + 1)
27+
28+
largestArea = max(largestArea, area)
29+
}
30+
}
31+
32+
largestArea.toLong()
33+
}
34+
35+
fun partTwo(filename: String) = generatorFactory.forFile(filename).readAs(::day09) { input ->
36+
val vertices = input.map { Vector2D(it.x, it.y) }.toList()
37+
val polygonSet = PolygonsSet(1e-3, *vertices.toTypedArray())
38+
val hullGenerator: ConvexHullGenerator2D = MonotoneChain()
39+
40+
val areas = mutableListOf<Pair<Long, List<Vector2D>>>()
41+
42+
vertices.indices.forEach { ti1 ->
43+
((ti1 + 1) until vertices.size).forEach { ti2 ->
44+
val t1 = vertices[ti1]
45+
val t2 = vertices[ti2]
46+
47+
if (t1.x == t2.x || t1.y == t2.y) { return@forEach }
48+
49+
val size = ((abs(t1.x - t2.x) + 1) * (abs(t1.y - t2.y) + 1)).toLong()
50+
val i1 = Vector2D(t1.x, t2.y)
51+
val i2 = Vector2D(t2.x, t1.y)
52+
53+
areas.add(size to listOf(t1, i1, t2, i2))
54+
}
55+
}
56+
57+
areas.sortedByDescending { it.first }.first { (_, vertices) ->
58+
polygonSet.contains(hullGenerator.generate(vertices).createRegion())
59+
}.first
60+
}
61+
62+
private fun day09(line: String) = line.split(",").map { it.toDouble() }.let { (x, y) -> Location(x, y) }
63+
}
64+
65+
data class Location(val x: Double, val y: Double)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## [Day 9: Movie Theater](https://adventofcode.com/2025/day/9)

src/test/kotlin/me/peckb/aoc/_2025/TestDayComponent.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import me.peckb.aoc._2025.calendar.day05.Day05Test
88
import me.peckb.aoc._2025.calendar.day06.Day06Test
99
import me.peckb.aoc._2025.calendar.day07.Day07Test
1010
import me.peckb.aoc._2025.calendar.day08.Day08Test
11+
import me.peckb.aoc._2025.calendar.day09.Day09Test
1112
import javax.inject.Singleton
1213
import me.peckb.aoc.DayComponent
1314
import me.peckb.aoc.InputModule
@@ -24,4 +25,5 @@ internal interface TestDayComponent : DayComponent {
2425
fun inject(day06Test: Day06Test)
2526
fun inject(day07Test: Day07Test)
2627
fun inject(day08Test: Day08Test)
28+
fun inject(day09Test: Day09Test)
2729
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package me.peckb.aoc._2025.calendar.day09
2+
3+
import javax.inject.Inject
4+
5+
import me.peckb.aoc._2025.DaggerTestDayComponent
6+
import org.junit.jupiter.api.Assertions.assertEquals
7+
import org.junit.jupiter.api.BeforeEach
8+
import org.junit.jupiter.api.Test
9+
10+
internal class Day09Test {
11+
@Inject
12+
lateinit var day09: Day09
13+
14+
@BeforeEach
15+
fun setup() {
16+
DaggerTestDayComponent.create().inject(this)
17+
}
18+
19+
@Test
20+
fun testDay09PartOne() {
21+
assertEquals(4749929916, day09.partOne(DAY_09))
22+
}
23+
24+
@Test
25+
fun testDay09PartTwo() {
26+
assertEquals(1572047142, day09.partTwo(DAY_09))
27+
}
28+
29+
companion object {
30+
private const val DAY_09: String = "advent-of-code-input/2025/day09.input"
31+
}
32+
}

0 commit comments

Comments
 (0)