First we have some really trivial code that will try to flip a coin
one hundred times. We track the number of times that the coin lands
as "heads" in a row. We also count when "tails" lands in a row and so
therefore we can also know the maximum counts for each. The code will
exit when it has a result with the percentage of heads that the user
requested. Below you can see the output when the user wants to see a
result of 80% heads in the one hundred coin flips. Since the drand48()
function is seeded with the nanosec portion of the current time we will
see different results every time the code is run. The code had to do the
one hundred coin flips 734,308,307 times before we saw 80% of the results
being "heads".
/*
* coin_flip.c : flip a coin one hundred times in a row and wait to
* see results with a large percentage of "heads"
*
* RETURN : This code will return eventually. Maybe. If the
* user requests a large percentage of "heads" then
* it may run a very long time. There is no promise
* that it will ever exit. Good luck.
*
* UPDATE : A bail out condition was needed to have the code
* bail out before the heat death of the universe.
*
* ------------------------------------------------------------------
* Copyright (c) 2024 Dennis Clarke
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ------------------------------------------------------------------
*/
/*********************************************************************
* The Open Group Base Specifications Issue 6
* IEEE Std 1003.1, 2004 Edition
*
* An XSI-conforming application should ensure that the feature
* test macro _XOPEN_SOURCE is defined with the value 600 before
* inclusion of any header. This is needed to enable the
* functionality described in The _POSIX_C_SOURCE Feature Test
* Macro and in addition to enable the XSI extension.
*
*********************************************************************/
#if ! defined (_XOPEN_SOURCE)
#define _XOPEN_SOURCE 600
#endif
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <inttypes.h>
#include <time.h>
#define LIMIT 70
int
main ( int argc, char **argv )
{
/* this code was written with some beers and while
* ranting about uniform distribution results for
* a given source of random data. No attempt was
* made to make the code well organized and variables
* were tossed into the fray at whim.
*/
int k, bias = 0;
uint64_t j;
int heads, tails;
int head_count, max_heads_in_a_row;
int tail_count;
int max_tails_in_a_row;
int max_heads_when;
int max_tails_when;
int this_flip;
int limit = LIMIT;
int64_t loop_up = 0;
int64_t loop_last = -1;
int bit_shift = 1;
double x;
struct timespec now_time;
/* did the user suggest a given percentage ? */
if ( argc > 1 ) {
/* * * * * W A R N I N G * * * *
*
* There is no checking for reasonable data here.
*/
limit = atoi(argv[1]);
printf("Geez I hope you really want %i\n", limit );
}
/* Get the REALTIME_CLOCK time in a timespec struct */
if ( clock_gettime(CLOCK_REALTIME, &now_time ) == -1 ) {
/* We could not get the clock. Bail out. */
fprintf(stderr,"ERROR : could not attain CLOCK_REALTIME\n");
return EXIT_FAILURE;
} else {
/* call srand48() with the nanosecond time data */
srand48( (long) now_time.tv_nsec );
}
/* this is the iteration counter */
j = 0;
max_heads_in_a_row = 0;
max_tails_in_a_row = 0;
max_heads_when = 0;
max_tails_when = 0;
doagain:
heads = 0;
tails = 0;
this_flip = 0;
head_count = 0;
tail_count = 0;
for ( k=0 ; k<100; k++ ) {
x = drand48();
if ( x < 0.5 ) {
tails += 1;
this_flip = 0;
} else {
heads += 1;
this_flip = 1;
}
if ( this_flip == 1 ) {
head_count += 1;
tail_count = 0;
if ( head_count > max_heads_in_a_row ) {
max_heads_in_a_row = head_count;
max_heads_when = j;
}
} else {
head_count = 0;
tail_count += 1;
if ( tail_count > max_tails_in_a_row ) {
max_tails_in_a_row = tail_count;
max_tails_when = j;
}
}
}
if ( heads > limit ) {
bias += 1;
}
j += 1;
/* This is just a progress report which will only
* happen when j is a perfect power of two. Also
* the power of two is increased with a left bit
* shift and so you can expect the reports to happen
* ever more slowly as the code runs. At least we
* see some sign of activity to let the user know
* something is running. */
if ( j & bit_shift ) {
printf ("\nloop j = %" PRIu64 "\n", j );
printf ("max number of heads in a row was %i\n", max_heads_in_a_row);
printf ("max heads happened at loop num %i\n", max_heads_when);
printf ("max number of tails in a row was %i\n", max_tails_in_a_row);
printf ("max tails happened at loop num %i\n", max_tails_when);
bit_shift *= 2;
}
/* be sure to bail out if we have already run 2^34 loops */
if ( ( bias < 1 ) && ( j < ( 1L<<34 ) ) ) goto doagain;
printf ("\nbias events count at %" PRIu64 " for %i%% heads.\n", j, limit );
printf ("max number of heads in a row was %i\n", max_heads_in_a_row);
printf ("max heads happened at loop num %i\n", max_heads_when);
printf ("max number of tails in a row was %i\n", max_tails_in_a_row);
printf ("max tails happened at loop num %i\n", max_tails_when);
/* Please see "The Hitch Hikers Guide to the Galaxy" */
return 42;
}
io$ /usr/bin/time -p /usr/bin/nice -n +18 ./coin_flip 80
Geez I hope you really want 80
loop j = 1
max number of heads in a row was 5
max heads happened at loop num 0
max number of tails in a row was 6
max tails happened at loop num 0
loop j = 2
max number of heads in a row was 6
max heads happened at loop num 1
max number of tails in a row was 6
max tails happened at loop num 0
loop j = 4
max number of heads in a row was 6
max heads happened at loop num 1
max number of tails in a row was 6
max tails happened at loop num 0
loop j = 8
max number of heads in a row was 10
max heads happened at loop num 4
max number of tails in a row was 6
max tails happened at loop num 0
loop j = 16
max number of heads in a row was 11
max heads happened at loop num 11
max number of tails in a row was 10
max tails happened at loop num 10
loop j = 32
max number of heads in a row was 11
max heads happened at loop num 11
max number of tails in a row was 10
max tails happened at loop num 10
loop j = 64
max number of heads in a row was 11
max heads happened at loop num 11
max number of tails in a row was 10
max tails happened at loop num 10
loop j = 128
max number of heads in a row was 11
max heads happened at loop num 11
max number of tails in a row was 11
max tails happened at loop num 65
loop j = 256
max number of heads in a row was 12
max heads happened at loop num 152
max number of tails in a row was 14
max tails happened at loop num 139
loop j = 512
max number of heads in a row was 16
max heads happened at loop num 490
max number of tails in a row was 14
max tails happened at loop num 139
loop j = 1024
max number of heads in a row was 16
max heads happened at loop num 490
max number of tails in a row was 15
max tails happened at loop num 861
loop j = 2048
max number of heads in a row was 17
max heads happened at loop num 1339
max number of tails in a row was 15
max tails happened at loop num 861
loop j = 4096
max number of heads in a row was 19
max heads happened at loop num 3968
max number of tails in a row was 19
max tails happened at loop num 3061
loop j = 8192
max number of heads in a row was 19
max heads happened at loop num 3968
max number of tails in a row was 19
max tails happened at loop num 3061
loop j = 16384
max number of heads in a row was 19
max heads happened at loop num 3968
max number of tails in a row was 19
max tails happened at loop num 3061
loop j = 32768
max number of heads in a row was 19
max heads happened at loop num 3968
max number of tails in a row was 21
max tails happened at loop num 24344
loop j = 65536
max number of heads in a row was 20
max heads happened at loop num 34721
max number of tails in a row was 21
max tails happened at loop num 24344
loop j = 131072
max number of heads in a row was 20
max heads happened at loop num 34721
max number of tails in a row was 22
max tails happened at loop num 86671
loop j = 262144
max number of heads in a row was 21
max heads happened at loop num 191800
max number of tails in a row was 22
max tails happened at loop num 86671
loop j = 524288
max number of heads in a row was 27
max heads happened at loop num 434509
max number of tails in a row was 23
max tails happened at loop num 386110
loop j = 1048576
max number of heads in a row was 27
max heads happened at loop num 434509
max number of tails in a row was 23
max tails happened at loop num 386110
loop j = 2097152
max number of heads in a row was 27
max heads happened at loop num 434509
max number of tails in a row was 25
max tails happened at loop num 1558459
loop j = 4194304
max number of heads in a row was 27
max heads happened at loop num 434509
max number of tails in a row was 25
max tails happened at loop num 1558459
loop j = 8388608
max number of heads in a row was 28
max heads happened at loop num 5492543
max number of tails in a row was 26
max tails happened at loop num 6296002
loop j = 16777216
max number of heads in a row was 29
max heads happened at loop num 15368274
max number of tails in a row was 31
max tails happened at loop num 15353233
loop j = 33554432
max number of heads in a row was 29
max heads happened at loop num 15368274
max number of tails in a row was 31
max tails happened at loop num 15353233
loop j = 67108864
max number of heads in a row was 30
max heads happened at loop num 49032334
max number of tails in a row was 31
max tails happened at loop num 15353233
loop j = 134217728
max number of heads in a row was 30
max heads happened at loop num 49032334
max number of tails in a row was 31
max tails happened at loop num 15353233
loop j = 268435456
max number of heads in a row was 36
max heads happened at loop num 250497298
max number of tails in a row was 34
max tails happened at loop num 163736586
loop j = 536870912
max number of heads in a row was 36
max heads happened at loop num 250497298
max number of tails in a row was 34
max tails happened at loop num 163736586
loop j = 1073741824
max number of heads in a row was 36
max heads happened at loop num 250497298
max number of tails in a row was 35
max tails happened at loop num 976052969
loop j = 2147483648
max number of heads in a row was 36
max heads happened at loop num 250497298
max number of tails in a row was 36
max tails happened at loop num 1894472577
bias events count at 4245791664 for 80% heads.
max number of heads in a row was 36
max heads happened at loop num 250497298
max number of tails in a row was 36
max tails happened at loop num 1894472577
real 31481.86
user 31474.83
sys 0.04
io$
Checked as HTML 4.01 Strict
Validates as CSS level 3 + SVG