Skip to content

Commit

Permalink
Port 05AB1E's transpose
Browse files Browse the repository at this point in the history
  • Loading branch information
ysthakur committed May 23, 2023
1 parent 571be84 commit 752d5aa
Showing 1 changed file with 28 additions and 26 deletions.
54 changes: 28 additions & 26 deletions shared/src/main/scala/ListHelpers.scala
Expand Up @@ -40,7 +40,6 @@ object ListHelpers:
end filter

/** A wrapper call to the generator method in interpreter */

def generate(function: VFun, initial: VList)(using ctx: Context): VList =
val firstN = initial.length match
case 0 => ctx.settings.defaultValue
Expand Down Expand Up @@ -245,40 +244,43 @@ object ListHelpers:
parts.toSeq
end split

/** Transpose a matrix.
*
* Hangs on infinite lists of finite lists. See [[transposeSafe]] for a version that handles those.
* Based on [[https://github.com/Adriandmen/05AB1E/blob/master/lib/commands/matrix_commands.ex 05AB1E's implementation]].
*/
def transpose(iterable: VList, filler: Option[VAny] = None)(using
ctx: Context
): VList =
/*Transposes a matrix
In order to handle infinite lists, it generates the transpose
antidiagonal by antidiagonal.
*/

val matrix = iterable.map(makeIterable(_))

def genRow(r: BigInt) =
val temp: LazyList[Option[VAny]] = LazyList
.unfold(0) { c =>
if !matrix.isDefinedAt(c) then None
else if matrix(c).isDefinedAt(r) then
Some((Some(matrix(c).index(r)), c + 1))
else if filler.isDefined then
Some((Some(filler.getOrElse(VNum(0))), c + 1))
else Some((None, c + 1))
val out = filler match
case None => LazyList.unfold(matrix) { matrix =>
val remaining = matrix.filter(_.nonEmpty)
Option.when(remaining.nonEmpty) {
(remaining.map(_.head), remaining.map(_.tail))
}
}
case Some(filler) => LazyList.unfold(matrix) { matrix =>
Option.when(matrix.exists(_.nonEmpty)) {
(matrix.flatMap(_.headOption.getOrElse(filler)), matrix.map(_.tail))
}
}
VList.from(temp.flatten)

val out: LazyList[VAny] = LazyList
.unfold(0) { r =>
if !matrix.exists(_.isDefinedAt(r)) then None
else
val row = genRow(r)
if row.forall(_.isInstanceOf[String]) then Some((row.mkString, r + 1))
else Some((row, r + 1))
}
VList.from(out)

end transpose

/** Transpose a matrix. Uses the length of the first row of the inputted matrix
* as the number of columns in the resulting matrix.
*
* @see transpose
*/
def transposeSafe(iterable: VList, filler: Option[VAny] = None)(using
ctx: Context
): VList =
val matrix = iterable.map(makeIterable(_))
???
end transposeSafe

def vectorisedMaximum(iterable: VList, b: VVal): VList =
VList.from(iterable.map { a =>
(a: @unchecked) match
Expand Down

0 comments on commit 752d5aa

Please sign in to comment.