Advertisement
Guest User

Untitled

a guest
Jan 20th, 2020
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.31 KB | None | 0 0
  1. #include <limits.h>
  2. #include <math.h>
  3. #include <stdbool.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <time.h>
  7. #define EVNT_RUNTIME_DAYS 21
  8. #define N_ITER 10000000
  9. #define N_MAX 36
  10. #define PTS_PER_DUPE 10
  11. #define PTS_PER_TDRAW 100
  12. #define ROLLS_PER_DAY 10
  13.  
  14. double square(double x)
  15. {
  16. return x*x;
  17. }
  18.  
  19. struct math_data
  20. {
  21. int gt_21;
  22. int max;
  23. int min;
  24. int mode;
  25. double median;
  26. double mean;
  27. double stdev;
  28. double variance;
  29. };
  30.  
  31. struct math_data *math_data_new(int gt_21, int max, int min, int mode,
  32. double median, double mean, double stdev, double variance)
  33. {
  34. struct math_data *obj = malloc(sizeof(*obj));
  35. obj->gt_21 = gt_21;
  36. obj->max = max;
  37. obj->min = min;
  38. obj->mode = mode;
  39. obj->median = median;
  40. obj->mean = mean;
  41. obj->stdev = stdev;
  42. obj->variance = variance;
  43. return obj;
  44. }
  45.  
  46. void math_data_print(struct math_data *data)
  47. {
  48. printf("-- Data Start --\n");
  49. printf(">21: %d (%.1lf%%)\n", data->gt_21,
  50. (double)data->gt_21 / N_ITER * 100);
  51. printf("max: %d\n", data->max);
  52. printf("min: %d\n", data->min);
  53. printf("mode: %d\n", data->mode);
  54. printf("median: %.1lf\n", data->median);
  55. printf("mean: %.15lf\n", data->mean);
  56. printf("stdev: %lf\n", data->stdev);
  57. printf("variance: %lf\n", data->variance);
  58. printf("-- Data End --\n");
  59. }
  60.  
  61. struct bingo_data
  62. {
  63. int total_rolls;
  64. int days;
  65. int uniques;
  66. int dupes;
  67. };
  68.  
  69. struct bingo_data *bingo_data_new(int total_rolls, int days,
  70. int uniques, int dupes)
  71. {
  72. struct bingo_data *obj = malloc(sizeof(*obj));
  73. obj->total_rolls = total_rolls;
  74. obj->days = days;
  75. obj->uniques = uniques;
  76. obj->dupes = dupes;
  77. return obj;
  78. }
  79.  
  80. struct bingo_data *bingo()
  81. {
  82. bool set[N_MAX + 1] = {false};
  83. int total_rolls = 0, days = 0, uniques = 0, dupes = 0;
  84. for (bool done = false; !done; total_rolls++) {
  85. days = total_rolls % ROLLS_PER_DAY == 0 ? days + 1 : days;
  86. int r = random() % N_MAX + 1;
  87. if (set[r]) {
  88. dupes++;
  89. } else {
  90. set[r] = true;
  91. uniques++;
  92. }
  93. int numbers_left = (dupes * PTS_PER_DUPE) / PTS_PER_TDRAW;
  94. done = uniques + numbers_left >= N_MAX;
  95. }
  96. return bingo_data_new(total_rolls, days, uniques, dupes);
  97. }
  98.  
  99. struct bingo_data *bingo_no_tdraw()
  100. {
  101. bool set[N_MAX + 1] = {false};
  102. int total_rolls = 0, days = 0, uniques = 0, dupes = 0;
  103. for (bool done = false; !done; total_rolls++) {
  104. days = total_rolls % ROLLS_PER_DAY == 0 ? days + 1 : days;
  105. int r = rand() % N_MAX + 1;
  106. if (set[r]) {
  107. dupes++;
  108. } else {
  109. set[r] = true;
  110. uniques++;
  111. }
  112. done = uniques >= N_MAX;
  113. }
  114. return bingo_data_new(total_rolls, days, uniques, dupes);
  115. }
  116.  
  117. int get_gt_runtime(struct bingo_data **a)
  118. {
  119. int count = 0;
  120. for (size_t i = 0; i < N_ITER; i++)
  121. if (a[i]->days > EVNT_RUNTIME_DAYS)
  122. count++;
  123. return count;
  124. }
  125.  
  126. int get_max(struct bingo_data **a)
  127. {
  128. int max = -1;
  129. for (size_t i = 0; i < N_ITER; i++)
  130. if (max < a[i]->days)
  131. max = a[i]->days;
  132. return max;
  133. }
  134.  
  135. int get_min(struct bingo_data **a)
  136. {
  137. int min = INT_MAX;
  138. for (size_t i = 0; i < N_ITER; i++)
  139. if (min > a[i]->days)
  140. min = a[i]->days;
  141. return min;
  142. }
  143.  
  144. double get_mode(struct bingo_data **a, int max)
  145. {
  146. int *freq_tbl = calloc(max + 1, sizeof(int));
  147. for (size_t i = 0; i < N_ITER; i++)
  148. freq_tbl[a[i]->days]++;
  149. int curr_max = -1;
  150. int mode = -1;
  151. for (size_t i = 1; i < max; i++) {
  152. if (freq_tbl[i] > curr_max) {
  153. curr_max = freq_tbl[i];
  154. mode = i;
  155. }
  156. }
  157. free(freq_tbl);
  158. return mode;
  159. }
  160.  
  161. double get_median(struct bingo_data **a, int max)
  162. {
  163. int *csort = calloc(max + 1, sizeof(int));
  164. for (size_t i = 0; i < N_ITER; i++)
  165. csort[a[i]->days]++;
  166. int *rez = malloc(N_ITER * sizeof(int));
  167. for (size_t i = 1, k = 0; i < max + 1; i++)
  168. for (int j = 0; j < csort[i]; j++)
  169. rez[k++] = i;
  170. double ret;
  171. if (N_ITER % 2 == 0) {
  172. int lef_mid = (N_ITER / 2) - 1;
  173. int rgt_mid = N_ITER / 2;
  174. ret = ((double)rez[lef_mid] + (double)rez[rgt_mid]) / 2;
  175. } else {
  176. int mid = N_ITER / 2;
  177. ret = (double)rez[mid];
  178. }
  179. free(csort);
  180. free(rez);
  181. return ret;
  182. }
  183.  
  184. double get_mean(struct bingo_data **a)
  185. {
  186. double mean = 0.0;
  187. for (size_t i = 0; i < N_ITER; i++)
  188. mean += (double)a[i]->days / N_ITER;
  189. return mean;
  190. }
  191.  
  192. double get_stdev(struct bingo_data **a, double mean)
  193. {
  194. double stdev = 0.0;
  195. for (size_t i = 0; i < N_ITER; i++)
  196. stdev += square((double)a[i]->days - mean) / (double)N_ITER;
  197. return sqrt(stdev);
  198. }
  199.  
  200. struct math_data *process(struct bingo_data **a)
  201. {
  202. printf("...Done. Processing data...\n");
  203. int gt_runtime = get_gt_runtime(a);
  204. int max = get_max(a);
  205. int min = get_min(a);
  206. int mode = get_mode(a, max);
  207. double median = get_median(a, max);
  208. double mean = get_mean(a);
  209. double stdev = get_stdev(a, mean);
  210. double variance = square(stdev);
  211. return math_data_new(gt_runtime, max, min, mode, median,
  212. mean, stdev, variance);
  213. }
  214.  
  215. struct bingo_data **simulate(struct bingo_data*(*f)())
  216. {
  217. struct bingo_data **a = malloc(N_ITER * sizeof(struct bingo_data*));
  218. for (size_t i = 0; i < N_ITER; i++) {
  219. if (i % (N_ITER / 10) == 0)
  220. printf("%zu... Done.\n", i);
  221. a[i] = (*f)();
  222. }
  223. return a;
  224. }
  225.  
  226. int main(void)
  227. {
  228. struct timespec ts;
  229. timespec_get(&ts, TIME_UTC);
  230. srandom(ts.tv_nsec ^ ts.tv_sec);
  231.  
  232. printf("GFL Bingo: simulating for %d iterations...\n", N_ITER);
  233. struct bingo_data **a = simulate(bingo);
  234. struct math_data *a_data = process(a);
  235. math_data_print(a_data);
  236. for (size_t i = 0; i < N_ITER; i++)
  237. free(a[i]);
  238. free(a);
  239. free(a_data);
  240.  
  241. printf("\n");
  242.  
  243. printf("GFL Bingo (no targeted draws): simulating"
  244. " for %d iterations...\n", N_ITER);
  245. struct bingo_data **b = simulate(bingo_no_tdraw);
  246. struct math_data *b_data = process(b);
  247. math_data_print(b_data);
  248. for (size_t i = 0; i < N_ITER; i++)
  249. free(b[i]);
  250. free(b);
  251. free(b_data);
  252. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement