From 798afb10a23cd0a929771de57b03875c0921c479 Mon Sep 17 00:00:00 2001 From: Daniel Lin Date: Sat, 7 Dec 2024 02:17:57 -0500 Subject: [PATCH] Day 7: Bridge Repair --- README.md | 2 +- .../github/ephemient/aoc2024/exe/Day7Bench.kt | 31 +++++++++++++ .../com/github/ephemient/aoc2024/Day7.kt | 43 +++++++++++++++++++ .../com/github/ephemient/aoc2024/Days.kt | 1 + .../com/github/ephemient/aoc2024/Day7Test.kt | 31 +++++++++++++ 5 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day7Bench.kt create mode 100644 kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt create mode 100644 kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day7Test.kt diff --git a/README.md b/README.md index 1ec8fb31..d9629137 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,4 @@ Development occurs in language-specific directories: |[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.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day5.kt)|[day5.py](py/aoc2024/day5.py)|[day5.rs](rs/src/day5.rs)| |[Day6.hs](hs/src/Day6.hs)|[Day6.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day6.kt)|[day6.py](py/aoc2024/day6.py)|[day6.rs](rs/src/day6.rs)| -|[Day7.hs](hs/src/Day7.hs)|||| +|[Day7.hs](hs/src/Day7.hs)|[Day7.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt)||[| diff --git a/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day7Bench.kt b/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day7Bench.kt new file mode 100644 index 00000000..236c6a34 --- /dev/null +++ b/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day7Bench.kt @@ -0,0 +1,31 @@ +package com.github.ephemient.aoc2024.exe + +import com.github.ephemient.aoc2024.Day7 +import kotlinx.benchmark.Benchmark +import kotlinx.benchmark.Blackhole +import kotlinx.benchmark.Scope +import kotlinx.benchmark.Setup +import kotlinx.benchmark.State + +@State(Scope.Benchmark) +class Day7Bench { + private lateinit var input: String + + @Setup + fun setup() { + input = getDayInput(7) + } + + @Benchmark + fun part1() = Day7(input).part1() + + @Benchmark + fun part2() = Day7(input).part2() + + @Benchmark + fun both(bh: Blackhole) { + val day7 = Day7(input) + bh.consume(day7.part1()) + bh.consume(day7.part2()) + } +} diff --git a/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt b/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt new file mode 100644 index 00000000..51676720 --- /dev/null +++ b/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt @@ -0,0 +1,43 @@ +package com.github.ephemient.aoc2024 + +class Day7(input: String) { + private val equations = input.lineSequence().filter { it.isNotEmpty() }.map { line -> + val (lhs, rhs) = line.split(": ", limit = 2) + lhs.toLong() to rhs.split(' ').map { it.toLong() } + }.toList() + + fun part1() = equations.sumOf { equation -> + val stack = mutableListOf(equation) + while (stack.isNotEmpty()) { + val (x, values) = stack.removeLast() + val y = values.last() + if (values.size == 1) { + if (x == y) return@sumOf equation.first else continue + } + val rest = values.subList(0, values.lastIndex) + if (x >= y) stack.add(x - y to rest) + if (x % y == 0L) stack.add(x / y to rest) + } + 0 + } + + fun part2() = equations.sumOf { equation -> + val stack = mutableListOf(equation) + while (stack.isNotEmpty()) { + val (x, values) = stack.removeLast() + val y = values.last() + if (values.size == 1) { + if (x == y) return@sumOf equation.first else continue + } + val rest = values.subList(0, values.lastIndex) + if (x >= y) stack.add(x - y to rest) + if (x % y == 0L) stack.add(x / y to rest) + if (x > y) { + var d = 10L + while (d <= y) d *= 10 + if (x % d == y) stack.add(x / d to rest) + } + } + 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 befda2d7..566470e0 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 @@ -7,6 +7,7 @@ val days: List = listOf( Day(4, ::Day4, Day4::part1, Day4::part2), Day(5, ::Day5, Day5::part1, Day5::part2), Day(6, ::Day6, Day6::part1, Day6::part2), + Day(7, ::Day7, Day7::part1, Day7::part2), ) data class Day( diff --git a/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day7Test.kt b/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day7Test.kt new file mode 100644 index 00000000..14ed26ae --- /dev/null +++ b/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day7Test.kt @@ -0,0 +1,31 @@ +package com.github.ephemient.aoc2024 + +import kotlin.test.Test +import kotlin.test.assertEquals + +class Day7Test { + @Test + fun part1() { + assertEquals(3749L, Day7(example).part1()) + } + + @Test + fun part2() { + assertEquals(11387L, Day7(example).part2()) + } + + companion object { + private val example = + """ + |190: 10 19 + |3267: 81 40 27 + |83: 17 5 + |156: 15 6 + |7290: 6 8 6 15 + |161011: 16 10 13 + |192: 17 8 14 + |21037: 9 7 18 13 + |292: 11 6 16 20 + |""".trimMargin() + } +}