diff --git a/src/main/kotlin/de/linkel/aoc/Day05.kt b/src/main/kotlin/de/linkel/aoc/Day05.kt index a67b3e6..457ca81 100644 --- a/src/main/kotlin/de/linkel/aoc/Day05.kt +++ b/src/main/kotlin/de/linkel/aoc/Day05.kt @@ -5,10 +5,76 @@ import de.linkel.aoc.base.QuizPart import jakarta.inject.Singleton @Singleton -class Day05: AbstractLinesAdventDay() { +class Day05: AbstractLinesAdventDay() { override val day = 5 + private val spaces = Regex("\\s+") - override fun process(part: QuizPart, lines: Sequence): Int { - return 0 + override fun process(part: QuizPart, lines: Sequence): Long { + val iterator = lines.iterator() + val seedsLineValues = iterator.next().substringAfter(":").split(spaces).filter { it.isNotEmpty() }.map { it.toLong() } + val seeds = if (part == QuizPart.A) seedsLineValues.map { LongRange(it, it) } + else seedsLineValues.windowed(2, step = 2).map { LongRange(it[0], it[0] + it[1] - 1) } + iterator.next() + assert(iterator.next().trim() == "seed-to-soil map:") + val seedToSoil = consumeUntilDelimiter(iterator, "soil-to-fertilizer map:") + val soilToFertilizer = consumeUntilDelimiter(iterator, "fertilizer-to-water map:") + val fertilizerToWater = consumeUntilDelimiter(iterator, "water-to-light map:") + val waterToLight = consumeUntilDelimiter(iterator, "light-to-temperature map:") + val lightToTemperature = consumeUntilDelimiter(iterator, "temperature-to-humidity map:") + val temperatureToHumidity = consumeUntilDelimiter(iterator, "humidity-to-location map:") + val humidityToLocation = consumeUntilDelimiter(iterator, "EOF") + + return seeds.minOf { seedRange -> + seedRange.minOf { seed -> + humidityToLocation.lookup( + temperatureToHumidity.lookup( + lightToTemperature.lookup( + waterToLight.lookup( + fertilizerToWater.lookup( + soilToFertilizer.lookup( + seedToSoil.lookup(seed) + ) + ) + ) + ) + ) + ) + } + } + } + + private fun consumeUntilDelimiter(iterator: Iterator, delimiter: String): Translation { + val result = mutableListOf() + while (iterator.hasNext()) { + val line = iterator.next().trim() + if (line.isEmpty()) continue + if (line == delimiter) break + val vals = line.split(spaces).map { it.trim().toLong() } + result.add( + Mapping( + destRange = LongRange(vals[0], vals[0] + vals[2] - 1), + sourceRange = LongRange(vals[1], vals[1] + vals[2] - 1) + ) + ) + } + return Translation(result) } + + data class Translation( + val mappings: List + ) { + fun lookup(input: Long): Long { + for (mapping in mappings) { + if (input in mapping.sourceRange) { + return mapping.destRange.first + (input - mapping.sourceRange.first) + } + } + return input + } + } + + data class Mapping( + val sourceRange: LongRange, + val destRange: LongRange + ) } diff --git a/src/main/kotlin/de/linkel/aoc/Day06.kt b/src/main/kotlin/de/linkel/aoc/Day06.kt new file mode 100644 index 0000000..3db745b --- /dev/null +++ b/src/main/kotlin/de/linkel/aoc/Day06.kt @@ -0,0 +1,14 @@ +package de.linkel.aoc + +import de.linkel.aoc.base.AbstractLinesAdventDay +import de.linkel.aoc.base.QuizPart +import jakarta.inject.Singleton + +@Singleton +class Day06: AbstractLinesAdventDay() { + override val day = 5 + + override fun process(part: QuizPart, lines: Sequence): Int { + return 0 + } +} diff --git a/src/test/kotlin/de/linkel/aoc/Day05Test.kt b/src/test/kotlin/de/linkel/aoc/Day05Test.kt index 78a0772..6af001f 100644 --- a/src/test/kotlin/de/linkel/aoc/Day05Test.kt +++ b/src/test/kotlin/de/linkel/aoc/Day05Test.kt @@ -1,13 +1,46 @@ package de.linkel.aoc -class Day05Test: AbstractDayTest() { +class Day05Test: AbstractDayTest() { override val exampleA = """ +seeds: 79 14 55 13 + +seed-to-soil map: +50 98 2 +52 50 48 + +soil-to-fertilizer map: +0 15 37 +37 52 2 +39 0 15 + +fertilizer-to-water map: +49 53 8 +0 11 42 +42 0 7 +57 7 4 + +water-to-light map: +88 18 7 +18 25 70 + +light-to-temperature map: +45 77 23 +81 45 19 +68 64 13 + +temperature-to-humidity map: +0 69 1 +1 0 69 + +humidity-to-location map: +60 56 37 +56 93 4 """.trimIndent() - override val exampleSolutionA = 0 - override val solutionA = 0 + override val exampleSolutionA = 35L + override val solutionA = 107430936L - override val exampleSolutionB = 0 - override val solutionB = 0 + override val exampleSolutionB = 46L + override val solutionB = 0L override val implementation = Day05() } diff --git a/src/test/kotlin/de/linkel/aoc/Day06Test.kt b/src/test/kotlin/de/linkel/aoc/Day06Test.kt new file mode 100644 index 0000000..b27ae24 --- /dev/null +++ b/src/test/kotlin/de/linkel/aoc/Day06Test.kt @@ -0,0 +1,13 @@ +package de.linkel.aoc + +class Day06Test: AbstractDayTest() { + override val exampleA = """ + """.trimIndent() + override val exampleSolutionA = 0 + override val solutionA = 0 + + override val exampleSolutionB = 0 + override val solutionB = 0 + + override val implementation = Day06() +}