Skip to content

Commit 919e166

Browse files
committed
2025, Day 5
1 parent deb3e11 commit 919e166

File tree

6 files changed

+154
-0
lines changed

6 files changed

+154
-0
lines changed

.idea/runConfigurations/2025__Day_5.xml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package lv.esupe.aoc.utils
2+
3+
infix fun IntRange.overlaps(other: IntRange): Boolean {
4+
return this.first <= other.last && other.first <= this.last
5+
}
6+
7+
infix fun LongRange.overlaps(other: LongRange): Boolean {
8+
return this.first <= other.last && other.first <= this.last
9+
}
10+
11+
fun IntRange.mergeWith(other: IntRange): IntRange {
12+
if (!(this overlaps other)) {
13+
throw IllegalArgumentException("Ranges must overlap to be merged")
14+
}
15+
16+
return minOf(this.first, other.first)..maxOf(this.last, other.last)
17+
}
18+
19+
fun LongRange.mergeWith(other: LongRange): LongRange {
20+
if (!(this overlaps other)) {
21+
throw IllegalArgumentException("Ranges must overlap to be merged")
22+
}
23+
24+
return minOf(this.first, other.first)..maxOf(this.last, other.last)
25+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package lv.esupe.aoc.year2025
2+
3+
import lv.esupe.aoc.Puzzle
4+
import lv.esupe.aoc.solve
5+
import lv.esupe.aoc.utils.chunkedBy
6+
import lv.esupe.aoc.utils.mergeWith
7+
import lv.esupe.aoc.utils.overlaps
8+
9+
fun main() = solve { Day5() }
10+
11+
class Day5 : Puzzle<Int, Long>(2025, 5) {
12+
override val input = rawInput
13+
14+
private val ranges: List<LongRange>
15+
private val ids: List<Long>
16+
17+
init {
18+
val (ranges, ids) = input.chunkedBy { it.isBlank() }
19+
this.ranges = ranges
20+
.map { line ->
21+
val (a, b) = line.split("-")
22+
.map { it.toLong() }
23+
a..b
24+
}
25+
.sortedBy { it.first }
26+
this.ids = ids.map { it.toLong() }
27+
}
28+
29+
override fun solvePartOne(): Int {
30+
return ids.count { id -> ranges.any { range -> id in range } }
31+
}
32+
33+
override fun solvePartTwo(): Long {
34+
val queue = ranges.toMutableList()
35+
val condensed = mutableListOf<LongRange>()
36+
while (queue.isNotEmpty()) {
37+
val rangeA = queue.removeAt(0)
38+
val rangeB = queue.firstOrNull { rangeB -> rangeA overlaps rangeB }
39+
if (rangeB != null) {
40+
queue.remove(rangeB)
41+
queue.add(rangeA.mergeWith(rangeB))
42+
} else {
43+
condensed.add(rangeA)
44+
}
45+
}
46+
return condensed.sumOf { range -> range.last - range.first + 1 }
47+
}
48+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package lv.esupe.aoc.utils
2+
3+
import org.junit.jupiter.api.Assertions.assertEquals
4+
import org.junit.jupiter.api.Assertions.assertFalse
5+
import org.junit.jupiter.api.Assertions.assertTrue
6+
import org.junit.jupiter.api.Nested
7+
import org.junit.jupiter.api.Test
8+
9+
class RangeTest {
10+
11+
@Nested
12+
inner class Overlaps {
13+
14+
@Test
15+
fun `overlaps functions correctly`() {
16+
assertTrue(1..10 overlaps 5..15)
17+
assertTrue(1..10 overlaps 5..10)
18+
assertTrue(1..10 overlaps 10..20)
19+
assertTrue(1..10 overlaps 1..10)
20+
assertTrue(1..10 overlaps (1 until 10))
21+
assertTrue(1..10 overlaps (2 until 10))
22+
assertTrue(1..10 overlaps -10..1)
23+
assertTrue(1..10 overlaps -10..5)
24+
25+
assertFalse(1..10 overlaps -10..0)
26+
assertFalse(1..10 overlaps (-10 until 1))
27+
assertFalse(1..10 overlaps 11..20)
28+
}
29+
}
30+
31+
@Nested
32+
inner class MergeWith {
33+
34+
@Test
35+
fun `mergeWith functions correctly`() {
36+
assertEquals(1..10, (1..5).mergeWith(5..10))
37+
assertEquals(1..10, (1..10).mergeWith(2..5))
38+
assertEquals(1..10, (1..7).mergeWith(4..10))
39+
assertEquals(1..10, (9..10).mergeWith(1..9))
40+
}
41+
}
42+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package lv.esupe.aoc.year2025
2+
3+
import lv.esupe.aoc.DayTest
4+
import org.junit.jupiter.api.Test
5+
6+
class Day5Test : DayTest<Int, Long>() {
7+
override val puzzle = { Day5() }
8+
9+
@Test
10+
fun day5_1() {
11+
runTest("_1", 3, 14)
12+
}
13+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
3-5
2+
10-14
3+
16-20
4+
12-18
5+
6+
1
7+
5
8+
8
9+
11
10+
17
11+
32

0 commit comments

Comments
 (0)