@@ -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