Day 13. Wrong bet on dynamic programming for part 1.

This commit is contained in:
Chris Hodges 2024-12-13 07:02:38 +01:00
parent 9e7ac0057b
commit 0d6bf1ca43

110
src/aoc2024/Day13.kt Normal file
View File

@ -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<String>): 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<Int>()
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<String>): 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()
}