@@ -2,8 +2,6 @@ package me.peckb.aoc._2025.calendar.day04
22
33import javax.inject.Inject
44import me.peckb.aoc.generators.InputGenerator.InputGeneratorFactory
5- import kotlin.math.max
6- import kotlin.math.min
75import kotlin.text.forEach
86
97class Day04 @Inject constructor(
@@ -12,70 +10,36 @@ class Day04 @Inject constructor(
1210 fun partOne (filename : String ) = generatorFactory.forFile(filename).read { input ->
1311 val printingDepartment = mapPaper(input)
1412
15- var superCount = 0
13+ var removable = 0
14+
1615 printingDepartment.indices.forEach { r ->
17- val row = printingDepartment[r]
18-
19- row.indices.forEach { c ->
20- var count = 0
21-
22- if (printingDepartment[r][c] == ' @' ) {
23- for (rIndex in (max(0 , r - 1 ).. min(row.size - 1 , r + 1 ))) {
24- for (cIndex in (max(0 , c - 1 ).. min(printingDepartment.size - 1 , c + 1 ))) {
25- if (printingDepartment[rIndex][cIndex] == ' @' && ! (rIndex == r && cIndex == c)) {
26- count++
27- }
28- }
29- }
30-
31- if (count < 4 ) {
32- superCount++
33- }
34- }
16+ printingDepartment[r].indices.forEach { c ->
17+ if (printingDepartment[r][c] == ' @' && printingDepartment.paperNeighbors(r, c) < 4 ) { removable++ }
3518 }
3619 }
3720
38- superCount
21+ removable
3922 }
4023
4124 fun partTwo (filename : String ) = generatorFactory.forFile(filename).read { input ->
4225 val printingDepartment = mapPaper(input)
4326
44- var superDuperCount = 0
45- var someWereRemoved = true
46- while (someWereRemoved) {
47- var superCount = 0
27+ var totalRemovedCount = 0
28+
29+ do {
4830 val toRemove = mutableListOf<Pair <Int , Int >>()
31+
4932 printingDepartment.indices.forEach { r ->
50- val row = printingDepartment[r]
51-
52-
53- row.indices.forEach { c ->
54- var count = 0
55-
56- if (printingDepartment[r][c] == ' @' ) {
57- for (rIndex in (max(0 , r - 1 ).. min(row.size - 1 , r + 1 ))) {
58- for (cIndex in (max(0 , c - 1 ).. min(printingDepartment.size - 1 , c + 1 ))) {
59- if (printingDepartment[rIndex][cIndex] == ' @' && ! (rIndex == r && cIndex == c)) {
60- count++
61- }
62- }
63- }
64-
65- if (count < 4 ) {
66- toRemove.add(r to c)
67- superCount++
68- }
69- }
33+ printingDepartment[r].indices.forEach { c ->
34+ if (printingDepartment[r][c] == ' @' && printingDepartment.paperNeighbors(r, c) < 4 ) { toRemove.add(r to c) }
7035 }
7136 }
7237
7338 toRemove.forEach { (r, c) -> printingDepartment[r][c] = ' .' }
74- someWereRemoved = superCount != 0
75- superDuperCount + = superCount
76- }
39+ totalRemovedCount + = toRemove.size
40+ } while (toRemove.isNotEmpty())
7741
78- superDuperCount
42+ totalRemovedCount
7943 }
8044
8145 private fun mapPaper (input : Sequence <String >): MutableList <MutableList <Char >> {
@@ -89,4 +53,22 @@ class Day04 @Inject constructor(
8953
9054 return workshop
9155 }
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+ }
9274}
0 commit comments