End of Life Ruby 3.1 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →
Array#repeated_combination
static VALUE
rb_ary_repeated_combination(VALUE ary, VALUE num)
{
long n, i, len;
n = NUM2LONG(num); /* Combination size from argument */
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size); /* Return enumerator if no block */
len = RARRAY_LEN(ary);
if (n < 0) {
/* yield nothing */
}
else if (n == 0) {
rb_yield(rb_ary_new2(0));
}
else if (n == 1) {
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
}
}
else if (len == 0) {
/* yield nothing */
}
else {
volatile VALUE t0;
long *p = ALLOCV_N(long, t0, n);
VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
RBASIC_CLEAR_CLASS(ary0);
rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */
ALLOCV_END(t0);
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
}
return ary;
}
Calls the block with each repeated combination of length n of the elements of self; each combination is an Array; returns self. The order of the combinations is indeterminate.
When a block and a positive Integer argument n are given, calls the block with each n-tuple repeated combination of the elements of self. The number of combinations is (n+1)(n+2)/2.
n = 1:
a = [0, 1, 2] a.repeated_combination(1) {|combination| p combination }
Output:
[0] [1] [2]
n = 2:
a.repeated_combination(2) {|combination| p combination }
Output:
[0, 0] [0, 1] [0, 2] [1, 1] [1, 2] [2, 2]
If n is zero, calls the block once with an empty Array.
If n is negative, does not call the block:
a.repeated_combination(-1) {|combination| fail 'Cannot happen' }
Returns a new Enumerator if no block given:
a = [0, 1, 2] a.repeated_combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)>
Using Enumerators, it’s convenient to show the combinations and counts for some values of n:
e = a.repeated_combination(0) e.size # => 1 e.to_a # => [[]] e = a.repeated_combination(1) e.size # => 3 e.to_a # => [[0], [1], [2]] e = a.repeated_combination(2) e.size # => 6 e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]]