Guest User

Untitled

a guest
Dec 18th, 2024
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 2.61 KB | Source Code | 0 0
  1. package day13
  2.  
  3. import common.aocreader.fetchAdventOfCodeInput
  4. import common.vec2d.*
  5. import common.runner.timedFunction
  6. import java.math.BigInteger
  7.  
  8.  
  9. data class Machine(val deltaA: Vec2DInt, val deltaB: Vec2DInt, val prizePos: Vec2DInt) {
  10.     /**
  11.      * Let a be the number of times we hit button A, and b be the number of times we hit button B.
  12.      * We want an integer solution to the equation:
  13.      * [dAx  dBx] (a) = (px)
  14.      * [dAy  dBy] (b)   (py)
  15.      */
  16.     fun calculateSolution(adjustment: Vec2DBigInt): Vec2DBigInt? {
  17.         val determinant = deltaA.x * deltaB.y - deltaB.x * deltaA.y
  18.         if (determinant == 0) return null
  19.  
  20.         // Adjusted prize pos.
  21.         val adjPrizePos = prizePos.toBigInteger() + adjustment
  22.  
  23.         // Rows of the inverted matrix * determinant
  24.         val detR1 = Vec2D.int(deltaB.y, -deltaB.x)
  25.         val detR2 = Vec2D.int(-deltaA.y, deltaA.x)
  26.  
  27.         val abDet = Vec2D.bigInt(
  28.             deltaB.y.toBigInteger() * adjPrizePos.x - deltaB.x.toBigInteger() * adjPrizePos.y,
  29.             deltaA.x.toBigInteger() * adjPrizePos.y - deltaA.y.toBigInteger() * adjPrizePos.x)
  30.  
  31.         // Mod these by determinant, and if zero, divide
  32.         val detBigInt = determinant.toBigInteger()
  33.         return if (abDet % detBigInt == Vec2DBigIntZero)
  34.             abDet / detBigInt
  35.         else
  36.             null
  37.     }
  38.  
  39.     companion object {
  40.         val TokenCost = Vec2D.bigInt(3.toBigInteger(), 1.toBigInteger())
  41.  
  42.         private val MachineRegex = """[XY][+=](\d+)""".toRegex()
  43.  
  44.         fun parse(input: String): Machine {
  45.             val matches = MachineRegex.findAll(input).map { it.groupValues[1].toInt() }.toList()
  46.             val (deltaA, deltaB, prizePos) = matches.chunked(2).map { Vec2D.int(it[0], it[1]) }
  47.             return Machine(deltaA, deltaB, prizePos)
  48.         }
  49.     }
  50. }
  51.  
  52. fun parse(input: String): List<Machine> =
  53.     input.split("""[\r\n]{2}""".toRegex()).map { Machine.parse(it.trim()) }
  54.  
  55. fun answer(input: String, adjustment: Vec2DBigInt = Vec2DBigIntZero): BigInteger =
  56.     parse(input)
  57.         .mapNotNull { it.calculateSolution(adjustment) }
  58.         .sumOf { sol -> sol dot Machine.TokenCost}
  59.  
  60. fun answer1(input: String): BigInteger =
  61.     answer(input)
  62.  
  63. private val adjustment2 = BigInteger("10000000000000")
  64.  
  65. fun answer2(input: String): BigInteger =
  66.     answer(input, Vec2D.bigInt(adjustment2, adjustment2))
  67.  
  68. fun main() {
  69.     val input = fetchAdventOfCodeInput(2024, 13)
  70.     println("--- Day 13: Claw Contraption ---")
  71.     timedFunction("Part 1") { answer1(input) } // 28262
  72.     timedFunction("Part 2") { answer2(input) } // 101406661266314
  73. }
Advertisement
Add Comment
Please, Sign In to add comment