I've been meaning to learn C for a long time, so I started with a simple montecarlo simulation of the premium bonds. I couldn't work out how to generate random numbers bigger than RAND_MAX, so split my random numbers win/lose, and then win how much. Something seemed wrong, because I wasn't seeing the same results I got in other languages, so I added a count of the random numbers generated:
This is code I wrote (on MacOS Mohave using CLANG to compile):
Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int cmpfunc (const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
int main()
{
int mybonds, period, numberoftrials, ernie, prize, win, i, j, k, m;
int winchance = 24500;
int totalprizes = 3513356;
int sum = 0;
static int randomnumbers[3513356];
memset(randomnumbers, 0, sizeof(randomnumbers));
srand(time(0));
printf("Number of bonds? : ") ;
scanf("%d", &mybonds) ;
printf("Number of months? : ");
scanf("%d", &period);
printf("Number of trials? : ") ;
scanf("%d", &numberoftrials) ;
int *results = (int*) malloc(numberoftrials * sizeof(int));
for (i = 0; i < numberoftrials; i++) {
results[i] = 0;
for (m = 0; m < period; m++) {
for (j = 0; j < mybonds; j++) {
if (rand() > RAND_MAX / winchance) {
results[i] += 0;
} else {
ernie = rand() % totalprizes;
randomnumbers[ernie] += 1;
if (ernie > 63374) {
results[i] += 25;
} else if (ernie > 35815) {
results[i] += 50;
} else if (ernie > 8256) {
results[i] += 100;
} else if (ernie > 2232) {
results[i] += 500;
} else if (ernie > 224) {
results[i] += 1000;
} else if (ernie > 103) {
results[i] += 5000;
} else if (ernie > 44) {
results[i] += 10000;
} else if (ernie > 19) {
results[i] += 25000;
} else if (ernie > 7) {
results[i] += 50000;
} else if (ernie > 1) {
results[i] += 100000;
} else {
results[i] += 1000000;
}
}
}
}
}
qsort(results, numberoftrials, sizeof(int),cmpfunc);
printf("\n");
printf("Worst result: %d\n", results[0]);
printf("Best result: %d\n", results[numberoftrials - 1] );
printf("Median result %d\n", results[numberoftrials / 2 + 1] );
for (k = 0; k < totalprizes; k++) {
sum += randomnumbers[k];
if (randomnumbers[k] > 0) {
printf("%d : %d\n", k, randomnumbers[k]);
}
}
printf("number of winners = %d\n ", sum);
free(results) ;
return 0;
}
And this is the output:
Number of bonds? : 50000
Number of months? : 12
Number of trials? : 10000
Worst result: 225
Best result: 100725
Median result 625
7 : 3
14 : 2
21 : 3
28 : 3
175 : 3
182 : 3
189 : 2
196 : 2
203 : 3
350 : 3
357 : 2
364 : 3
371 : 3
525 : 3
etc, etc
2440698 : 12245
2457505 : 13585
2474312 : 114779
2491119 : 802
number of winners = 657216
I haven't checked every single winning number, but so far every one I've picked is a multiple of 7.
I did try putting in a new srand(time(0)) seed before the second rand(), but this just dramatically reduced the number of random numbers generated. Where have I gone wrong?