Advertisement
Guest User

Untitled

a guest
Dec 21st, 2014
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.55 KB | None | 0 0
  1.  
  2. 16,22c16
  3. < #define GLOBAL_RAND_SEED_KEY "$mrb_g_rand_seed"
  4. < #define GLOBAL_RAND_SEED_KEY_CSTR_LEN 16
  5. <
  6. < #define INSTANCE_RAND_SEED_KEY "$mrb_i_rand_seed"
  7. < #define INSTANCE_RAND_SEED_KEY_CSTR_LEN 16
  8. <
  9. < #define MT_STATE_KEY "$mrb_i_mt_state"
  10. ---
  11. > static char const MT_STATE_KEY[] = "$mrb_i_mt_state";
  12. 28,41c22,23
  13. < static void mt_g_srand(unsigned long seed)
  14. < {
  15. < init_genrand(seed);
  16. < }
  17. <
  18. < static unsigned long mt_g_rand()
  19. < {
  20. < return genrand_int32();
  21. < }
  22. <
  23. < static double mt_g_rand_real()
  24. < {
  25. < return genrand_real1();
  26. < }
  27. ---
  28. > static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self);
  29. > static mrb_value mrb_random_srand(mrb_state *mrb, mrb_value self);
  30. 43,73c25
  31. < static mrb_value
  32. < mrb_random_mt_g_srand(mrb_state *mrb, mrb_value seed)
  33. < {
  34. < if (mrb_nil_p(seed)) {
  35. < seed = mrb_fixnum_value(time(NULL) + mt_g_rand());
  36. < if (mrb_fixnum(seed) < 0) {
  37. < seed = mrb_fixnum_value( 0 - mrb_fixnum(seed));
  38. < }
  39. < }
  40. <
  41. < mt_g_srand((unsigned) mrb_fixnum(seed));
  42. <
  43. < return seed;
  44. < }
  45. <
  46. < static mrb_value
  47. < mrb_random_mt_g_rand(mrb_state *mrb, mrb_value max)
  48. < {
  49. < mrb_value value;
  50. <
  51. < if (mrb_fixnum(max) == 0) {
  52. < value = mrb_float_value(mrb, mt_g_rand_real());
  53. < }
  54. < else {
  55. < value = mrb_fixnum_value(mt_g_rand() % mrb_fixnum(max));
  56. < }
  57. <
  58. < return value;
  59. < }
  60. <
  61. < static void
  62. ---
  63. > static void
  64. 77c29
  65. < }
  66. ---
  67. > }
  68. 79c31
  69. < static unsigned long
  70. ---
  71. > static unsigned long
  72. 83c35
  73. < }
  74. ---
  75. > }
  76. 85c37
  77. < static double
  78. ---
  79. > static double
  80. 89c41
  81. < }
  82. ---
  83. > }
  84. 91c43
  85. < static mrb_value
  86. ---
  87. > static mrb_value
  88. 93c45
  89. < {
  90. ---
  91. > {
  92. 95c47
  93. < seed = mrb_fixnum_value(time(NULL) + mt_rand(t));
  94. ---
  95. > seed = mrb_fixnum_value((mrb_int)(time(NULL) + mt_rand(t)));
  96. 97c49
  97. < seed = mrb_fixnum_value( 0 - mrb_fixnum(seed));
  98. ---
  99. > seed = mrb_fixnum_value(0 - mrb_fixnum(seed));
  100. 106c58
  101. < static mrb_value
  102. ---
  103. > static mrb_value
  104. 108c60
  105. < {
  106. ---
  107. > {
  108. 121c73
  109. < static mrb_value
  110. ---
  111. > static mrb_value
  112. 126c78
  113. < arg = mrb_fixnum_value(0);
  114. ---
  115. > arg = mrb_nil_value();
  116. 141,142c93,101
  117. < static void
  118. < mrb_random_g_rand_seed(mrb_state *mrb)
  119. ---
  120. > static mrb_value
  121. > get_random(mrb_state *mrb) {
  122. > return mrb_const_get(mrb,
  123. > mrb_obj_value(mrb_class_get(mrb, "Random")),
  124. > mrb_intern_lit(mrb, "DEFAULT"));
  125. > }
  126. >
  127. > static mt_state *
  128. > get_random_state(mrb_state *mrb)
  129. 144,149c103,104
  130. < mrb_value seed;
  131. <
  132. < seed = mrb_gv_get(mrb, mrb_intern(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN));
  133. < if (mrb_nil_p(seed)) {
  134. < mrb_random_mt_g_srand(mrb, mrb_nil_value());
  135. < }
  136. ---
  137. > mrb_value random_val = get_random(mrb);
  138. > return DATA_GET_PTR(mrb, random_val, &mt_state_type, mt_state);
  139. 152c107
  140. < static mrb_value
  141. ---
  142. > static mrb_value
  143. 155,159c110,111
  144. < mrb_value max;
  145. <
  146. < max = get_opt(mrb);
  147. < mrb_random_g_rand_seed(mrb);
  148. < return mrb_random_mt_g_rand(mrb, max);
  149. ---
  150. > mrb_value random = get_random(mrb);
  151. > return mrb_random_rand(mrb, random);
  152. 162c114
  153. < static mrb_value
  154. ---
  155. > static mrb_value
  156. 165,172c117,118
  157. < mrb_value seed;
  158. < mrb_value old_seed;
  159. <
  160. < seed = get_opt(mrb);
  161. < seed = mrb_random_mt_g_srand(mrb, seed);
  162. < old_seed = mrb_gv_get(mrb, mrb_intern(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN));
  163. < mrb_gv_set(mrb, mrb_intern(mrb, GLOBAL_RAND_SEED_KEY, GLOBAL_RAND_SEED_KEY_CSTR_LEN), seed);
  164. < return old_seed;
  165. ---
  166. > mrb_value random = get_random(mrb);
  167. > return mrb_random_srand(mrb, random);
  168. 175c121
  169. < static mrb_value
  170. ---
  171. > static mrb_value
  172. 180,183c126
  173. <
  174. < DATA_TYPE(self) = &mt_state_type;
  175. < DATA_PTR(self) = NULL;
  176. <
  177. ---
  178. >
  179. 188c131,132
  180. < }
  181. ---
  182. > }
  183. > mrb_data_init(self, NULL, &mt_state_type);
  184. 195,198c139,149
  185. < mrb_iv_set(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN), seed);
  186. <
  187. < DATA_PTR(self) = t;
  188. <
  189. ---
  190. > if (mrb_nil_p(seed)) {
  191. > t->has_seed = FALSE;
  192. > }
  193. > else {
  194. > mrb_assert(mrb_fixnum_p(seed));
  195. > t->has_seed = TRUE;
  196. > t->seed = mrb_fixnum(seed);
  197. > }
  198. >
  199. > mrb_data_init(self, t, &mt_state_type);
  200. >
  201. 202,203c153,154
  202. < static void
  203. < mrb_random_rand_seed(mrb_state *mrb, mrb_value self)
  204. ---
  205. > static void
  206. > mrb_random_rand_seed(mrb_state *mrb, mt_state *t)
  207. 205,209c156
  208. < mrb_value seed;
  209. < mt_state *t = DATA_PTR(self);
  210. <
  211. < seed = mrb_iv_get(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN));
  212. < if (mrb_nil_p(seed)) {
  213. ---
  214. > if (!t->has_seed) {
  215. 214c161
  216. < static mrb_value
  217. ---
  218. > static mrb_value
  219. 218c165
  220. < mt_state *t = DATA_PTR(self);
  221. ---
  222. > mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);
  223. 221c168
  224. < mrb_random_rand_seed(mrb, self);
  225. ---
  226. > mrb_random_rand_seed(mrb, t);
  227. 225c172
  228. < static mrb_value
  229. ---
  230. > static mrb_value
  231. 230c177
  232. < mt_state *t = DATA_PTR(self);
  233. ---
  234. > mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);
  235. 234,235c181,189
  236. < old_seed = mrb_iv_get(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN));
  237. < mrb_iv_set(mrb, self, mrb_intern(mrb, INSTANCE_RAND_SEED_KEY, INSTANCE_RAND_SEED_KEY_CSTR_LEN), seed);
  238. ---
  239. > old_seed = t->has_seed? mrb_fixnum_value(t->seed) : mrb_nil_value();
  240. > if (mrb_nil_p(seed)) {
  241. > t->has_seed = FALSE;
  242. > }
  243. > else {
  244. > mrb_assert(mrb_fixnum_p(seed));
  245. > t->has_seed = TRUE;
  246. > t->seed = mrb_fixnum(seed);
  247. > }
  248. 251,252c205,206
  249. < mrb_value random = mrb_nil_value();
  250. <
  251. ---
  252. > mt_state *random = NULL;
  253. >
  254. 254c208
  255. < mrb_get_args(mrb, "|o", &random);
  256. ---
  257. > mrb_get_args(mrb, "|d", &random, &mt_state_type);
  258. 256,261c210,211
  259. < if (mrb_nil_p(random)) {
  260. < mrb_random_g_rand_seed(mrb);
  261. < }
  262. < else {
  263. < mrb_data_check_type(mrb, random, &mt_state_type);
  264. < mrb_random_rand_seed(mrb, random);
  265. ---
  266. > if (random == NULL) {
  267. > random = get_random_state(mrb);
  268. 263c213,214
  269. <
  270. ---
  271. > mrb_random_rand_seed(mrb, random);
  272. >
  273. 265c216
  274. <
  275. ---
  276. >
  277. 269,276c220,222
  278. <
  279. < if (mrb_nil_p(random)) {
  280. < j = mrb_fixnum(mrb_random_mt_g_rand(mrb, mrb_fixnum_value(RARRAY_LEN(ary))));
  281. < }
  282. < else {
  283. < j = mrb_fixnum(mrb_random_mt_rand(mrb, DATA_PTR(random), mrb_fixnum_value(RARRAY_LEN(ary))));
  284. < }
  285. <
  286. ---
  287. >
  288. > j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary))));
  289. >
  290. 278,280c224,226
  291. < RARRAY_PTR(ary)[i] = RARRAY_PTR(ary)[j];
  292. < RARRAY_PTR(ary)[j] = tmp;
  293. < }
  294. ---
  295. > mrb_ary_ptr(ary)->ptr[i] = RARRAY_PTR(ary)[j];
  296. > mrb_ary_ptr(ary)->ptr[j] = tmp;
  297. > }
  298. 282c228
  299. <
  300. ---
  301. >
  302. 298c244
  303. <
  304. ---
  305. >
  306. 301a248,317
  307. > /*
  308. > * call-seq:
  309. > * ary.sample -> obj
  310. > * ary.sample(n) -> new_ary
  311. > *
  312. > * Choose a random element or +n+ random elements from the array.
  313. > *
  314. > * The elements are chosen by using random and unique indices into the array
  315. > * in order to ensure that an element doesn't repeat itself unless the array
  316. > * already contained duplicate elements.
  317. > *
  318. > * If the array is empty the first form returns +nil+ and the second form
  319. > * returns an empty array.
  320. > */
  321. >
  322. > static mrb_value
  323. > mrb_ary_sample(mrb_state *mrb, mrb_value ary)
  324. > {
  325. > mrb_int n = 0;
  326. > mrb_bool given;
  327. > mt_state *random = NULL;
  328. > mrb_int len = RARRAY_LEN(ary);
  329. >
  330. > mrb_get_args(mrb, "|i?d", &n, &given, &random, &mt_state_type);
  331. > if (random == NULL) {
  332. > random = get_random_state(mrb);
  333. > }
  334. > mrb_random_rand_seed(mrb, random);
  335. > mt_rand(random);
  336. > if (!given) { /* pick one element */
  337. > switch (len) {
  338. > case 0:
  339. > return mrb_nil_value();
  340. > case 1:
  341. > return RARRAY_PTR(ary)[0];
  342. > default:
  343. > return RARRAY_PTR(ary)[mt_rand(random) % len];
  344. > }
  345. > }
  346. > else {
  347. > mrb_value result;
  348. > mrb_int i, j;
  349. >
  350. > if (n < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "negative sample number");
  351. > if (n > len) n = len;
  352. > result = mrb_ary_new_capa(mrb, n);
  353. > for (i=0; i<n; i++) {
  354. > mrb_int r;
  355. >
  356. > for (;;) {
  357. > retry:
  358. > r = mt_rand(random) % len;
  359. >
  360. > for (j=0; j<i; j++) {
  361. > if (mrb_fixnum(RARRAY_PTR(result)[j]) == r) {
  362. > goto retry; /* retry if duplicate */
  363. > }
  364. > }
  365. > break;
  366. > }
  367. > mrb_ary_push(mrb, result, mrb_fixnum_value(r));
  368. > }
  369. > for (i=0; i<n; i++) {
  370. > mrb_ary_set(mrb, result, i, RARRAY_PTR(ary)[mrb_fixnum(RARRAY_PTR(result)[i])]);
  371. > }
  372. > return result;
  373. > }
  374. > }
  375. >
  376. >
  377. 318c334
  378. <
  379. ---
  380. >
  381. 320a337,340
  382. > mrb_define_method(mrb, array, "sample", mrb_ary_sample, MRB_ARGS_OPT(2));
  383. >
  384. > mrb_const_set(mrb, mrb_obj_value(random), mrb_intern_lit(mrb, "DEFAULT"),
  385. > mrb_obj_new(mrb, random, 0, NULL));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement