diff --git a/src/aoc2024/Day13.kt b/src/aoc2024/Day13.kt new file mode 100644 index 0000000..b3cde5a --- /dev/null +++ b/src/aoc2024/Day13.kt @@ -0,0 +1,110 @@ +package aoc2024 + +import println +import readInput + +/* +--- Day 13: Claw Contraption --- +https://adventofcode.com/2024/day/13 +*/ +fun main() { + + val inlineTestInput = """ +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 +""" + + fun part1(input: List): Int { + var i = 0 + var sum = 0 + while (i < input.size) { + val (ax, ay) = "Button A: X\\+(\\d+), Y\\+(\\d+)".toRegex().find(input[i++])!!.groupValues.drop(1).map { it.toInt() } + val (bx, by) = "Button B: X\\+(\\d+), Y\\+(\\d+)".toRegex().find(input[i++])!!.groupValues.drop(1).map { it.toInt() } + val (px, py) = "Prize: X=(\\d+), Y=(\\d+)".toRegex().find(input[i++])!!.groupValues.drop(1).map { it.toInt() } + i++ + val xpos = IntArray(101 * 101) + val ypos = IntArray(101 * 101) + val solutions = ArrayList() + for (b in 1..100) { + for (a in 1..100) { + val op = (a - 1) + (b - 1) * 101 + if ((xpos[op] == px) && (ypos[op] == py)) { + solutions.add(op) + } + if ((xpos[op] > px) || (ypos[op] > py)) break + xpos[a + (b - 1) * 101] = xpos[op] + ax + xpos[(a - 1) + b * 101] = xpos[op] + bx + ypos[a + (b - 1) * 101] = ypos[op] + ay + ypos[(a - 1) + b * 101] = ypos[op] + by + } + } + val minTokens = solutions.minOfOrNull { (it % 101) * 3 + (it / 101) } + sum += minTokens ?: 0 + } + return sum + } + + fun part2(input: List): Long { + var i = 0 + var sum = 0L + + // 1. ax * pa + bx * pb = px + // 2. ay * pa + by * pb = py + // 3. pa * 3 + pb <- min + // 4. pa, pb in N (int > 0) + + // ax * pa + bx * pb - px = ay * pa + by * pb - py + // (ax - ay) * pa + (bx - by) * pb + py - px = 0 + // (ax - ay) * pa + (bx - by) * pb = px - py + + while (i < input.size) { + val (ax, ay) = "Button A: X\\+(\\d+), Y\\+(\\d+)".toRegex().find(input[i++])!!.groupValues.drop(1).map { it.toLong() } + val (bx, by) = "Button B: X\\+(\\d+), Y\\+(\\d+)".toRegex().find(input[i++])!!.groupValues.drop(1).map { it.toLong() } + val (px, py) = "Prize: X=(\\d+), Y=(\\d+)".toRegex().find(input[i++])!!.groupValues.drop(1).map { it.toLong() + 10000000000000L } + i++ + +// val t1 = ax - ay +// val t2 = bx - by +// val t3 = px - py + + val pad = (px * by - py * bx) + val pan = (ax * by - ay * bx) + if (pad % pan == 0L) { + val pa = pad / pan + val pbd = (px - pa * ax) + if (pbd % bx == 0L) { + val pb = pbd / bx + sum += pa * 3 + pb + } + } + } + return sum + } + + // test if implementation meets criteria from the description, like: + val testInput = inlineTestInput.trim().reader().readLines() + //val testInput = readInput("aoc2024/Day13_test") + val testInputPart1Result = part1(testInput) + println("Part 1 Test: $testInputPart1Result") + val testInputPart2Result = part2(testInput) + println("Part 2 Test: $testInputPart2Result") + check(testInputPart1Result == 480) + //check(testInputPart2Result == 0L) + + val input = readInput("aoc2024/Day13") + part1(input).println() + part2(input).println() +}