mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* array.c (rb_ary_permutation): Remove limitation for lengthy permutations
[ruby-core:29240] * test/ruby/test_array.rb: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27252 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
ceb62c31a1
commit
f3d2f9e4d1
3 changed files with 13 additions and 25 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Wed Apr 8 02:33:55 2010 Marc-Andre Lafortune <ruby-core@marc-andre.ca>
|
||||||
|
|
||||||
|
* array.c (rb_ary_permutation): Remove limitation for lengthy permutations
|
||||||
|
[ruby-core:29240]
|
||||||
|
|
||||||
|
* test/ruby/test_array.rb: ditto
|
||||||
|
|
||||||
Wed Apr 7 23:33:55 2010 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
Wed Apr 7 23:33:55 2010 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
|
||||||
|
|
||||||
* misc/ruby-mode.el (ruby-mode-map): binded C-c C-c and C-c C-c C-u
|
* misc/ruby-mode.el (ruby-mode-map): binded C-c C-c and C-c C-c C-u
|
||||||
|
|
27
array.c
27
array.c
|
@ -3958,26 +3958,6 @@ rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long
|
|
||||||
combi_len(long n, long k)
|
|
||||||
{
|
|
||||||
long i, val = 1;
|
|
||||||
|
|
||||||
if (k*2 > n) k = n-k;
|
|
||||||
if (k == 0) return 1;
|
|
||||||
if (k < 0) return 0;
|
|
||||||
val = 1;
|
|
||||||
for (i=1; i <= k; i++,n--) {
|
|
||||||
long m = val;
|
|
||||||
val *= n;
|
|
||||||
if (val < m) {
|
|
||||||
rb_raise(rb_eRangeError, "too big for combination");
|
|
||||||
}
|
|
||||||
val /= i;
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* ary.combination(n) { |c| block } -> ary
|
* ary.combination(n) { |c| block } -> ary
|
||||||
|
@ -4024,14 +4004,13 @@ rb_ary_combination(VALUE ary, VALUE num)
|
||||||
else {
|
else {
|
||||||
volatile VALUE t0 = tmpbuf(n+1, sizeof(long));
|
volatile VALUE t0 = tmpbuf(n+1, sizeof(long));
|
||||||
long *stack = (long*)RSTRING_PTR(t0);
|
long *stack = (long*)RSTRING_PTR(t0);
|
||||||
long nlen = combi_len(len, n);
|
|
||||||
volatile VALUE cc = tmpary(n);
|
volatile VALUE cc = tmpary(n);
|
||||||
VALUE *chosen = RARRAY_PTR(cc);
|
VALUE *chosen = RARRAY_PTR(cc);
|
||||||
long lev = 0;
|
long lev = 0;
|
||||||
|
|
||||||
MEMZERO(stack, long, n);
|
MEMZERO(stack, long, n);
|
||||||
stack[0] = -1;
|
stack[0] = -1;
|
||||||
for (i = 0; i < nlen; i++) {
|
for (;;) {
|
||||||
chosen[lev] = RARRAY_PTR(ary)[stack[lev+1]];
|
chosen[lev] = RARRAY_PTR(ary)[stack[lev+1]];
|
||||||
for (lev++; lev < n; lev++) {
|
for (lev++; lev < n; lev++) {
|
||||||
chosen[lev] = RARRAY_PTR(ary)[stack[lev+1] = stack[lev]+1];
|
chosen[lev] = RARRAY_PTR(ary)[stack[lev+1] = stack[lev]+1];
|
||||||
|
@ -4041,9 +4020,11 @@ rb_ary_combination(VALUE ary, VALUE num)
|
||||||
rb_raise(rb_eRuntimeError, "combination reentered");
|
rb_raise(rb_eRuntimeError, "combination reentered");
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
if (lev == 0) goto done;
|
||||||
stack[lev--]++;
|
stack[lev--]++;
|
||||||
} while (lev && (stack[lev+1]+n == len+lev+1));
|
} while (stack[lev+1]+n == len+lev+1);
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
tmpbuf_discard(t0);
|
tmpbuf_discard(t0);
|
||||||
tmpary_discard(cc);
|
tmpary_discard(cc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1842,8 +1842,8 @@ class TestArray < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_combination2
|
def test_combination2
|
||||||
assert_raise(RangeError) do
|
assert_nothing_raised do
|
||||||
(0..100).to_a.combination(50) {}
|
(0..100).to_a.combination(50) { break }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue