Skip to content

Commit d5467a1

Browse files
authored
Day 04 2025 (#298)
* Day 04 2025 ... messy * split out input parsing * more cleanup
1 parent 27a91d6 commit d5467a1

File tree

4 files changed

+109
-0
lines changed

4 files changed

+109
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package me.peckb.aoc._2025.calendar.day04
2+
3+
import javax.inject.Inject
4+
import me.peckb.aoc.generators.InputGenerator.InputGeneratorFactory
5+
import kotlin.text.forEach
6+
7+
class Day04 @Inject constructor(
8+
private val generatorFactory: InputGeneratorFactory,
9+
) {
10+
fun partOne(filename: String) = generatorFactory.forFile(filename).read { input ->
11+
val printingDepartment = mapPaper(input)
12+
13+
var removable = 0
14+
15+
printingDepartment.indices.forEach { r ->
16+
printingDepartment[r].indices.forEach { c ->
17+
if (printingDepartment[r][c] == '@' && printingDepartment.paperNeighbors(r, c) < 4) { removable++ }
18+
}
19+
}
20+
21+
removable
22+
}
23+
24+
fun partTwo(filename: String) = generatorFactory.forFile(filename).read { input ->
25+
val printingDepartment = mapPaper(input)
26+
27+
var totalRemovedCount = 0
28+
29+
do {
30+
val toRemove = mutableListOf<Pair<Int, Int>>()
31+
32+
printingDepartment.indices.forEach { r ->
33+
printingDepartment[r].indices.forEach { c ->
34+
if (printingDepartment[r][c] == '@' && printingDepartment.paperNeighbors(r, c) < 4) { toRemove.add(r to c) }
35+
}
36+
}
37+
38+
toRemove.forEach { (r, c) -> printingDepartment[r][c] = '.' }
39+
totalRemovedCount += toRemove.size
40+
} while (toRemove.isNotEmpty())
41+
42+
totalRemovedCount
43+
}
44+
45+
private fun mapPaper(input: Sequence<String>): MutableList<MutableList<Char>> {
46+
val workshop = mutableListOf<MutableList<Char>>()
47+
48+
input.forEach { r ->
49+
val row = mutableListOf<Char>()
50+
r.forEach { c -> row.add(c) }
51+
workshop.add(row)
52+
}
53+
54+
return workshop
55+
}
56+
57+
private fun MutableList<MutableList<Char>>.paperNeighbors(r: Int, c: Int): Int {
58+
return (-1 .. 1).sumOf { rDelta ->
59+
// ensure row bounds
60+
val rIndex = rDelta + r
61+
if (rIndex !in 0 until size) return@sumOf 0
62+
63+
(-1 .. 1).count { cDelta ->
64+
// don't count ourselves
65+
if (rDelta == 0 && cDelta == 0) return@count false
66+
// ensure column bounds
67+
val cIndex = cDelta + c
68+
if (cIndex !in 0 until this[rIndex].size) return@count false
69+
70+
this[rIndex][cIndex] == '@'
71+
}
72+
}
73+
}
74+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## [Day 4: Printing Department](https://adventofcode.com/2025/day/4)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package me.peckb.aoc._2025
33
import dagger.Component
44
import me.peckb.aoc._2025.calendar.day02.Day02Test
55
import me.peckb.aoc._2025.calendar.day03.Day03Test
6+
import me.peckb.aoc._2025.calendar.day04.Day04Test
67
import javax.inject.Singleton
78
import me.peckb.aoc.DayComponent
89
import me.peckb.aoc.InputModule
@@ -14,4 +15,5 @@ internal interface TestDayComponent : DayComponent {
1415
fun inject(day01Test: Day01Test)
1516
fun inject(day02Test: Day02Test)
1617
fun inject(day03Test: Day03Test)
18+
fun inject(day04Test: Day04Test)
1719
}
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.day04
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 Day04Test {
11+
@Inject
12+
lateinit var day04: Day04
13+
14+
@BeforeEach
15+
fun setup() {
16+
DaggerTestDayComponent.create().inject(this)
17+
}
18+
19+
@Test
20+
fun testDay04PartOne() {
21+
assertEquals(1508, day04.partOne(DAY_04))
22+
}
23+
24+
@Test
25+
fun testDay04PartTwo() {
26+
assertEquals(8538, day04.partTwo(DAY_04))
27+
}
28+
29+
companion object {
30+
private const val DAY_04: String = "advent-of-code-input/2025/day04.input"
31+
}
32+
}

0 commit comments

Comments
 (0)