Skip to content

Commit 6fe66d7

Browse files
committed
feat: day 13
1 parent 4470ef6 commit 6fe66d7

File tree

1 file changed

+18
-48
lines changed
  • src/main/kotlin/dev/mtib/aoc/aoc24/days

1 file changed

+18
-48
lines changed

src/main/kotlin/dev/mtib/aoc/aoc24/days/Day13.kt

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -27,57 +27,31 @@ object Day13: AocDay(2024, 13) {
2727
aMovement = aMovement,
2828
bMovement = bMovement
2929
)
30-
private fun toModel(): ExpressionsBasedModel {
31-
val options = Options()
32-
options.integer(IntegerStrategy.newConfigurable().withParallelism(Parallelism.CORES))
33-
options.solution = NumberContext.of(200, 200)
34-
options.feasibility = NumberContext.of(100, 100)
35-
val model = ExpressionsBasedModel(options)
30+
private fun findIntersection(
31+
aX: BigInteger, aY: BigInteger, bX: BigInteger, bY: BigInteger, xPrize: BigInteger, yPrize: BigInteger
32+
): Pair<BigInteger, BigInteger>? {
33+
val aXWithBY = aX * bY
34+
val xPrizeWithBY = xPrize * bY
3635

37-
val aPress = model.addVariable("aPress").integer().lower(0)
38-
val bPress = model.addVariable("bPress").integer().lower(0)
36+
val aYWithBX = aY * bX
37+
val yPrizeWithBX = yPrize * bX
3938

40-
val cost = model.addExpression("cost")
41-
cost.set(aPress, BigInteger("3"))
42-
cost.set(bPress, BigInteger("1"))
43-
cost.weight(1)
39+
val (a, aRem) = (xPrizeWithBY - yPrizeWithBX).divideAndRemainder(aXWithBY - aYWithBX)
40+
val (b, bRem) = (yPrize - aY * a).divideAndRemainder(bY)
4441

45-
val xMatch = model.addExpression("xMatch").lower(target.first).upper(target.first)
46-
xMatch.set(aPress, aMovement.first)
47-
xMatch.set(bPress, bMovement.first)
48-
49-
val yMatch = model.addExpression("yMatch").lower(target.second).upper(target.second)
50-
yMatch.set(aPress, aMovement.second)
51-
yMatch.set(bPress, bMovement.second)
52-
53-
return model
54-
}
55-
56-
fun solve(): BigInteger? {
57-
val model = toModel()
58-
val result: Optimisation.Result? = run {
59-
for (i in 1..(if (partMode == 2) 10 else 1)) {
60-
val result = model.minimise()
61-
if (result.state.isFeasible) {
62-
if (i > 1) {
63-
logger.log { "found solution after ${i} iterations" }
64-
}
65-
if (model.validate(result)) {
66-
return@run result
67-
}
68-
}
69-
}
70-
null
71-
}
72-
73-
if (result == null) {
42+
if (aRem.compareTo(BigInteger.ZERO) != 0 || bRem.compareTo(BigInteger.ZERO) != 0) {
7443
return null
7544
}
7645

77-
val aPress = model.variables.find { it.name == "aPress" }!!
78-
val bPress = model.variables.find { it.name == "bPress" }!!
46+
return Pair(a, b)
47+
}
7948

80-
return aPress.value.toBigIntegerExact().multiply(BigInteger("3")) + bPress.value.toBigIntegerExact()
49+
50+
fun solve(): BigInteger? {
51+
val (aPress, bPress) = findIntersection(
52+
aMovement.first, aMovement.second, bMovement.first, bMovement.second, target.first, target.second
53+
) ?: return null
54+
return aPress.multiply(BigInteger("3")) + bPress
8155
}
8256
}
8357

@@ -133,10 +107,6 @@ object Day13: AocDay(2024, 13) {
133107
}
134108

135109
override suspend fun part2(): BigInteger {
136-
not(465116279064, Hint.Direction.TooLow)
137-
not(57928637781847, Hint.Direction.TooLow)
138-
not(81122608248687, Hint.Direction.TooHigh)
139-
not(80657109890803)
140110
return getClawMachines().mapNotNull { it.adjusted().solve() }.fold(BigInteger.ZERO, BigInteger::add)
141111
}
142112
}

0 commit comments

Comments
 (0)