4049 
4049 
return result;

4050 
4050 
}

4051 
4051 


4052 
/*


4053 
* callseq:


4054 
* ary.sample! > obj


4055 
* ary.sample!(random: rng) > obj


4056 
* ary.sample!(n) > new_ary


4057 
* ary.sample!(n, random: rng) > new_ary


4058 
*


4059 
* Choose and delete a random element or +n+ random elements from the array. The elements


4060 
* are chosen by using random and unique indices into the array in order to


4061 
* ensure that an element doesn't repeat itself unless the array already


4062 
* contained duplicate elements. If the array is empty the first form returns


4063 
* <code>nil</code> and the second form returns an empty array.


4064 
*


4065 
* If +rng+ is given, it will be used as the random number generator.


4066 
*/


4067 


4068 
static VALUE


4069 
rb_ary_sample_bang(int argc, VALUE *argv, VALUE ary)


4070 
{


4071 
VALUE nv, result, *ptr_result;


4072 
VALUE opts, randgen = rb_cRandom;


4073 
VALUE a, b, c;


4074 
long n, len, i, j, k;


4075 
double rnds[3];


4076 


4077 
if (OPTHASH_GIVEN_P(opts)) {


4078 
randgen = rb_hash_lookup2(opts, sym_random, randgen);


4079 
}


4080 
len = RARRAY_LEN(ary);


4081 
if (argc == 0) {


4082 
if (len == 0) return Qnil;


4083 
if (len == 1) {


4084 
i = 0;


4085 
}


4086 
else {


4087 
double x = rb_random_real(randgen);


4088 
if (len == 0) return Qnil;


4089 
i = (long)(x * len);


4090 
}


4091 
return rb_ary_delete_at(ary, i);


4092 
}


4093 
rb_scan_args(argc, argv, "1", &nv);


4094 
n = NUM2LONG(nv);


4095 
if (n < 0) rb_raise(rb_eArgError, "negative sample number");


4096 
if (n > len) n = len;


4097 
if (n <= numberof(rnds)) {


4098 
for (i = 0; i < n; ++i) {


4099 
rnds[i] = rb_random_real(randgen);


4100 
}


4101 
}


4102 
switch (n) {


4103 
case 0:


4104 
return rb_ary_new2(0);


4105 
case 1:


4106 
i = (long)(rnds[0] * len);


4107 
return rb_ary_new3(1, rb_ary_delete_at(ary, i));


4108 
case 2:


4109 
i = (long)(rnds[0] * len);


4110 
j = (long)(rnds[1] * (len1));


4111 
a = rb_ary_delete_at(ary, i);


4112 
b = rb_ary_delete_at(ary, j);


4113 
return rb_ary_new3(2, a, b);


4114 
case 3:


4115 
i = (long)(rnds[0] * len);


4116 
j = (long)(rnds[1] * (len1));


4117 
k = (long)(rnds[2] * (len2));


4118 
a = rb_ary_delete_at(ary, i);


4119 
b = rb_ary_delete_at(ary, j);


4120 
c = rb_ary_delete_at(ary, k);


4121 
return rb_ary_new3(3, a, b, c);


4122 
}


4123 
result = rb_ary_new2(n);


4124 
ptr_result = RARRAY_PTR(result);


4125 
for (i=0; i<n; i++) {


4126 
j = (long)(rb_random_real(randgen) * len);


4127 
ptr_result[i] = rb_ary_delete_at(ary, j);


4128 
}


4129 
ARY_SET_LEN(result, n);


4130 


4131 
return result;


4132 
}

4052 
4133 

4053 
4134 
/*

4054 
4135 
* callseq:

...  ...  
4998 
5079 
rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, 1);

4999 
5080 
rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, 1);

5000 
5081 
rb_define_method(rb_cArray, "sample", rb_ary_sample, 1);


5082 
rb_define_method(rb_cArray, "sample!", rb_ary_sample_bang, 1);

5001 
5083 
rb_define_method(rb_cArray, "cycle", rb_ary_cycle, 1);

5002 
5084 
rb_define_method(rb_cArray, "permutation", rb_ary_permutation, 1);

5003 
5085 
rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
