instance method
Array#repeated_permutation
(::int n) { (::Array[Elem] p) -> void } -> self
(::int n) -> ::Enumerator[::Array[Elem], self]
repeated_permutation(size) {|permutation| ... } → self
repeated_permutation(size) → new_enumerator
array.c
View on GitHub ↗
static VALUE
rb_ary_repeated_permutation(VALUE ary, VALUE num)
{
long r, n, i;
n = RARRAY_LEN(ary); /* Array length */
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_permutation_size); /* Return Enumerator if no block */
r = NUM2LONG(num); /* Permutation size from argument */
if (r < 0) {
/* no permutations: yield nothing */
}
else if (r == 0) { /* exactly one permutation: the zero-length array */
rb_yield(rb_ary_new2(0));
}
else if (r == 1) { /* this is a special, easy case */
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
}
}
else { /* this is the general case */
volatile VALUE t0;
long *p = ALLOCV_N(long, t0, r);
VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
RBASIC_CLEAR_CLASS(ary0);
rpermute0(n, r, p, ary0); /* compute and yield repeated permutations */
ALLOCV_END(t0);
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
With a block given, calls the block with each repeated permutation of length size of the elements of self; each permutation is an array; returns self. The order of the permutations is indeterminate.
If a positive integer argument size is given, calls the block with each size-tuple repeated permutation of the elements of self. The number of permutations is self.size**size.
Examples:
-
sizeis 1:Examplep = [] [0, 1, 2].repeated_permutation(1) {|permutation| p.push(permutation) } p # => [[0], [1], [2]]
-
sizeis 2:Examplep = [] [0, 1, 2].repeated_permutation(2) {|permutation| p.push(permutation) } p # => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
If size is zero, calls the block once with an empty array.
If size is negative, does not call the block:
Example
[0, 1, 2].repeated_permutation(-1) {|permutation| fail 'Cannot happen' }
With no block given, returns a new Enumerator.
Related: see Methods for Combining.