From 732c69df0efbc92aa615fdec0769700f1e312bac Mon Sep 17 00:00:00 2001 From: chrisly42 Date: Thu, 4 Dec 2025 06:41:19 +0100 Subject: [PATCH] Day 4. --- src/Utils.kt | 5 +++- src/aoc2025/Day04.kt | 56 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/aoc2025/Day04.kt diff --git a/src/Utils.kt b/src/Utils.kt index cf0cafd..1e9f30f 100644 --- a/src/Utils.kt +++ b/src/Utils.kt @@ -152,6 +152,9 @@ class CharGrid { fun applyWithPos(op: (grid: CharGrid, pos: RelPos) -> Char?) = generateGridPos().forEach { this[it] = op(this, it) } + fun applyWithPos(relposes: Iterable, op: (grid: CharGrid, pos: RelPos) -> Char?) = + relposes.forEach { this[it] = op(this, it) } + fun apply(op: (content: Char) -> Char?) = applyWithPos { grid: CharGrid, pos -> op(grid[pos]) } @@ -201,7 +204,7 @@ class CharGrid { fun matchRelative(c: Int, r: Int, relposes: Iterable, predicate: (char: Char) -> Boolean): List = relposes.filter { predicate(get(c + it.dc, r + it.dr)) } - fun matchRelativeRelPos(pos: RelPos, relposes: Iterable, predicate: (char: Char) -> Boolean): List = + fun matchRelative(pos: RelPos, relposes: Iterable, predicate: (char: Char) -> Boolean): List = relposes.filter { predicate(get(pos.translate(it))) } fun matchAbsoluteRelPos(pos: RelPos, relposes: Iterable, predicate: (char: Char) -> Boolean): List = diff --git a/src/aoc2025/Day04.kt b/src/aoc2025/Day04.kt new file mode 100644 index 0000000..40084b1 --- /dev/null +++ b/src/aoc2025/Day04.kt @@ -0,0 +1,56 @@ +package aoc2025 + +import CharGrid +import println +import readInput + +/* +--- Day 4: Printing Department --- +https://adventofcode.com/2025/day/4 +*/ +fun main() { + + val inlineTestInput = """ +..@@.@@@@. +@@@.@.@.@@ +@@@@@.@.@@ +@.@@@@..@. +@@.@@@@.@@ +.@@@@@@@.@ +.@.@.@.@@@ +@.@@@.@@@@ +.@@@@@@@@. +@.@.@@@.@. +""" + + fun part1(input: List): Int { + val grid = CharGrid(input) + val matches = grid.findMatchesRelPos { it == '@' }.filter { grid.matchRelative(it, CharGrid.BOX_POS) { it == '@' }.size < 4 } + return matches.count() + } + + fun part2(input: List): Int { + val grid = CharGrid(input) + var removed = 0 + do { + val matches = grid.findMatchesRelPos { it == '@' }.filter { grid.matchRelative(it, CharGrid.BOX_POS) { it == '@' }.size < 4 } + grid.applyWithPos(matches) { _, _ -> 'x' } + removed += matches.size + } while (matches.isNotEmpty()) + return removed + } + + // test if implementation meets criteria from the description, like: + val testInput = inlineTestInput.trim().reader().readLines() + //val testInput = readInput("aoc2025/Day04_test") + val testInputPart1Result = part1(testInput) + println("Part 1 Test: $testInputPart1Result") + val testInputPart2Result = part2(testInput) + println("Part 2 Test: $testInputPart2Result") + check(testInputPart1Result == 13) + check(testInputPart2Result == 43) + + val input = readInput("aoc2025/Day04") + part1(input).println() + part2(input).println() +}