From 3997d24a012f3a0c364d3c551b4d8b38b3443676 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Thu, 28 Jan 2010 11:53:12 +0900 Subject: [PATCH] * array.c (rb_ary_permutation, rb_ary_combiation), test/ruby/test_array.rb (TestArray#test_permutation_length, TestArray#test_combination_length): length method was added for an enumerator generated by Array#permutation and Array#combination. --- ChangeLog | 7 +++++++ array.c | 17 ++++++++++++++--- test/ruby/test_array.rb | 13 +++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 639993a..ed66eb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Thu Jan 28 11:48:00 Kenta Murata + + * array.c (rb_ary_permutation, rb_ary_combiation), test/ruby/test_array.rb + (TestArray#test_permutation_length, TestArray#test_combination_length): + length method was added for an enumerator generated by Array#permutation + and Array#combination. + Thu Jan 28 09:44:19 2010 NARUSE, Yui * regcomp.c (onig_compile): initialize ScanEnv. diff --git a/array.c b/array.c index b844d0c..77d3eda 100644 --- a/array.c +++ b/array.c @@ -3853,10 +3853,15 @@ rb_ary_permutation(int argc, VALUE *argv, VALUE ary) long r, n, i; n = RARRAY_LEN(ary); /* Array length */ - RETURN_ENUMERATOR(ary, argc, argv); /* Return enumerator if no block */ rb_scan_args(argc, argv, "01", &num); r = NIL_P(num) ? n : NUM2LONG(num); /* Permutation size from argument */ - + if (!rb_block_given_p()) { + VALUE enu = rb_enumeratorize(ary, ID2SYM(rb_frame_this_func()), argc, argv); + long nlen = (r == 0) ? 1 : (r == 1) ? n : (r <= n) ? (r-1)*n : 0; + rb_iv_set(enu, "@length", LONG2NUM(nlen)); + rb_define_attr(rb_singleton_class(enu), "length", 1, 0); + return enu; + } if (r < 0 || n < r) { /* no permutations: yield nothing */ } @@ -3936,8 +3941,14 @@ rb_ary_combination(VALUE ary, VALUE num) long n, i, len; n = NUM2LONG(num); - RETURN_ENUMERATOR(ary, 1, &num); len = RARRAY_LEN(ary); + if (!rb_block_given_p()) { + VALUE enu = rb_enumeratorize(ary, ID2SYM(rb_frame_this_func()), 1, &num); + long nlen = combi_len(len, n); + rb_iv_set(enu, "@length", LONG2NUM(nlen)); + rb_define_attr(rb_singleton_class(enu), "length", 1, 0); + return enu; + } if (n < 0 || len < n) { /* yield nothing */ } diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index f05c9e4..12af5b7 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1355,6 +1355,11 @@ class TestArray < Test::Unit::TestCase assert_equal(@cls[], @cls[1,2,3,4].combination(5).to_a) end + def test_combination_length + assert_equal(6, @cls[1,2,3,4].combination(2).length) + assert_equal(4, @cls[1,2,3,4].combination(3).length) + end + 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])) @@ -1388,6 +1393,14 @@ class TestArray < Test::Unit::TestCase assert_equal(@cls[1, 2, 3, 4].permutation.to_a, b) end + def test_permutation_length + assert_equal(6, @cls[1, 2, 3].permutation.length) + assert_equal(1, @cls[1, 2, 3].permutation(0).length) + assert_equal(3, @cls[1, 2, 3].permutation(1).length) + assert_equal(6, @cls[1, 2, 3].permutation(3).length) + assert_equal(0, @cls[1, 2, 3].permutation(4).length) + end + def test_take assert_equal([1,2,3], [1,2,3,4,5,0].take(3)) assert_raise(ArgumentError, '[ruby-dev:34123]') { [1,2].take(-1) } -- 1.6.4.4