Skip to content
Permalink
Browse files

Merge pull request #628 from kostya/product

Array#product
  • Loading branch information
alex committed Apr 21, 2013
2 parents daa5616 + 428dfae commit 3d04293f0541ecb73de1f14b066ce30885c0264f
Showing with 64 additions and 30 deletions.
  1. +9 −7 lib-topaz/array.rb
  2. +50 −16 lib-topaz/topaz/array.rb
  3. +0 −7 spec/tags/core/array/product_tags.txt
  4. +5 −0 topaz/modules/topaz.py
@@ -79,14 +79,16 @@ def each(&block)
return self
end

def product(ary)
result = []
self.each do |obj|
ary.each do |other|
result << [obj, other]
end
def product(*args, &block)
args = args.unshift(self)
if block
Topaz::Array.product(args, &block)
self
else
out = self.class.allocate
Topaz::Array.product(args) { |e| out << e }
out
end
result
end

def compact
@@ -1,21 +1,55 @@
module Topaz
class Array
def self.flatten(array, out, level)
modified = nil
Thread.current.recursion_guard(:array_flatten, array) do
array.each do |e|
if level == 0
out << e
elsif e.respond_to?(:to_ary) && ary = ::Array.try_convert(e)
modified = true
flatten(ary, out, level - 1)
else
out << e
end
class Topaz::Array
def self.flatten(array, out, level)
modified = nil
Thread.current.recursion_guard(:array_flatten, array) do
array.each do |e|
if level == 0
out << e
elsif e.respond_to?(:to_ary) && ary = ::Array.try_convert(e)
modified = true
flatten(ary, out, level - 1)
else
out << e
end
return modified
end
raise ArgumentError, "tried to flatten recursive array"
return modified
end
raise ArgumentError, "tried to flatten recursive array"
end

def self.product(args, &block)
arrs, pool, lens = [], [], []
sumlen = 1
args.each do |arr|
arr = Topaz.convert_type(arr, Array, :to_ary)
next unless arr
size = arr.size
return if size == 0
sumlen *= size
arrs << arr
lens << size
pool << arr[0]
end
raise RangeError.new("product result is too large") if sumlen > Topaz::FIXNUM_MAX

yield pool.dup

n = arrs.size
indices = [0] * n

while true do
i = n - 1
indices[i] += 1

while indices[i] >= lens[i] do
indices[i] = 0
pool[i] = arrs[i][indices[i]]
i -= 1
return if i < 0
indices[i] += 1
end
pool[i] = arrs[i][indices[i]]
yield pool.dup
end
end
end

This file was deleted.

@@ -1,4 +1,5 @@
from __future__ import absolute_import
import sys

from rpython.rlib.rarithmetic import intmask

@@ -9,6 +10,10 @@
class Topaz(Module):
moduledef = ModuleDef("Topaz", filepath=__file__)

@moduledef.setup_module
def setup_module(space, w_mod):
space.set_const(w_mod, "FIXNUM_MAX", space.newint(sys.maxint))

@moduledef.function("intmask")
def method_intmask(self, space, w_int):
if space.is_kind_of(w_int, space.w_fixnum):

0 comments on commit 3d04293

Please sign in to comment.
You can’t perform that action at this time.