Module: Cartesian

Defined in:
lib/cartesian.rb,
lib/cartesian/version.rb

Overview

:nodoc:

Defined Under Namespace

Modules: VERSION

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.joined_product(first, second) ⇒ Object

Behaves as product, except for the elements are joined.

Cartesian::joined_cartesian( [1,2], %w(A B) ) #=> ["1A", "1B", "2A", "2B"]

or, if mixed in into Array,

[1,2].joined_cartesian %w(A B) #=> ["1A", "1B", "2A", "2B"]


65
66
67
# File 'lib/cartesian.rb', line 65

def Cartesian.joined_product(first, second)
  product(first, second).map {|pair| pair.join }
end

.product(first, second) ⇒ Object

Produces the cartesian product of self and other. The result is an array of pairs (i.e. two-element arrays).

Cartesian::product( [1,2], %w(A B) ) #=> [[1, "A"], [1, "B"], [2, "A"], [2, "B"]]

or, if mixed in into Array,

[1,2].cartesian %w(A B) #=> [[1, "A"], [1, "B"], [2, "A"], [2, "B"]]


53
54
55
# File 'lib/cartesian.rb', line 53

def Cartesian.product(first, second)
  first.x(second).to_a
end

Instance Method Details

#**(fixnum) ⇒ Object Also known as: power!

Concise way of iterating multi-dimensionally over the same array or range.

For instance,

for x,y,z in [0,1]**3
  puts [x, y, z].join(',')
end

produces the following output

0,0,0
0,0,1
0,1,0
0,1,1
1,0,0
1,0,1
1,1,0
1,1,1

It also works with Range objects.



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/cartesian.rb', line 143

def **(fixnum)
  if fixnum < 0
    raise ArgumentError, "negative power"
  elsif fixnum == 0
    return []
  elsif fixnum == 1
    return self
  else
    iter = CartesianIterator.new(self, self)
    (fixnum-2).times do
      iter.product!(self)
    end
    iter
  end
end

#joined_cartesian(other) ⇒ Object

Cartesian.joined_product for mixin.



71
72
73
# File 'lib/cartesian.rb', line 71

def joined_cartesian(other)
  Cartesian.joined_product(self, other)
end

#left_product(other) ⇒ Object



112
113
114
115
116
117
118
119
# File 'lib/cartesian.rb', line 112

def left_product(other)
  case other
  when CartesianIterator
    other.right_product(self)
  else
    CartesianIterator.new(other, self)
  end
end

#x(other) ⇒ Object Also known as: cartesian, right_product

Convenient way of iterating over the elements. Preferable when the cartesian product array is not needed, for the consumption of memory is fixed and very small, in contrast with the exponential memory requirements of the conventional approach.

for row, col in (1..10).x(1..30)
  Matrix[row, col] = row**2 + col**3
end

Of course, calls can be chained as in

for x, y, z in (1..10).x(1..10).x(1..10)
  # ... do something ...
end

for letter, number in %w{a b c}.x(1..3)
  ... do something ...
end

++

Beware that both self and other must implement to_a, i.e., be convertible to array.



101
102
103
104
105
106
107
108
# File 'lib/cartesian.rb', line 101

def x(other)
  case other
  when CartesianIterator
    other.left_product(self)
  else
    CartesianIterator.new(self, other)
  end
end