appcodix
appcodix

Reputation: 342

Swap all Integers of a List with Scala

If I have a swap method, which can swap two Integers in a List:

def swap[E]: (List[E], Int, Int) => List[E] = (ls, i, j) => 
  ls.updated(i, ls(j)).updated(j, ls(i))

And now I want to swap all Integers of a list using this method. That means the result should be like this:

swapAll(List(1,2,3)) == List(List(2,1,3), List(3,2,1), List(1,3,2))

I thought of something like this:

def swapAll: List[Int] => List[List[Int]] = ls => for(i <- 0 to ls.length; j <- i to ls.length) yield List(swap(ps, i, j))

But it doesn't work, does somebody have an Idea?

Upvotes: 0

Views: 94

Answers (1)

Andrey Tyukin
Andrey Tyukin

Reputation: 44918

Almost there.

def swap[E](ls: List[E], i: Int, j: Int): List[E] = {
  ls.updated(i, ls(j)).updated(j, ls(i))
}


def swapAll(ps: List[Int]): List[List[Int]] = {
  val n = ps.size
  (for {
    i <- 0 until n
    j <- (i + 1) until n
  } yield swap(ps, i, j))(collection.breakOut)
}

Example:

swapAll(List(1, 2, 3))
// List(List(2, 1, 3), List(3, 2, 1), List(1, 3, 2))

The breakOut is a special explicitly inserted CanBuildFrom. It's necessary because without it, the type of the produced collection is some weird IndexedSequence derived from the 0 until n Range, but you want a List instead.

Upvotes: 3

Related Questions