Exemplo n.º 1
0
Arquivo: random.c Projeto: ASnow/mruby
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;
}
Exemplo n.º 2
0
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;
  }
}