diff --git a/README.md b/README.md index a9aa43b9..b978bd1d 100644 --- a/README.md +++ b/README.md @@ -9,4 +9,4 @@ Development occurs in language-specific directories: |[Day2.hs](hs/src/Day2.hs)|[Day2.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day2.kt)|[day2.py](py/aoc2024/day2.py)|[day2.rs](rs/src/day2.rs)| |[Day3.hs](hs/src/Day3.hs)|[Day3.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day3.kt)|[day3.py](py/aoc2024/day3.py)|[day3.rs](rs/src/day3.rs)| |[Day4.hs](hs/src/Day4.hs)|[Day4.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day4.kt)|[day4.py](py/aoc2024/day4.py)|[day4.rs](rs/src/day4.rs)| -|[Day5.hs](hs/src/Day5.hs)|||| +|[Day5.hs](hs/src/Day5.hs)|[Day5.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day5.kt)||| diff --git a/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day5Bench.kt b/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day5Bench.kt new file mode 100644 index 00000000..3216d3b3 --- /dev/null +++ b/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day5Bench.kt @@ -0,0 +1,23 @@ +package com.github.ephemient.aoc2024.exe + +import com.github.ephemient.aoc2024.Day5 +import kotlinx.benchmark.Benchmark +import kotlinx.benchmark.Scope +import kotlinx.benchmark.Setup +import kotlinx.benchmark.State + +@State(Scope.Benchmark) +class Day5Bench { + private lateinit var input: String + + @Setup + fun setup() { + input = getDayInput(5) + } + + @Benchmark + fun part1() = Day5(input).part1() + + @Benchmark + fun part2() = Day5(input).part2() +} diff --git a/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day5.kt b/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day5.kt new file mode 100644 index 00000000..2c27e221 --- /dev/null +++ b/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day5.kt @@ -0,0 +1,40 @@ +package com.github.ephemient.aoc2024 + +class Day5(input: String) { + private val deps: Set + private val updates: List> + + init { + val (deps, updates) = input.split("\n\n") + this.deps = deps.lines().mapTo(mutableSetOf()) { line -> + val (first, second) = line.split('|', limit = 2) + first.toInt() to second.toInt() + } + this.updates = updates.lines().mapNotNull { line -> + line.ifEmpty { return@mapNotNull null }.split(',').map { it.toInt() } + } + } + + fun part1() = updates.sumOf { pages -> + if ( + pages.withIndex().all { (i, x) -> + pages.subList(i + 1, pages.size).all { y -> y to x !in deps } + } + ) pages[pages.size / 2] else 0 + } + + fun part2(): Int = updates.sumOf { update -> + val pages = update.toMutableList() + for (i in pages.indices) { + while (true) { + val x = pages[i] + val j = i + 1 + pages.subList(i + 1, pages.size).indexOfFirst { it to x in deps } + if (j > i) { + pages[i] = pages[j] + pages[j] = x + } else break + } + } + if (update != pages) pages[pages.size / 2] else 0 + } +} 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 1b3b8d86..f533a7fd 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 @@ -5,6 +5,7 @@ val days: List = listOf( Day(2, ::Day2, Day2::part1, Day2::part2), Day(3, ::Day3, Day3::part1, Day3::part2), Day(4, ::Day4, Day4::part1, Day4::part2), + Day(5, ::Day5, Day5::part1, Day5::part2), ) data class Day( diff --git a/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day5Test.kt b/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day5Test.kt new file mode 100644 index 00000000..b131c283 --- /dev/null +++ b/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day5Test.kt @@ -0,0 +1,50 @@ +package com.github.ephemient.aoc2024 + +import kotlin.test.Test +import kotlin.test.assertEquals + +class Day5Test { + @Test + fun part1() { + assertEquals(143, Day5(example).part1()) + } + + @Test + fun part2() { + assertEquals(123, Day5(example).part2()) + } + + companion object { + private val example = + """ + |47|53 + |97|13 + |97|61 + |97|47 + |75|29 + |61|13 + |75|53 + |29|13 + |97|29 + |53|29 + |61|53 + |97|53 + |61|29 + |47|13 + |75|47 + |97|75 + |47|61 + |75|61 + |47|29 + |75|13 + |53|13 + | + |75,47,61,53,29 + |97,61,53,29,13 + |75,29,13 + |75,97,47,61,53 + |61,13,29 + |97,13,75,29,47 + |""".trimMargin() + } +}