diff --git a/README.md b/README.md index b427b06..c596fd9 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,4 @@ Development occurs in language-specific directories: |[Day7.hs](hs/src/Day7.hs)|[Day7.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt)|[day7.py](py/aoc2024/day7.py)|[day7.rs](rs/src/day7.rs)| |[Day8.hs](hs/src/Day8.hs)|[Day8.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day8.kt)|[day8.py](py/aoc2024/day8.py)|[day8.rs](rs/src/day8.rs)| |[Day9.hs](hs/src/Day9.hs)|[Day9.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day9.kt)|[day9.py](py/aoc2024/day9.py)|[day9.rs](rs/src/day9.rs)| -|[Day10.hs](hs/src/Day10.hs)|||| +|[Day10.hs](hs/src/Day10.hs)|[Day10.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day10.kt)||| diff --git a/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day10Bench.kt b/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day10Bench.kt new file mode 100644 index 0000000..6a1641d --- /dev/null +++ b/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day10Bench.kt @@ -0,0 +1,31 @@ +package com.github.ephemient.aoc2024.exe + +import com.github.ephemient.aoc2024.Day10 +import kotlinx.benchmark.Benchmark +import kotlinx.benchmark.Blackhole +import kotlinx.benchmark.Scope +import kotlinx.benchmark.Setup +import kotlinx.benchmark.State + +@State(Scope.Benchmark) +class Day10Bench { + private lateinit var input: String + + @Setup + fun setup() { + input = getDayInput(10) + } + + @Benchmark + fun part1() = Day10(input).part1() + + @Benchmark + fun part2() = Day10(input).part2() + + @Benchmark + fun solve(bh: Blackhole) { + val day10 = Day10(input) + bh.consume(day10.part1()) + bh.consume(day10.part2()) + } +} diff --git a/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day10.kt b/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day10.kt new file mode 100644 index 0000000..0e871e7 --- /dev/null +++ b/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day10.kt @@ -0,0 +1,41 @@ +package com.github.ephemient.aoc2024 + +class Day10(input: String) { + private val levels: List> + init { + val levels = List(10) { mutableSetOf() } + for ((y, line) in input.lineSequence().withIndex()) { + for ((x, char) in line.withIndex()) { + if (char.isDigit()) levels[char.digitToInt()].add(y to x) + } + } + this.levels = levels + } + + private inline fun bfs(start: (IntPair) -> T, plus: (T, T) -> T): Map = + levels.subList(1, 10).fold(levels[0].associateWith(start)) { acc, points -> + buildMap { + for ((key, value) in acc) { + for (point in key.adj) { + if (point in points) { + put(point, if (contains(point)) plus(value, getValue(point)) else value) + } + } + } + } + } + + fun part1() = bfs(::setOf, Set::plus).values.sumOf { it.size } + + fun part2() = bfs({ 1 }, Int::plus).values.sum() + + companion object { + private val IntPair.adj: List + get() = listOf( + first - 1 to second, + first to second - 1, + first to second + 1, + first + 1 to second, + ) + } +} diff --git a/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Days.kt b/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Days.kt index 2e08526..7c172ee 100644 --- a/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Days.kt +++ b/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Days.kt @@ -10,6 +10,7 @@ val days: List = listOf( Day(7, ::Day7, Day7::part1, Day7::part2), Day(8, ::Day8, Day8::part1, Day8::part2), Day(9, ::Day9, Day9::part1, Day9::part2), + Day(10, ::Day10, Day10::part1, Day10::part2), ) data class Day( diff --git a/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day10Test.kt b/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day10Test.kt new file mode 100644 index 0000000..6a426db --- /dev/null +++ b/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day10Test.kt @@ -0,0 +1,30 @@ +package com.github.ephemient.aoc2024 + +import kotlin.test.Test +import kotlin.test.assertEquals + +class Day10Test { + @Test + fun part1() { + assertEquals(36, Day10(example).part1()) + } + + @Test + fun part2() { + assertEquals(81, Day10(example).part2()) + } + + companion object { + private val example = + """ + |89010123 + |78121874 + |87430965 + |96549874 + |45678903 + |32019012 + |01329801 + |10456732 + |""".trimMargin() + } +}