array.c: combinate0
* array.c (combinate0): extract. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46425 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9729275473
commit
02725fb682
40
array.c
40
array.c
@ -4884,6 +4884,27 @@ rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
|
|||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
combinate0(const long len, const long n, long *const stack, const VALUE values)
|
||||||
|
{
|
||||||
|
long lev = 0;
|
||||||
|
|
||||||
|
MEMZERO(stack+1, long, n);
|
||||||
|
stack[0] = -1;
|
||||||
|
for (;;) {
|
||||||
|
for (lev++; lev < n; lev++) {
|
||||||
|
stack[lev+1] = stack[lev]+1;
|
||||||
|
}
|
||||||
|
if (!yield_indexed_values(values, n, stack+1)) {
|
||||||
|
rb_raise(rb_eRuntimeError, "combination reentered");
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
if (lev == 0) return;
|
||||||
|
stack[lev--]++;
|
||||||
|
} while (stack[lev+1]+n == len+lev+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
|
rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
|
||||||
{
|
{
|
||||||
@ -4921,7 +4942,7 @@ rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_ary_combination(VALUE ary, VALUE num)
|
rb_ary_combination(VALUE ary, VALUE num)
|
||||||
{
|
{
|
||||||
long n, i, len;
|
long i, n, len;
|
||||||
|
|
||||||
n = NUM2LONG(num);
|
n = NUM2LONG(num);
|
||||||
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
|
RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
|
||||||
@ -4941,24 +4962,9 @@ rb_ary_combination(VALUE ary, VALUE num)
|
|||||||
VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
|
VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
|
||||||
volatile VALUE t0;
|
volatile VALUE t0;
|
||||||
long *stack = ALLOCV_N(long, t0, n+1);
|
long *stack = ALLOCV_N(long, t0, n+1);
|
||||||
long lev = 0;
|
|
||||||
|
|
||||||
RBASIC_CLEAR_CLASS(ary0);
|
RBASIC_CLEAR_CLASS(ary0);
|
||||||
MEMZERO(stack+1, long, n);
|
combinate0(len, n, stack, ary0);
|
||||||
stack[0] = -1;
|
|
||||||
for (;;) {
|
|
||||||
for (lev++; lev < n; lev++) {
|
|
||||||
stack[lev+1] = stack[lev]+1;
|
|
||||||
}
|
|
||||||
if (!yield_indexed_values(ary0, n, stack+1)) {
|
|
||||||
rb_raise(rb_eRuntimeError, "combination reentered");
|
|
||||||
}
|
|
||||||
do {
|
|
||||||
if (lev == 0) goto done;
|
|
||||||
stack[lev--]++;
|
|
||||||
} while (stack[lev+1]+n == len+lev+1);
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
ALLOCV_END(t0);
|
ALLOCV_END(t0);
|
||||||
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
|
RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user