0a5eb48929f4014d1a1bf448517158d5

Originally published at http://www.dorkalev.com/2009/06/erlang-riddle-for-rubists.html

In the book Software for a Concurrent World, Joe Armstrong gives an example of a function that returns all permutations of a given string.

perms([]) -> [[]];
perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].

I have tried to rewrite it in Ruby, in a form that would mostly imitate what's done here.
That's my best try so far.

I hate the flatten hack I did there to simulate Erlang's valuse return as one Array.
I dislike having to send prem all his recursive "past" (as "nx").

I think there must be a better way to do it. A better way that will deliver the Erlangian concepts.
Do you think you might have a better way to pronounce the Erlangian magic of this function in Rubish ? If so, please post it here (as a comment) I'd really love to see it!

Whoever has a better solution (me need to like) will get full credits on my blog and endless honor (!)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def prem(s,nx = [])
  return nx.join if s.empty?
  s.collect { |b| prem(s-[b],nx+[b]) }.flatten
end

puts prem('dor'.split(//))

output:

dor
dro
odr
ord
rdo
rod

Refactorings

No refactoring yet !

Avatar

bob

June 13, 2009, June 13, 2009 08:19, permalink

No rating. Login to rate!

Luckily for you, they added a "permutation" method to Array in Ruby 1.8.7 / 1.9

1
'dor'.split('').permutation.each { |x| puts x.join }
0a5eb48929f4014d1a1bf448517158d5

dorkalev

June 13, 2009, June 13, 2009 08:25, permalink

No rating. Login to rate!

man, you loose all the fun of this task that way - though I DO LIKE YOUR WAY OF THINKING! ;-)

A8d3f35baafdaea851914b17dae9e1fc

Adam

June 13, 2009, June 13, 2009 20:49, permalink

No rating. Login to rate!
1
2
3
4
5
6
7
8
class Array
  def permutation
    return [self] if size < 2
    inject([]) do |array,element|
      array + (self - [element]).permutation.map { |object| [element] + object }
    end
  end
end

Your refactoring





Format Copy from initial code

or Cancel