I need to generate permutations on a given list. I managed to do it like this
let rec Permute (final, arr) =
if List.length arr > 0 then
for x in arr do
let n_final = final @ [x]
let rest = arr |> List.filter (fun a -> not (x = a))
Permute (n_final, rest)
else
printfn "%A" final
let DoPermute lst =
Permute ([], lst)
DoPermute lst
There are obvious issues with this code. For example, list elements must be unique. Also, this is more-less a same approach that I would use when generating straight forward implementation in any other language. Is there any better way to implement this in F#.
Thanks!
For permutations of small lists, I use the following code:
It works as follows: the function "distrib" distributes a given element over all positions in a list, example:
The function perms works (recursively) as follows: distribute the head of the list over all permutations of its tail.
The distrib function will get slow for large lists, because it uses the @ operator a lot, but for lists of reasonable length (<=10), the code above works fine.
One warning: if your list contains duplicates, the result will contain identical permutations. For example:
The nice thing about this code is that it returns a sequence of permutations, instead of generating them all at once.
Of course, generating permutations with an imperative array-based algorithm will be (much) faster, but this algorithm has served me well in most cases.
In the spirit of Cyrl's suggestion, here's a sequence comprehension version
where
remove
is a simple function that removes a given element from a listIMHO the best solution should alleviate the fact that F# is a functional language so imho the solution should be as close to the definition of what we mean as permutation there as possible. So the permutation is such an instance of list of things where the head of the list is somehow added to the permutation of the rest of the input list. The erlang solution shows that in a pretty way:
taken fron the "programming erlang" book
There is a list comprehension operator used, in solution mentioned here by the fellow stackoverflowers there is a helper function which does the similar job basically I'd vote for the solution without any visible loops etc, just pure function definition
Here's the solution I gave in my book F# for Scientists (page 166-167):
It depends on what you mean by "better". I'd consider this to be slightly more elegant, but that may be a matter of taste:
This can handle lists with duplicate elements, though it will result in duplicated permutations.
Here's another sequence-based version, hopefully more readable than the voted answer. This version is similar to Jon's version in terms of logic, but uses computation expressions instead of lists. The first function computes all ways to insert an element x in a list l. The second function computes permutations. You should be able to use this on larger lists (e.g. for brute force searches on all permutations of a set of inputs).