From 113b355a7de28db8d9d0f6bc3ac9d93ca54af4bd Mon Sep 17 00:00:00 2001 From: Stephan Linkel <251381+norganos@users.noreply.github.com> Date: Wed, 13 Dec 2023 06:55:18 +0100 Subject: [PATCH] day 13 --- src/main/kotlin/de/linkel/aoc/Day13.kt | 82 +++++++++++++++++++++- src/test/kotlin/de/linkel/aoc/Day13Test.kt | 38 ++++++++-- 2 files changed, 115 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/de/linkel/aoc/Day13.kt b/src/main/kotlin/de/linkel/aoc/Day13.kt index b0b6f7d..b4ef8ca 100644 --- a/src/main/kotlin/de/linkel/aoc/Day13.kt +++ b/src/main/kotlin/de/linkel/aoc/Day13.kt @@ -3,12 +3,92 @@ package de.linkel.aoc import de.linkel.aoc.base.AbstractLinesAdventDay import de.linkel.aoc.base.QuizPart import jakarta.inject.Singleton +import kotlin.math.min @Singleton class Day13: AbstractLinesAdventDay() { override val day = 13 override fun process(part: QuizPart, lines: Sequence): Int { - return 0 + return lines.split { it.isEmpty() } + .sumOf { rows -> + val cols = (0 until rows.first().length) + .map { c -> + rows.map { it[c] }.joinToString("") + } + val mirroredRows = findReflection(rows) + val mirroredCols = findReflection(cols) + + val aResult = mirroredCols + mirroredRows * 100 + if (part == QuizPart.A) { + aResult + } else { + val mrows = rows.toMutableList() + val mcols = cols.toMutableList() + coordinates(rows.size, cols.size) + .firstNotNullOf { pos -> + val backup = mrows[pos.first][pos.second] + val char = if (backup == '#') '.' else '#' + mrows[pos.first] = mrows[pos.first].replaceIndex(pos.second, char) + mcols[pos.second] = mcols[pos.second].replaceIndex(pos.first, char) + + val mirroredRows2 = findReflection(mrows, mirroredRows) + val mirroredCols2 = findReflection(mcols, mirroredCols) + val result = mirroredCols2 + mirroredRows2 * 100 + + mrows[pos.first] = mrows[pos.first].replaceIndex(pos.second, backup) + mcols[pos.second] = mcols[pos.second].replaceIndex(pos.first, backup) + + result.takeIf { it != 0 } + } + } + } + } + + private fun findReflection(input: List, except: Int = -1): Int { + return (1 until input.size) + .filter { it != except } + .firstNotNullOfOrNull { divider -> + val size = min(divider, input.size - divider) + val top = input.subList(divider - size, divider) + val bottom = input.subList(divider, divider + size).reversed() + if (top == bottom) + divider + else null + } ?: 0 + } +} + +fun String.replaceIndex(idx: Int, char: Char): String { + return "${this.substring(0, idx)}$char${this.substring(idx+1)}" +} + +fun coordinates(rows: Int, cols: Int): Sequence> { + return sequence { + (0 until rows) + .forEach { r -> + (0 until cols) + .forEach { c -> + yield(r to c) + } + } + } +} + +fun Sequence.split(predicate: (T) -> Boolean): Sequence> { + val input = this + return sequence { + val buffer = mutableListOf() + input.forEach { element -> + if (predicate(element)) { + yield(buffer.toList()) + buffer.clear() + } else { + buffer.add(element) + } + } + if (buffer.isNotEmpty()) { + yield(buffer.toList()) + } } } diff --git a/src/test/kotlin/de/linkel/aoc/Day13Test.kt b/src/test/kotlin/de/linkel/aoc/Day13Test.kt index f3fe09a..00bb426 100644 --- a/src/test/kotlin/de/linkel/aoc/Day13Test.kt +++ b/src/test/kotlin/de/linkel/aoc/Day13Test.kt @@ -2,12 +2,42 @@ package de.linkel.aoc class Day13Test: AbstractDayTest() { override val exampleA = """ +#.##..##. +..#.##.#. +##......# +##......# +..#.##.#. +..##..##. +#.#.##.#. + +#...##..# +#....#..# +..##..### +#####.##. +#####.##. +..##..### +#....#..# """.trimIndent() - override val exampleSolutionA = 0 - override val solutionA = 0 + override val exampleSolutionA = 405 + override val solutionA = 29213 - override val exampleSolutionB = 0 - override val solutionB = 0 + override val exampleSolutionB = 400 + override val solutionB = 37453 override val implementation = Day13() } + +/* + 9 +0 2 4 6 8 + 1 3 5 7 + +#...##..# 0 +#....#..# 1 +..##..### 2 +#####.##. 3 +#####.##. 4 +..##..### 5 +#....#..# 6 + 7 + */