After accepting that I was confused by forces, it all started making sense

Posted by s on Nov. 27, 2008, 3:27 p.m.

I saw a most beautiful face. I can't remember it though. It was the kind that you see and it is there to be appreciated and then you look away and the image is gone

http://www.wsu.edu/~brians/errors/errors.html

Now have a permutator

def permutate(x):

. if len(x)<2:return [x]

. r=[]

. for y in xrange(len(x)):

. . z=x[:]

. . z[0],z[y]=z[y],z[0]

. . r+=map(lambda x:[z[0]]+x,permutate(z[1:]))

. return r

Given a sorted input, it won't output in lexically sorted order. Issue is the swap mechanism, I should be taking out y and leaving 0 where it is. This can be remedied with

def permutate(x):

. if len(x)<2:return [x]

. r=[]

. for y in xrange(len(x)):

. . z=x[:]

. . Y=[z[y]]

. . del z[y]

. . r+=map(lambda x:Y+x,permutate(z))

. return r

The z=x[:];Y=[z[y]];del z[y] can be taken out by making permutate(z) permutate(x[:y]+x[y+1:]) and Y [x[y]]. This degrades performance slightly though, but since it makes the for loop a single line it can be turned into a list comprehension. This makes up for the degraded performance. So, here's a permutation outputter in one line

def permutate(x):return [x] if len(x)<2 else [map(lambda Y:[x[y]]+Y,permutate(x[:y]+x[y+1:])) for y in xrange(len(x))]

The main issue with this being that it doesn't output the simplest output. Instead it outputs trees, so 0123 and 0132 both share the same 0. The following simplifies the issue by instead grouping them only by the root (Where each list shares the same root and is in a list, not the weird system of the above). This means that if one wishes for a flat list of the lists, reduce(lambda x,y:x+y,permutate()) will suffice

def permutate(x):return [[x]] if len(x)<2 else [map(lambda X:[x[y]]+X[0],permutate(x[:y]+x[y+1:])) for y in xrange(len(x))]

Of course, one could embed reduce into the definition

def permutate(x):return [x] if len(x)<2 else reduce(lambda x,y:x+y,[map(lambda X:[x[y]]+X,permutate(x[:y]+x[y+1:])) for y in xrange(len(x))])

And so there you have it, the one liner evolved to suit the output of the original solution and is the slowest one around. How I wish it would be the swiftest, so to free me of the guilt of choosing between code size and time size

I think I've embraced recursion. It seems natural, and I've probably used it a few times where iteration would of sufficed

Comments

Mu6502 16 years ago

speed kills.

s 16 years ago

No it doesn't