I’m looking at Pavel’s solution to Project Euler question 24, but can’t quite work out how this function works – can someone explain what it’s doing? Its purpose is to return the millionth lexicographic permutation of the digits 0 to 9.
def ps(s: String): Seq[String] = if(s.size == 1) Seq(s) else
s.flatMap(c => ps(s.filterNot(_ == c)).map(c +))
val r = ps("0123456789")(999999).toLong
I understand that when the input String is length 1, the function returns that character as a Seq, and I think then what happens is that it’s appended to the only other character that was left, but I can’t really visualise how you get to that point, or why this results in a list of permutations.
(I already solved the problem myself but used the permutations method, which makes it a fairly trivial 1-liner, but would like to be able to understand the above.)
For each letter (
flatMap(c => ...)) of the given strings,psgenerates a permutation by permutating the remaining lettersps(s.filterNot(_ == c))and prepending the taken letter in front of this permutation (map(c +)). For the trivial case of a one letter string, it does nothing (if(s.size == 1) Seq(s)).Edit: Why does this work?
Let’s begin with shuffling a one letter string:
Now for two letters, we split the task into subtasks. Take each character in the set, put it to the first position and permutate the rest.
For three letters, it’s the same. Take each character and prepend it to each of the sub-permutations of the remaining letters.
So, basically the outermost function guarantees that each letter gets to the first position, the first recursive call guarantees the same for the second position and so on.