Created
August 12, 2018 16:19
-
-
Save rustybrooks/443d1c1816bf490c35f7cdbd7921b9a6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cpuid.h> // for __get_cpuid intrinsic | |
#include <stdio.h> | |
#include <string.h> | |
#include <immintrin.h> | |
#include <math.h> | |
int has_rdrand() { | |
const unsigned int flag_RDRAND = (1 << 30); | |
unsigned int eax, ebx, ecx, edx; | |
__get_cpuid(1, &eax, &ebx, &ecx, &edx); | |
return ((ecx & flag_RDRAND) == flag_RDRAND); | |
} | |
void translate_sequence(int s, char out[4]) { | |
for (int i=0; i<3; i++) { | |
out[i] = s & (1 << i) ? 'H' : 'T'; | |
} | |
} | |
int main(int argc, char **argv) { | |
if (!has_rdrand()) { | |
printf("This CPU does not support RDRAND, exiting\n"); | |
return 1; | |
} | |
if (argc < 3) { | |
printf("Requires 2 arguments: numiters and doprint\n"); | |
return 1; | |
} | |
uint64_t iterations = atoi(argv[1]), wins=0; | |
uint8_t doprint = atoi(argv[2]); | |
// through this program, H is a binary 1 and T is a binary 0 | |
int winmap[8] = { | |
0, // TTT you bet T on the 4th | |
1, // TTH you bet H on the 4th | |
1, // THT you bet H on the 4th | |
0, // THH you bet T on the 4th | |
1, // HTT you bet H on the 4th | |
0, // HTH you bet T on the 4th | |
0, // HHT you bet T on the 4th | |
1, // HHH you bet H on the 4th | |
}; | |
char outseq[4] = {0, 0, 0, 0}; | |
uint8_t sequence, final, win; | |
uint32_t randblock; | |
for (int i=0; i<iterations; i++) { | |
_rdrand32_step(&randblock); | |
for (int s1=0; s1<8; s1++) { | |
sequence = randblock & 7; // first 3 bits | |
final = (randblock & 8) == 8; // 4th bit | |
translate_sequence(sequence, outseq); // to make it look nice | |
win = final == winmap[sequence]; // check whether we won | |
wins += win; | |
if (doprint) | |
printf("sequence = %s, bet = %c, final = %c, win = %c\n", outseq, winmap[sequence]?'H':'T', final?'H':'T', win?'Y':'N'); | |
randblock = randblock >> 4; // shift 4 bits out of our block to get a fresh game | |
} | |
if (i % 10000000 == 0) printf("%0.1f%% done\n", 100.0*i/iterations); | |
} | |
printf("won %lld / %lld = %0.6f", wins, iterations*8, 100.0*wins/(iterations*8)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment