@@ -27,57 +27,31 @@ object Day13: AocDay(2024, 13) {
27
27
aMovement = aMovement,
28
28
bMovement = bMovement
29
29
)
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
36
35
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
39
38
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)
44
41
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 ) {
74
43
return null
75
44
}
76
45
77
- val aPress = model.variables.find { it.name == " aPress " } !!
78
- val bPress = model.variables.find { it.name == " bPress " } !!
46
+ return Pair (a, b)
47
+ }
79
48
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
81
55
}
82
56
}
83
57
@@ -133,10 +107,6 @@ object Day13: AocDay(2024, 13) {
133
107
}
134
108
135
109
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 )
140
110
return getClawMachines().mapNotNull { it.adjusted().solve() }.fold(BigInteger .ZERO , BigInteger ::add)
141
111
}
142
112
}
0 commit comments