Skip to content

Commit 2763310

Browse files
committed
Optimize gaussian elimination solution evaluation
1 parent d0ad64c commit 2763310

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

src/main/scala/eu/sim642/adventofcodelib/GaussianElimination.scala

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,24 @@ object GaussianElimination {
1010
case class Solution[A: Integral](dependentVars: Seq[Int], dependentGenerator: Seq[A],
1111
freeVars: Seq[Int], freeGenerators: Seq[Seq[A]],
1212
const: Seq[A]) {
13+
private lazy val freeGeneratorsTransposed = { // transpose of empty generators needs right length for lazyZip to work below
14+
if (freeGenerators.isEmpty)
15+
const.map(_ => Nil)
16+
else
17+
freeGenerators.transpose
18+
}
19+
20+
require(dependentGenerator.size == const.size)
21+
require(dependentGenerator.size == freeGeneratorsTransposed.size)
22+
1323
def evaluate(freeVals: Seq[A]): Seq[A] = {
14-
(dependentGenerator lazyZip const).zipWithIndex.map({case ((mainVar, v), i) =>
15-
val r = v - (freeGenerators lazyZip freeVals).map((freeVar, freeVal) => freeVar(i) * freeVal).sum
24+
(const lazyZip freeGeneratorsTransposed lazyZip dependentGenerator).map((v, fgt, mainVar) => {
25+
val r = v - (fgt lazyZip freeVals).map(_ * _).sum
1626
if (r % mainVar == 0)
1727
r / mainVar
1828
else
1929
-summon[Integral[A]].one // TODO: Option
20-
}).toList
30+
})
2131
}
2232
}
2333

@@ -101,8 +111,8 @@ object GaussianElimination {
101111
dependentVars = mainVars.toSeq,
102112
dependentGenerator = (mainVars lazyZip m).view.map((v, row) => row(v)).toSeq,
103113
freeVars = freeVars.toSeq,
104-
freeGenerators = freeVars.view.map(x => m.view.map(_(x)).toSeq).toSeq,
105-
const = m.view.map(_.last).toSeq
114+
freeGenerators = freeVars.view.map(x => m.view.take(mainVars.size).map(_(x)).toSeq).toSeq,
115+
const = m.view.take(mainVars.size).map(_.last).toSeq
106116
)
107117
}
108118
}

0 commit comments

Comments
 (0)