Skip to content

Instantly share code, notes, and snippets.

@sshark
Last active July 15, 2016 06:58
Show Gist options
  • Select an option

  • Save sshark/c8372821f1cd642b9d2c to your computer and use it in GitHub Desktop.

Select an option

Save sshark/c8372821f1cd642b9d2c to your computer and use it in GitHub Desktop.
Show all permutations
// returns a lazy sequence
def fillAndArrange(xs: Seq[Int], ys: Seq[Int] = 1 to 9): Stream[Seq[Int]] = ys.diff(xs) match {
case Seq() => Stream(xs)
case zs => zs.flatten(z => fillAndArrange(xs.updated(xs.indexOf(0),z),zs)).toStream
}
assert(fillAndArrange(List(0, 0, 1, 5, 0, 0, 8, 0, 0)).size == 720)
// more elaborated than using Seq.updated(...) and returns a strict sequence
def arrange(l: Seq[Int], acc: Seq[Int] = Seq.empty[Int]): Seq[Seq[Int]] = l match {
case Nil => Seq(acc)
case xs => xs.flatMap(y => arrange(xs.filterNot(_ == y), acc :+ y))
}
def replaceZeros(zeros: Seq[Int], nonZeros: Seq[Int], acc: Seq[Int] = Seq.empty[Int]): Seq[Int] = zeros match {
case Nil => acc
case x +: xs => if (x == 0) replaceZeros(zeros.tail, nonZeros.tail, acc :+ nonZeros.head) else
replaceZeros(zeros.tail, nonZeros, acc :+ x)
}
def arrangements(s: String): Seq[Seq[Int]] =
if (s.size == 9 && s.forall(x => (x.toChar >= 0x30 && x.toChar <= 0x39) || x == '_')) {
val nums = s.map(x => if (x == '_') 0 else x.toInt - 0x30)
val missingNums = (1 to 9).filterNot(nums.contains(_))
arrange(missingNums)
} else Nil
assert(arrangements("4___7__1_").distinct.size == 720)
assert(arrangements("4__a7__1_") == Nil)
assert(arrangements("4__7__1_").size == 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment