e$B1sF#$G$9!#e(B
Array#product e$B$Oe(B Enumerator
e$B$G$J$/G[Ns$rJV$7$^$9$,!“2?$+M}M3$,e(B
e$B$”$C$F$N$3$H$G$7$g$&$+!#e(B
Array#permutation e$B$de(B combination e$B$N$h$&$Ke(B Enumerator
e$B$rJV$7$?J}$,e(B
e$B<+A3$+$DJXMx$@$H;W$$$^$9!#$3$l$i$N%a%=%C%I$Oe(B brute force
e$BE*$JC5:w$Ke(B
e$B$h$/;H$$$^$9$,!"e(Bproduct
e$B$@$1C5:wA0$K5pBg$JG[Ns$r3NJ]$7$F$7$^$&$N$Ge(B
e$B$$$d$i$7$$$G$9!#e(B
e$B;EMMJQ99$K$J$C$F$7$^$$$^$9$,!"0l1~8@$C$F$_$^$7$?!#$I$&$G$7$g$&$+!#e(B
Index: array.c
— array.c (revision 24823)
+++ array.c (working copy)
@@ -3858,30 +3858,35 @@
- call-seq:
-
ary.product(other_ary, ...)
-
- Returns an array of all combinations of elements from all arrays.
-
- The length of the returned array is the product of the length
-
- of ary and the argument arrays
-
- When invoked with a block, yields all combinations of elements
-
- from all arrays.
-
-
[1,2,3].product([4,5]) # =>
-
[[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
-
-
[1,2].product([1,2]) # => [[1,1],[1,2],[2,1],[2,2]]
-
-
-
[1,2].product([3,4],[5,6]) # =>
-
[[1,3,5],[1,3,6],[1,4,5],[1,4,6],
-
-
#
-
[2,3,5],[2,3,6],[2,4,5],[2,4,6]]
-
-
[1,2].product() # => [[1],[2]]
-
-
-
[1,2].product([]) # => []
-
-
- When invoked without a block, returns an enumerator object instead.
-
-
-
[1,2,3].product([4,5]).to_a # =>
-
[[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
-
-
[1,2].product([1,2]).to_a # => [[1,1],[1,2],[2,1],[2,2]]
-
-
-
[1,2].product([3,4],[5,6]).to_a # =>
-
[[1,3,5],[1,3,6],[1,4,5],[1,4,6],
-
-
#
-
[2,3,5],[2,3,6],[2,4,5],[2,4,6]]
-
-
[1,2].product().to_a # => [[1],[2]]
-
-
-
[1,2].product([]).to_a # => []
-
static VALUE
rb_ary_product(int argc, VALUE argv, VALUE ary)
{
int n = argc+1; / How many arrays we’re operating on */
- volatile VALUE t0 = tmpbuf(n, sizeof(VALUE));
- volatile VALUE t1 = tmpbuf(n, sizeof(int));
- VALUE arrays = (VALUE)RSTRING_PTR(t0); /* The arrays we’re
computing the product of */ - int counters = (int)RSTRING_PTR(t1); /* The current position in
each one */ - VALUE result; /* The array we’ll be returning */
-
volatile VALUE t0, t1;
-
VALUE *arrays;
-
int *counters;
long i,j;
long resultlen = 1; -
RETURN_ENUMERATOR(ary, argc, argv);
-
t0 = tmpbuf(n, sizeof(VALUE));
-
t1 = tmpbuf(n, sizeof(int));
-
arrays = (VALUE*)RSTRING_PTR(t0); /* The arrays we’re computing
the product of */ -
counters = (int*)RSTRING_PTR(t1); /* The current position in each
one */ -
RBASIC(t0)->klass = 0;
RBASIC(t1)->klass = 0;
@@ -3903,7 +3908,6 @@
}
/* Otherwise, allocate and fill in an array of results */
- result = rb_ary_new2(resultlen);
for (i = 0; i < resultlen; i++) {
int m;
/* fill in one subarray */
@@ -3913,7 +3917,7 @@
}
/* put it on the result array */
- rb_ary_push(result, subarray);
-
rb_yield(subarray);
/*
- Increment the last counter. If it overflows, reset to 0
@@ -3930,7 +3934,7 @@
tmpbuf_discard(t0);
tmpbuf_discard(t1);
- Increment the last counter. If it overflows, reset to 0
- return result;
- return ary;
}
/*
Index: test/ruby/test_array.rb
— test/ruby/test_array.rb (revision 24823)
+++ test/ruby/test_array.rb (working copy)
@@ -1306,14 +1306,14 @@
def test_product
assert_equal(@cls[[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]],
-
@cls[1,2,3].product([4,5]).to_a)
-
assert_equal(@cls[[1,1],[1,2],[2,1],[2,2]],
@cls[1,2].product([1,2]).to_a)assert_equal(@cls[[1,3,5],[1,3,6],[1,4,5],[1,4,6],
[2,3,5],[2,3,6],[2,4,5],[2,4,6]],
-
@cls[1,2].product([3,4],[5,6]))
- assert_equal(@cls[[1],[2]], @cls[1,2].product)
- assert_equal(@cls[], @cls[1,2].product([]))
-
@cls[1,2].product([3,4],[5,6]).to_a)
- assert_equal(@cls[[1],[2]], @cls[1,2].product.to_a)
- assert_equal(@cls[], @cls[1,2].product([]).to_a)
end
def test_permutation