Day 13. Wrong bet on dynamic programming for part 1.
This commit is contained in:
parent
9e7ac0057b
commit
0d6bf1ca43
110
src/aoc2024/Day13.kt
Normal file
110
src/aoc2024/Day13.kt
Normal 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()
|
||||
}
|
Loading…
Reference in New Issue
Block a user