Skip to content

Commit 15cf6e7

Browse files
committed
adventofcode 2025 Day 9
GitOrigin-RevId: 11c34a287af6c42cde0986e863d639deaa5c9754
1 parent ac1b755 commit 15cf6e7

File tree

4 files changed

+140
-1
lines changed
  • advent-of-code/src

4 files changed

+140
-1
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
package com.willmolloy.adventofcode._2025
2+
3+
import com.willmolloy.adventofcode.common.Day
4+
import com.willmolloy.adventofcode.common.Input
5+
import com.willmolloy.adventofcode.common.extensions.debug
6+
import com.willmolloy.adventofcode.common.extensions.size
7+
import com.willmolloy.adventofcode.common.grid.Point
8+
import kotlin.collections.lastIndex
9+
import kotlin.math.abs
10+
import kotlin.math.max
11+
import kotlin.math.min
12+
13+
/** https://adventofcode.com/2025/day/9 */
14+
object Day9 : Day(2025, 9) {
15+
16+
override fun part1(input: Input): Any {
17+
val redTiles = getRedTiles(input)
18+
19+
var max = 0L
20+
21+
for ((i, p1) in redTiles.withIndex()) {
22+
for (p2 in redTiles.drop(i + 1)) {
23+
val area = (abs(p2.y - p1.y) + 1) * (abs(p2.x - p1.x) + 1)
24+
max = max(max, area)
25+
}
26+
}
27+
28+
return max
29+
}
30+
31+
private fun getRedTiles(input: Input): List<Point> =
32+
input.readLines().map {
33+
val split = it.split(",")
34+
Point(split[0], split[1])
35+
}
36+
37+
private fun getLoopOfGreenTiles(redTiles: List<Point>): List<Point> {
38+
val greenTiles = mutableListOf<Point>()
39+
40+
for (i in 0 until redTiles.size) {
41+
val point = redTiles[i]
42+
val adjPoint = if (i < redTiles.lastIndex) redTiles[i + 1] else redTiles[0]
43+
// "Tiles that are adjacent will always be on either the same row or the same column."
44+
if (point.x == adjPoint.x) {
45+
// same col
46+
for (y in min(point.y, adjPoint.y)..max(point.y, adjPoint.y)) {
47+
greenTiles.add(Point(point.x, y))
48+
}
49+
} else {
50+
// same row
51+
for (x in min(point.x, adjPoint.x)..max(point.x, adjPoint.x)) {
52+
greenTiles.add(Point(x, point.y))
53+
}
54+
}
55+
}
56+
57+
return greenTiles
58+
}
59+
60+
override fun part2(input: Input): Any {
61+
val redTiles = getRedTiles(input)
62+
val greenTiles = getLoopOfGreenTiles(redTiles)
63+
val redGreenTiles = redTiles.union(greenTiles)
64+
65+
// "In addition, all the tiles inside this loop of red and green tiles are also green."
66+
val rowStart = redGreenTiles.minOf { it.y }
67+
val rowEnd = redGreenTiles.maxOf { it.y }
68+
println("ROWS = $rowStart..$rowEnd")
69+
70+
// ROW -> COL RANGE
71+
val tiledRanges = mutableMapOf<Long, LongRange>()
72+
73+
for (row in rowStart..rowEnd) {
74+
val tilesInRow = redGreenTiles.filter { it.y == row }
75+
if (tilesInRow.isEmpty()) {
76+
continue
77+
}
78+
79+
val colStart = tilesInRow.minOf { it.x }
80+
val colEnd = tilesInRow.maxOf { it.x }
81+
82+
tiledRanges[row] = colStart..colEnd
83+
}
84+
85+
tiledRanges.debug()
86+
87+
fun area(p1: Point, p2: Point): Long {
88+
// no need to filter for topLeft/bottomRight points because all the points in the rectangle
89+
// are checked that they're tiled - so just force topLeft/bottomRight:
90+
val cols = min(p1.x, p2.x)..max(p1.x, p2.x)
91+
val rows = min(p1.y, p2.y)..max(p1.y, p2.y)
92+
93+
for (row in rows) {
94+
val tiledRange = tiledRanges[row] ?: return 0L
95+
if (tiledRange.start > cols.start) {
96+
return 0L
97+
}
98+
if (tiledRange.endInclusive < cols.endInclusive) {
99+
return 0L
100+
}
101+
}
102+
103+
return cols.size * rows.size
104+
}
105+
106+
// "The rectangle you choose still must have red tiles in opposite corners"
107+
var max = 0L
108+
109+
for ((i, p1) in redTiles.withIndex()) {
110+
for (p2 in redTiles.drop(i + 1)) {
111+
val area = area(p1, p2)
112+
if (area > max) {
113+
max = area
114+
println("NEW MAX: $p1 and $p2 = $area")
115+
}
116+
}
117+
}
118+
119+
return max
120+
}
121+
}

advent-of-code/src/main/kotlin/com/willmolloy/adventofcode/common/datastructures/DisjointSet.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package com.willmolloy.adventofcode.common.datastructures
55
*
66
* @author <a href=https://willmolloy.com>Will Molloy</a>
77
*/
8-
class DisjointSet(private val parent: IntArray, private val size: IntArray) {
8+
class DisjointSet private constructor(private val parent: IntArray, private val size: IntArray) {
99

1010
constructor(numNodes: Int) : this(IntArray(numNodes) { it }, IntArray(numNodes) { 1 })
1111

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
7,1
2+
11,1
3+
11,7
4+
9,7
5+
9,5
6+
2,5
7+
2,3
8+
7,3
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.willmolloy.adventofcode._2025
2+
3+
import com.willmolloy.adventofcode.common.DayTest
4+
5+
object Day9Test : DayTest(Day9) {
6+
7+
override fun part1() = Answer(50, 4774877510)
8+
9+
override fun part2() = Answer(24, 1560475800)
10+
}

0 commit comments

Comments
 (0)