Skip to content

Commit 0fc9660

Browse files
committed
Simplify gaussian elimination solution in 2025 day 10 part 2
1 parent a1a26b4 commit 0fc9660

File tree

1 file changed

+17
-28
lines changed

1 file changed

+17
-28
lines changed

src/main/scala/eu/sim642/adventofcode2025/Day10.scala

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -120,41 +120,30 @@ object Day10 {
120120
val zeroCol = machine.joltages.map(_ => 0L)
121121
val rows =
122122
machine.buttons
123-
.map(button =>
124-
button.foldLeft(zeroCol)((acc, i) => acc.updated(i, 1L))
125-
)
123+
.map(_.foldLeft(zeroCol)(_.updated(_, 1L)))
126124
.transpose
127125

128126
val sol = GaussianElimination.solve(rows, machine.joltages.map(_.toLong))
129-
130127
//val mSum = m.transpose.map(_.sum) // TODO: use?
131128

132-
val maxVals = machine.buttons.map(_.map(machine.joltages(_)).min)
133-
134-
def helper0(sum: Int, maxs: List[Int]): Iterator[List[Int]] = {
135-
maxs match {
136-
case Nil => Iterator(Nil)
137-
case List(m) if sum <= m => Iterator(List(sum))
138-
case List(m) => Iterator.empty
139-
case m :: newMaxs =>
140-
for {
141-
x <- (0 to (m min sum)).iterator
142-
rest <- helper0(sum - x, newMaxs)
143-
} yield x :: rest
144-
}
129+
def helper(freeMaxs: List[Int]): Iterator[List[Int]] = freeMaxs match { // TODO: this seems like it should exist from earlier somewhere
130+
case Nil => Iterator(Nil)
131+
case freeMax :: newFreeMaxs =>
132+
for {
133+
freeVal <- (0 to freeMax).iterator
134+
newFreeVals <- helper(newFreeMaxs)
135+
} yield freeVal :: newFreeVals
145136
}
146137

147-
val bound = sol.freeVars.map(maxVals).sum
148-
val choices = (0 to bound).iterator.flatMap(helper0(_, sol.freeVars.map(maxVals).toList))
149-
150-
val answer =
151-
choices
152-
.map(freeVals => (sol.evaluate(freeVals.map(_.toLong)), freeVals))
153-
.filter(p => p._1.forall(_ >= 0) && (p._1 lazyZip sol.dependentVars).forall((a, b) => a <= maxVals(b))) // all main vals must be non-negative, but at most their max
154-
.map((s1, s2) => s1.sum + s2.sum)
155-
.min
156-
157-
answer.toInt
138+
val maxs = machine.buttons.map(_.map(machine.joltages).min)
139+
val freeMaxs = sol.freeVars.map(maxs)
140+
val dependentMaxs = sol.dependentVars.map(maxs)
141+
(for {
142+
freeVals <- helper(freeMaxs.toList)
143+
dependentVals = sol.evaluate(freeVals.map(_.toLong))
144+
if dependentVals.forall(_ >= 0)
145+
if (dependentVals lazyZip dependentMaxs).forall(_ <= _)
146+
} yield dependentVals.sum.toInt + freeVals.sum).min
158147
}
159148
}
160149

0 commit comments

Comments
 (0)