Sha256: 5ad939fd00c6d726a68a7c271ef7cf87152aaef817f49e45e04f6e3299b5ee8a

Contents?: true

Size: 1.9 KB

Versions: 109

Compression:

Stored size: 1.9 KB

Contents

require 'epitools'

class Array
  
  alias_method :mult, :"*"
  
  #
  # Overloaded * operator.
  #
  # Original behaviour:
  #   array * number == <number> copies of array
  # Extra behaviour:
  #   array * array = Cartesian product of the two arrays
  #
  def *(other)
    if other.is_a? Array
      # cross-product
      result = []
      (0...self.size).each do |a|
        (0...other.size).each do |b|
          result << [self[a], other[b]]
        end
      end
      result
    else
      send(:mult, other)
    end
  end
  
  #
  # Multiply the array by itself 'exponent'-times.
  #
  def **(exponent)
    ([self] * exponent).foldl(:*)
  end
  
  def all_pairs(reflexive=false)
    (0...size).each do |a|
      start = reflexive ? a : a+1
      (start...size).each do |b|
        yield self[a], self[b]
      end
    end
  end
  
  enumerable :all_pairs
  
end


#
# Returns all the `size`-sized selections of the elements from an array.
#
# I can't remember why I wrote it like this, but the array you want to
# permute is passed in as a block. For example:
#
#   >> perms(1) { [1,2,3,4] }
#   => [[1], [2], [3], [4]] 
#   >> perms(2) { [1,2,3,4] }
#   => [[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4],
#       [3, 1], [3, 2], [3, 3], [3, 4], [4, 1], [4, 2], [4, 3], [4, 4]]
#
# The block also gets passed a parameter: the depth of the recursion.
# I can't remember why I did that either! :D
#
def perms(size, n=0, stack=[], &block)
  ps = yield(n)
  results = []
  if n >= size
    results << stack
  else  
    ps.each do |p|
      results += perms(size, n+1, stack + [p], &block)
    end
  end
  results
end
  

if $0 == __FILE__
  puts "-------------- foldl ---"
  p [:sum, [1,1,1].foldl(:+)]
  p ["[[1,2],[3]].foldl(:+)", [[1,2],[3]].foldl(:+)]
  p [[0,1],[0,1]].foldl(:*)

  puts "-------------- cartesian product ---"
  p ["[0,1]*[2,3]",[0,1]*[2,3]]

  puts "-------------- cartesian exponent ---"
  p [0,1]**3
end

Version data entries

109 entries across 109 versions & 1 rubygems

Version Path
epitools-0.5.103 lib/epitools/permutations.rb
epitools-0.5.100 lib/epitools/permutations.rb
epitools-0.5.99 lib/epitools/permutations.rb
epitools-0.5.98 lib/epitools/permutations.rb
epitools-0.5.97 lib/epitools/permutations.rb
epitools-0.5.96 lib/epitools/permutations.rb
epitools-0.5.95 lib/epitools/permutations.rb
epitools-0.5.94 lib/epitools/permutations.rb
epitools-0.5.93 lib/epitools/permutations.rb
epitools-0.5.92 lib/epitools/permutations.rb
epitools-0.5.91 lib/epitools/permutations.rb
epitools-0.5.90 lib/epitools/permutations.rb
epitools-0.5.89 lib/epitools/permutations.rb
epitools-0.5.88 lib/epitools/permutations.rb
epitools-0.5.87 lib/epitools/permutations.rb
epitools-0.5.86 lib/epitools/permutations.rb
epitools-0.5.85 lib/epitools/permutations.rb
epitools-0.5.84 lib/epitools/permutations.rb
epitools-0.5.83 lib/epitools/permutations.rb
epitools-0.5.82 lib/epitools/permutations.rb