diff --git a/README.md b/README.md index c46030a9..0f40d420 100644 --- a/README.md +++ b/README.md @@ -17,4 +17,4 @@ Development occurs in language-specific directories: |[Day10.hs](hs/src/Day10.hs)|[Day10.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day10.kt)|[day10.py](py/aoc2024/day10.py)|[day10.rs](rs/src/day10.rs)| |[Day11.hs](hs/src/Day11.hs)|[Day11.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day11.kt)|[day11.py](py/aoc2024/day11.py)|[day11.rs](rs/src/day11.rs)| |[Day12.hs](hs/src/Day12.hs)|[Day12.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day12.kt)|[day12.py](py/aoc2024/day12.py)|| -|[Day13.hs](hs/src/Day13.hs)|||| +|[Day12.hs](hs/src/Day12.hs)|[Day12.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day12.kt)||| diff --git a/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day13Bench.kt b/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day13Bench.kt new file mode 100644 index 00000000..7b265f59 --- /dev/null +++ b/kt/aoc2024-exe/src/commonBench/kotlin/com/github/ephemient/aoc2024/exe/Day13Bench.kt @@ -0,0 +1,31 @@ +package com.github.ephemient.aoc2024.exe + +import com.github.ephemient.aoc2024.Day13 +import kotlinx.benchmark.Benchmark +import kotlinx.benchmark.Blackhole +import kotlinx.benchmark.Scope +import kotlinx.benchmark.Setup +import kotlinx.benchmark.State + +@State(Scope.Benchmark) +class Day13Bench { + private lateinit var input: String + + @Setup + fun setup() { + input = getDayInput(13) + } + + @Benchmark + fun part1() = Day13(input).part1() + + @Benchmark + fun part2() = Day13(input).part2() + + @Benchmark + fun solve(bh: Blackhole) { + val day13 = Day13(input) + bh.consume(day13.part1()) + bh.consume(day13.part2()) + } +} diff --git a/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day13.kt b/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day13.kt new file mode 100644 index 00000000..9a1ef03c --- /dev/null +++ b/kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day13.kt @@ -0,0 +1,42 @@ +package com.github.ephemient.aoc2024 + +class Day13(input: String) { + private val machines = pattern.findAll(input).map { matchResult -> + val (ax, ay, bx, `by`, x, y) = matchResult.destructured + Machine(ax.toLong(), ay.toLong(), bx.toLong(), `by`.toLong(), x.toLong(), y.toLong()) + }.toList() + + fun part1() = machines.sumOf { it.solve() } + + fun part2() = machines.sumOf { it.copy(x = it.x + 10000000000000, y = it.y + 10000000000000).solve() } + + private data class Machine( + val ax: Long, + val ay: Long, + val bx: Long, + val `by`: Long, + val x: Long, + val y: Long, + ) { + fun solve(): Long { + val aNumerator = x * `by` - y * bx + val aDenominator = ax * `by` - bx * ay + val bNumerator = x * ay - y * ax + val bDenominator = ay * bx - `by` * ax + return if (aNumerator % aDenominator == 0L && bNumerator % bDenominator == 0L) { + val a = aNumerator / aDenominator + val b = bNumerator / bDenominator + 3 * a + b + } else 0 + } + } + + companion object { + private val pattern = + """ + Button A: X\+(\d+), Y\+(\d+) + Button B: X\+(\d+), Y\+(\d+) + Prize: X=(\d+), Y=(\d+) + """.trimIndent().toRegex() + } +} 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 8e377b0c..ab96ff84 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 @@ -13,6 +13,7 @@ val days: List = listOf( Day(10, ::Day10, Day10::part1, Day10::part2), Day(11, ::Day11, Day11::part1, Day11::part2), Day(12, ::Day12, Day12::part1, Day12::part2), + Day(13, ::Day13, Day13::part1, Day13::part2), ) data class Day( diff --git a/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day12Test.kt b/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day12Test.kt index 6af2c140..1b20cc29 100644 --- a/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day12Test.kt +++ b/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day12Test.kt @@ -13,9 +13,9 @@ class Day12Test { @Test fun part2() { -// assertEquals(80, Day12(example1).part2()) -// assertEquals(436, Day12(example2).part2()) -// assertEquals(236, Day12(example4).part2()) + assertEquals(80, Day12(example1).part2()) + assertEquals(436, Day12(example2).part2()) + assertEquals(236, Day12(example4).part2()) assertEquals(368, Day12(example5).part2()) assertEquals(1206, Day12(example3).part2()) } diff --git a/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day13Test.kt b/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day13Test.kt new file mode 100644 index 00000000..41a4c222 --- /dev/null +++ b/kt/aoc2024-lib/src/commonTest/kotlin/com/github/ephemient/aoc2024/Day13Test.kt @@ -0,0 +1,32 @@ +package com.github.ephemient.aoc2024 + +import kotlin.test.Test +import kotlin.test.assertEquals + +class Day13Test { + @Test + fun part1() { + assertEquals(480, Day13(example).part1()) + } + + companion object { + val example = + """ + |Button A: X+94, Y+34 + |Button B: X+22, Y+67 + |Prize: X=8400, Y=5400 + | + |Button A: X+26, Y+66 + |Button B: X+67, Y+21 + |Prize: X=12748, Y=12176 + | + |Button A: X+17, Y+86 + |Button B: X+84, Y+37 + |Prize: X=7870, Y=6450 + | + |Button A: X+69, Y+23 + |Button B: X+27, Y+71 + |Prize: X=18641, Y=10279 + |""".trimMargin() + } +}