{{ message }}

# topazproject / topaz

Merge pull request #720 from kostya/permutation2

`Array permutations`
alex committed May 20, 2013
2 parents 97c4cc3 + fbcdc25 commit 925e6b02211cb65eadcbdaafe2daac5f61597751
 @@ -396,4 +396,32 @@ def -(other) other.each { |e| h[e] = true } self.reject { |e| h.has_key?(e) } end def permutation(r = nil, &block) return self.enum_for(:permutation, r) unless block r = r ? Topaz.convert_type(r, Fixnum, :to_int) : self.size Topaz::Array.permutation(self, r, &block) self end def combination(r = nil, &block) return self.enum_for(:combination, r) unless block r = r ? Topaz.convert_type(r, Fixnum, :to_int) : self.size Topaz::Array.combination(self, r, &block) self end def repeated_combination(r, &block) return self.enum_for(:repeated_combination, r) unless block r = Topaz.convert_type(r, Fixnum, :to_int) Topaz::Array.repeated_combination(self, r, &block) self end def repeated_permutation(r, &block) return self.enum_for(:repeated_permutation, r) unless block r = Topaz.convert_type(r, Fixnum, :to_int) Topaz::Array.repeated_permutation(self, r, &block) self end end
 @@ -32,11 +32,11 @@ def self.product(args, &block) end raise RangeError.new("product result is too large") if sumlen > Topaz::FIXNUM_MAX yield pool.dup n = arrs.size indices =  * n yield pool[0, n] while true do i = n - 1 indices[i] += 1 @@ -49,7 +49,119 @@ def self.product(args, &block) indices[i] += 1 end pool[i] = arrs[i][indices[i]] yield pool.dup yield pool[0, n] end end def self.permutation(iterable, r, &block) n = iterable.size return if r > n || r < 0 pool = iterable.dup cycles = (n - r + 1..n).to_a.reverse yield pool[0, r] while true stop = true i = r - 1 while i >= 0 cycles[i] -= 1 if cycles[i] == 0 e = pool[i] j = i + 1 while j < n pool[j - 1] = pool[j] j += 1 end pool[n - 1] = e cycles[i] = n - i else j = cycles[i] pool[i], pool[-j] = pool[-j], pool[i] yield pool[0, r] stop = false break end i -= 1 end return if stop end end def self.combination(iterable, r, &block) n = iterable.size return if r > n || r < 0 copy = iterable.dup pool = iterable.dup indices = (0...r).to_a yield pool[0, r] while true stop = true i = r - 1 while i >= 0 if indices[i] != i + n - r stop = false break end i -= 1 end return if stop indices[i] += 1 pool[i] = copy[indices[i]] j = i + 1 while j < r indices[j] = indices[j - 1] + 1 pool[j] = copy[indices[j]] j += 1 end yield pool[0, r] end end def self.repeated_combination(iterable, r, &block) n = iterable.size return if r < 0 || (n < r && n == 0) copy = iterable.dup indices =  * r pool = indices.map { |i| copy[i] } yield pool[0, r] while true stop = true i = r - 1 while i >= 0 if indices[i] != n - 1 stop = false break end i -= 1 end return if stop ii = indices[i] j = i while j < r indices[j] = ii + 1 pool[j] = copy[ii + 1] j += 1 end yield pool[0, r] end end def self.repeated_permutation(iterable, r, &block) n = iterable.size return if r < 0 || (r != 0 && n == 0) if r == 0 yield [] else product([iterable.dup] * r, &block) end end end

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.