lib/core/facets/enumerable/permutation.rb in facets-2.1.3 vs lib/core/facets/enumerable/permutation.rb in facets-2.2.0

- old
+ new

@@ -1,45 +1,37 @@ -# TITLE: -# Permutations -# -# DESCRIPTION: -# Enumerble permutation extensions. -# -# AUTHORS: -# - Florian Gross - require 'facets/integer/factorial' -# module Enumerable # Permutation proves the possible orders of an enumerable. # Each is index by a permutation number. The maximum number of # arrangements is the factorial of the size of the array. # - # CREDIT Florian Gross + # CREDIT: Florian Gross def permutation(number) arr = to_a out = arr[0..0] nextfactor = factor = 1 arr.each_with_index {|x,i| case i - when 0: next + when 0 + next else nextfactor = factor * (i+1) out.insert(number % nextfactor / factor, x) factor = nextfactor end } out end - alias :permute :permutation + alias_method :permute, :permutation + # Calculate permutation number. # - # CREDIT Florian Gross + # CREDIT: Florian Gross def permutation_number(original_array=self.to_a.sort) arr = to_a m = 1 v = 0 @@ -64,43 +56,46 @@ # bac # bca # cab # cba # - # CREDIT Florian Gross + # CREDIT: Daniel Sheppard def each_permutation() - arr = to_a - size = arr.size - perm_count = (1...size).inject(0) { |s,x| s + x * x.factorial } - weights = Array.new(size-1) {|i| (i+1).factorial } - s = weights.size - x,i,v,pos = nil - 0.upto(perm_count) do |v| - out = arr[0..0] - arr.each_with_index {|x,i| - case i - when 0: next - when s: out.insert(v / weights[i-1], x) - else out.insert(v % weights[i] / weights[i-1], x) - end - } + pos = Array.new(size) {|i| i} + s = (0...size).to_a.reverse + out = nil + while true + out = [] + pos.each_with_index {|p,i| out.insert(p, self[i]) } yield out + break if s.each do |i| + break if pos[i] > 0 && pos[i] -= 1 + pos[i] = i + end end end - #-- OLD VERSION - #def each_permutation( prefixed=[] ) - # s = self.to_a - # if (length < 2) - # # there are no elements left to permute - # yield(prefixed + self) - # else - # # recursively permute the remaining elements - # s.each_with_index do |e, i| - # (s[0,i]+s[(i+1)..-1]).each_permutation(prefixed+[e]) { |a| yield a } - # end - # end - #end - #++ + # OLD VERSION + # # CREDIT: Florian Gross + # + # def each_permutation() + # arr = to_a + # size = arr.size + # perm_count = (1...size).inject(0) { |s,x| s + x * x.factorial } + # weights = Array.new(size-1) {|i| (i+1).factorial } + # s = weights.size + # x,i,v,pos = nil + # 0.upto(perm_count) do |v| + # out = arr[0..0] + # arr.each_with_index {|x,i| + # case i + # when 0: next + # when s: out.insert(v / weights[i-1], x) + # else out.insert(v % weights[i] / weights[i-1], x) + # end + # } + # yield out + # end + # end end