Brent Yorgey byorgey at seas.upenn.edu
Thu Feb 12 14:40:09 EST 2009

```On Thu, Feb 12, 2009 at 08:19:46PM +0100, Thomas Davie wrote:
>
> On 12 Feb 2009, at 19:33, Brent Yorgey wrote:
>
>> On Thu, Feb 12, 2009 at 11:58:21AM -0500, Andrew Wagner wrote:
>>>>
>>>> <rant>
>>>> It seems everyone has just been reading the first few words of Jan's
>>>> email and not the actual content.  Jan is clearly trying to write a
>>>> *random list shuffling* function, not a function to generate
>>>> permutations.  Let's try to be helpful, people...
>>>> </rant>
>>>>
>>>
>>> Agreed, I've been quite confused by this thread. In the spirit of
>>> laziness,
>>> though, wouldn't it seem like the "right" method is to generate all the
>>> permutations lazily, and then choose a random element of that list?
>>
>> Well, it sounds nice, but it's pretty inefficient.  And by "pretty
>> inefficient" I mean "horrendously, terribly inefficient" -- there are
>> n! permutations of a list of length n, so this would take time O(n!)
>> as opposed to O(n); O(n!) is even worse than O(2^n).
>
> Would it?  We're talking about lazyness here... it's not gonna compute one
> it doesn't need, and if you're somewhat cleverer with your permute function
> than I was, I'm sure you can do as little computation as the imperative
> version.

Indexing into a list is still O(n) in the index, whether you actually
compute the elements or not.  That is, if you're actually building a
list of permutations, then even if you don't compute anything about
the permutations you don't need, just traversing through the spine of
the list to get the one you want will take a very long
time---O(n!)---for reasonably large n.  However, you can actually
write a pure function with type

Int -> [a] -> [a]

which just computes which permutation "would be" at the given index,
without ever actually constructing a list of them.  I'll leave this as
an interesting exercise (hint: convert the input number to "base
factorial"...), although I still think it's not going to be quite as
fast as the imperative version (at least O(n lg n)).

-Brent
```