Search code examples
rubyrecursionidioms

Idiomatic ruby for generating permutations?


I'm wondering what the idiomatic version of this function for generating permutations would look like in Ruby. I understand that [1,2,3].permutation.to_a will generate the same result, but I'm more interested in learning Ruby and how to approach a recursive problem like this in Ruby.

def permutations(seq)
    if seq.empty? || seq.count == 1
        seq
    else
        seq.map { |x|
            permutations(seq.select { |e| e != x }).map { |p|
                if p.class == Fixnum
                    [x, p]
                else
                    p.unshift(x)
                end
            }
        }.flatten(1)
    end
end

Thanks!


Solution

  • class Array
      def permutations
        return [self] if size < 2
        perm = []
        each { |e| (self - [e]).permutations.each { |p| perm << ([e] + p) } }
        perm
      end
    end 
    
    [1, 2, 3].permutations #=> [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] 
    

    Source: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/32844

    Edit: To avoid monkey-patching, put it into a module:

    module ArrayExtensions
      def permutations
        #snip
      end
    end
    
    Array.send :include, ArrayExtensions