11package me.peckb.aoc._2025.calendar.day10
22
3+ import com.microsoft.z3.BitVecNum
4+ import com.microsoft.z3.BitVecSort
5+ import com.microsoft.z3.Context
6+ import com.microsoft.z3.Expr
7+ import com.microsoft.z3.Optimize
8+ import com.microsoft.z3.Status
39import javax.inject.Inject
410import me.peckb.aoc.generators.InputGenerator.InputGeneratorFactory
11+ import org.apache.commons.math3.stat.inference.TestUtils.g
512import kotlin.math.min
13+ import kotlin.use
614
715class Day10 @Inject constructor(
816 private val generatorFactory : InputGeneratorFactory ,
@@ -15,7 +23,83 @@ class Day10 @Inject constructor(
1523
1624 fun partTwo (filename : String ) = generatorFactory.forFile(filename).readAs(::day10) { input ->
1725 input.sumOf { machine ->
18- 4
26+
27+ Context ().use { ctx ->
28+ var bestFound = Int .MAX_VALUE
29+
30+ val bits = 64 // the answer will fit inside a long
31+
32+ fun valueOf (value : Int ) = ctx.mkBV(value, bits)
33+
34+ fun variableOf (name : String ) = ctx.mkBVConst(name, bits)
35+
36+ infix fun Expr<BitVecSort>.equalTo (t : Expr <BitVecSort >) = ctx.mkEq(this , t)
37+
38+ infix fun Expr<BitVecSort>.notEqual (t : Expr <BitVecSort >) = ctx.mkNot(this equalTo t)
39+
40+ operator fun Expr<BitVecSort>.plus (t : Expr <BitVecSort >) = ctx.mkBVAdd(this , t)
41+
42+ operator fun Expr<BitVecSort>.times (t : Expr <BitVecSort >) = ctx.mkBVMul(this , t)
43+
44+ infix fun Expr<BitVecSort>.lessThan (t : Expr <BitVecSort >) = ctx.mkBVSLT(this , t)
45+
46+ infix fun Expr<BitVecSort>.gte (t : Expr <BitVecSort >) = ctx.mkBVSGE(this , t)
47+
48+ val a = variableOf(" a" )
49+ val b = variableOf(" b" )
50+ val c = variableOf(" c" )
51+ val d = variableOf(" d" )
52+ val e = variableOf(" e" )
53+ val f = variableOf(" f" )
54+
55+ val optimizer = ctx.mkOptimize()
56+
57+ optimizer.Add (e + f equalTo valueOf(3 ))
58+ optimizer.Add (b + f equalTo valueOf(5 ))
59+ optimizer.Add (c + d + e equalTo valueOf(4 ))
60+ optimizer.Add (a + b + d equalTo valueOf(7 ))
61+ // optimizer.Add(a lessThan valueOf(10000))
62+ // optimizer.Add(b lessThan valueOf(10000))
63+ // optimizer.Add(c lessThan valueOf(10000))
64+ // optimizer.Add(d lessThan valueOf(10000))
65+ // optimizer.Add(e lessThan valueOf(10000))
66+ // optimizer.Add(f lessThan valueOf(10000))
67+ optimizer.Add (a gte valueOf(0 ))
68+ optimizer.Add (b gte valueOf(0 ))
69+ optimizer.Add (c gte valueOf(0 ))
70+ optimizer.Add (d gte valueOf(0 ))
71+ optimizer.Add (e gte valueOf(0 ))
72+ optimizer.Add (f gte valueOf(0 ))
73+
74+ optimizer.MkMinimize (a + b + c + d + e + f)
75+
76+ optimizer.Check ()
77+ // while(optimizer.Check() == Status.SATISFIABLE) {
78+ val model = optimizer.model
79+
80+ val aEval = (model.evaluate(a, true ) as BitVecNum )
81+ val bEval = (model.evaluate(b, true ) as BitVecNum )
82+ val cEval = (model.evaluate(c, true ) as BitVecNum )
83+ val dEval = (model.evaluate(d, true ) as BitVecNum )
84+ val eEval = (model.evaluate(e, true ) as BitVecNum )
85+ val fEval = (model.evaluate(f, true ) as BitVecNum )
86+
87+ bestFound = min(bestFound, aEval.int + bEval.int + cEval.int + dEval.int + eEval.int + fEval.int)
88+
89+ // optimizer.Add(
90+ // ctx.mkOr(
91+ // a notEqual aEval,
92+ // b notEqual bEval,
93+ // c notEqual cEval,
94+ // d notEqual dEval,
95+ // e notEqual eEval,
96+ // f notEqual fEval,
97+ // )
98+ // )
99+ // }
100+ // println(bestFound)
101+ bestFound
102+ }
19103 }
20104 }
21105
0 commit comments