static mrb_value mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) { mrb_int i; mt_state *random = NULL; if (RARRAY_LEN(ary) > 1) { mrb_get_args(mrb, "|d", &random, &mt_state_type); if (random == NULL) { random = get_random_state(mrb); } mrb_random_rand_seed(mrb, random); mrb_ary_modify(mrb, mrb_ary_ptr(ary)); for (i = RARRAY_LEN(ary) - 1; i > 0; i--) { mrb_int j; mrb_value tmp; j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary)))); tmp = RARRAY_PTR(ary)[i]; mrb_ary_ptr(ary)->ptr[i] = RARRAY_PTR(ary)[j]; mrb_ary_ptr(ary)->ptr[j] = tmp; } } return ary; }
static mrb_value mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) { mrb_int i; mrb_value random = mrb_nil_value(); if (RARRAY_LEN(ary) > 1) { mrb_get_args(mrb, "|o", &random); if( mrb_nil_p(random) ) { mrb_random_g_rand_seed(mrb); } else { mrb_data_check_type(mrb, random, &mt_state_type); mrb_random_rand_seed(mrb, random); } mrb_ary_modify(mrb, mrb_ary_ptr(ary)); for (i = RARRAY_LEN(ary) - 1; i > 0; i--) { mrb_int j; if( mrb_nil_p(random) ) { j = mrb_fixnum(mrb_random_mt_g_rand(mrb, mrb_fixnum_value(RARRAY_LEN(ary)))); } else { j = mrb_fixnum(mrb_random_mt_rand(mrb, DATA_PTR(random), mrb_fixnum_value(RARRAY_LEN(ary)))); } mrb_value t = RARRAY_PTR(ary)[i]; RARRAY_PTR(ary)[i] = RARRAY_PTR(ary)[j]; RARRAY_PTR(ary)[j] = t; } } return ary; }
static mrb_value mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) { mrb_int i; mt_state *random = NULL; if (RARRAY_LEN(ary) > 1) { mrb_get_args(mrb, "|d", &random, &mt_state_type); if (random == NULL) { mrb_value random_val = mrb_const_get(mrb, mrb_obj_value(mrb_class_get(mrb, "Random")), mrb_intern_lit(mrb, "DEFAULT")); random = (mt_state *)DATA_PTR(random_val); } mrb_random_rand_seed(mrb, random); mrb_ary_modify(mrb, mrb_ary_ptr(ary)); for (i = RARRAY_LEN(ary) - 1; i > 0; i--) { mrb_int j; mrb_value tmp; j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary)))); tmp = RARRAY_PTR(ary)[i]; RARRAY_PTR(ary)[i] = RARRAY_PTR(ary)[j]; RARRAY_PTR(ary)[j] = tmp; } } return ary; }
static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self) { mrb_value max; mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state); max = get_opt(mrb); mrb_random_rand_seed(mrb, t); return mrb_random_mt_rand(mrb, t, max); }
static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self) { mrb_value max; mt_state *t = DATA_PTR(self); max = get_opt(mrb); mrb_random_rand_seed(mrb, self); return mrb_random_mt_rand(mrb, t, max); }
static mrb_value mrb_ary_sample(mrb_state *mrb, mrb_value ary) { mrb_int n = 0; mrb_bool given; mt_state *random = NULL; mrb_int len = RARRAY_LEN(ary); mrb_get_args(mrb, "|i?d", &n, &given, &random, &mt_state_type); if (random == NULL) { random = get_random_state(mrb); } mrb_random_rand_seed(mrb, random); mt_rand(random); if (!given) { /* pick one element */ switch (len) { case 0: return mrb_nil_value(); case 1: return RARRAY_PTR(ary)[0]; default: return RARRAY_PTR(ary)[mt_rand(random) % len]; } } else { mrb_value result; mrb_int i, j; if (n < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "negative sample number"); if (n > len) n = len; result = mrb_ary_new_capa(mrb, n); for (i=0; i<n; i++) { mrb_int r; for (;;) { retry: r = mt_rand(random) % len; for (j=0; j<i; j++) { if (mrb_fixnum(RARRAY_PTR(result)[j]) == r) { goto retry; /* retry if duplicate */ } } break; } RARRAY_PTR(result)[i] = mrb_fixnum_value(r); RARRAY_LEN(result)++; } for (i=0; i<n; i++) { RARRAY_PTR(result)[i] = RARRAY_PTR(ary)[mrb_fixnum(RARRAY_PTR(result)[i])]; } return result; } }