/***************************************************************** * * Copyright 2009 by Sean Conner. All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Comments, questions and criticisms can be sent to: sean@conman.org * ***************************************************************/ /************************************************************* * * This program was my attempt to figure out the odds to the * following word puzzle: * * Let's say, hypothetically speaking, you met someone who told you * they had two children, and one of them is a girl. What are the odds * that person has a boy and a girl? * * The answer is 1/2, except of course, when it's 2/3. * *************************************************************/ #include #include #include #include /***************************************************************/ typedef enum coin { HEADS, TAILS } a_coin; typedef enum kid { A_BOY, A_GIRL } a_kid; typedef enum choice { FIRST, SECOND } a_choice; /**************************************************************/ void init_seed(void) { FILE *fp; unsigned int seed; fp = fopen("/dev/urandom","r"); if (fp) { fread(&seed,sizeof(seed),1,fp); srand(seed); fclose(fp); } else srand(time(NULL)); } /*************************************************************/ a_coin coinflip(void) { if (rand() > (RAND_MAX / 2)) return HEADS; else return TAILS; } /**************************************************************/ double pc(unsigned long a,unsigned long b) { return ((double)a / (double)b) * 100.0; } /**************************************************************/ int main(int argc,char *argv[]) { a_kid first; a_kid second; a_choice which_to_disclose; unsigned long i; unsigned long max_pairs = 1000000uL; unsigned long number_of_pairs = 0uL; unsigned long number_of_kids = 0uL; unsigned long total_boys = 0uL; unsigned long total_girls = 0uL; unsigned long total_at_least_one_boy = 0uL; unsigned long total_at_least_one_girl = 0uL; unsigned long total_boy_boy = 0uL; unsigned long total_boy_girl = 0uL; unsigned long total_girl_boy = 0uL; unsigned long total_girl_girl = 0uL; unsigned long disclose_first = 0uL; unsigned long disclose_second = 0uL; unsigned long disclose_first_boy = 0uL; unsigned long disclose_first_boy_then_boy = 0uL; unsigned long disclose_first_boy_then_girl = 0uL; unsigned long disclose_first_boy_pick_boy_win = 0uL; unsigned long disclose_first_boy_pick_boy_lose = 0uL; unsigned long disclose_first_boy_pick_girl_win = 0uL; unsigned long disclose_first_boy_pick_girl_lose = 0uL; unsigned long disclose_second_boy = 0uL; unsigned long disclose_second_boy_then_boy = 0uL; unsigned long disclose_second_boy_then_girl = 0uL; unsigned long disclose_second_boy_pick_boy_win = 0uL; unsigned long disclose_second_boy_pick_boy_lose = 0uL; unsigned long disclose_second_boy_pick_girl_win = 0uL; unsigned long disclose_second_boy_pick_girl_lose = 0uL; unsigned long disclose_first_girl = 0uL; unsigned long disclose_first_girl_then_girl = 0uL; unsigned long disclose_first_girl_then_boy = 0uL; unsigned long disclose_first_girl_pick_boy_win = 0uL; unsigned long disclose_first_girl_pick_boy_lose = 0uL; unsigned long disclose_first_girl_pick_girl_win = 0uL; unsigned long disclose_first_girl_pick_girl_lose = 0uL; unsigned long disclose_second_girl = 0uL; unsigned long disclose_second_girl_then_girl = 0uL; unsigned long disclose_second_girl_then_boy = 0uL; unsigned long disclose_second_girl_pick_boy_win = 0uL; unsigned long disclose_second_girl_pick_boy_lose = 0uL; unsigned long disclose_second_girl_pick_girl_win = 0uL; unsigned long disclose_second_girl_pick_girl_lose = 0uL; unsigned long disclose_a_boy = 0uL; unsigned long disclose_a_boy_then_boy = 0uL; unsigned long disclose_a_boy_then_girl = 0uL; unsigned long disclose_a_boy_pick_boy_win = 0uL; unsigned long disclose_a_boy_pick_boy_lose = 0uL; unsigned long disclose_a_boy_pick_girl_win = 0uL; unsigned long disclose_a_boy_pick_girl_lose = 0uL; unsigned long disclose_a_girl = 0uL; unsigned long disclose_a_girl_then_girl = 0uL; unsigned long disclose_a_girl_then_boy = 0uL; unsigned long disclose_a_girl_pick_boy_win = 0uL; unsigned long disclose_a_girl_pick_boy_lose = 0uL; unsigned long disclose_a_girl_pick_girl_win = 0uL; unsigned long disclose_a_girl_pick_girl_lose = 0uL; if (argc > 1) max_pairs = strtoul(argv[1],NULL,10); init_seed(); for (i = 0 ; i < max_pairs ; i++) { first = (coinflip() == HEADS) ? A_BOY : A_GIRL; second = (coinflip() == HEADS) ? A_BOY : A_GIRL; which_to_disclose = (coinflip() == HEADS) ? FIRST : SECOND; /*----------------------------------------------------- ; if we restrict outselves to just those that have at ; least a girl, the results are *still* 50/50. ;-----------------------------------------------------*/ #if 0 if ((first == A_BOY) && (second == A_BOY)) continue; #endif /*-------------------------------------------------- ; *BUT*, if said pairings were forced to disclose a ; girl *when there's a girl*, *THEN* we get the 2/3 ; odds ... ;---------------------------------------------------*/ #if 0 if (first == A_GIRL) which_to_disclose = FIRST; else if (second == A_GIRL) which_to_disclose = SECOND; #endif number_of_pairs++; number_of_kids += 2; if (first == A_BOY) total_boys++; else if (first == A_GIRL) total_girls++; else assert(0); if (second == A_BOY) total_boys++; else if (second == A_GIRL) total_girls++; else assert(0); if ((first == A_BOY) || (second == A_BOY)) total_at_least_one_boy++; if ((first == A_GIRL) || (second == A_GIRL)) total_at_least_one_girl++; if ((first == A_BOY) && (second == A_BOY)) total_boy_boy++; else if ((first == A_BOY) && (second == A_GIRL)) total_boy_girl++; else if ((first == A_GIRL) && (second == A_BOY)) total_girl_boy++; else if ((first == A_GIRL) && (second == A_GIRL)) total_girl_girl++; else assert(0); if (which_to_disclose == FIRST) { disclose_first++; if (first == A_BOY) { disclose_first_boy++; disclose_a_boy++; if (second == A_BOY) { disclose_first_boy_then_boy++; disclose_first_boy_pick_boy_win++; disclose_first_boy_pick_girl_lose++; disclose_a_boy_then_boy++; disclose_a_boy_pick_boy_win++; disclose_a_boy_pick_girl_lose++; } else if (second == A_GIRL) { disclose_first_boy_then_girl++; disclose_first_boy_pick_boy_lose++; disclose_first_boy_pick_girl_win++; disclose_a_boy_then_girl++; disclose_a_boy_pick_boy_lose++; disclose_a_boy_pick_girl_win++; } else assert(0); } else if (first == A_GIRL) { disclose_first_girl++; disclose_a_girl++; if (second == A_BOY) { disclose_first_girl_then_boy++; disclose_first_girl_pick_boy_win++; disclose_first_girl_pick_girl_lose++; disclose_a_girl_then_boy++; disclose_a_girl_pick_boy_win++; disclose_a_girl_pick_girl_lose++; } else if (second == A_GIRL) { disclose_first_girl_then_girl++; disclose_first_girl_pick_boy_lose++; disclose_first_girl_pick_girl_win++; disclose_a_girl_then_girl++; disclose_a_girl_pick_boy_lose++; disclose_a_girl_pick_girl_win++; } else assert(0); } else assert(0); } else if (which_to_disclose == SECOND) { disclose_second++; if (second == A_BOY) { disclose_second_boy++; disclose_a_boy++; if (first == A_BOY) { disclose_second_boy_then_boy++; disclose_second_boy_pick_boy_win++; disclose_second_boy_pick_girl_lose++; disclose_a_boy_then_boy++; disclose_a_boy_pick_boy_win++; disclose_a_boy_pick_girl_lose++; } else if (first == A_GIRL) { disclose_second_boy_then_girl++; disclose_second_boy_pick_boy_lose++; disclose_second_boy_pick_girl_win++; disclose_a_boy_then_girl++; disclose_a_boy_pick_boy_lose++; disclose_a_boy_pick_girl_win++; } else assert(0); } else if (second == A_GIRL) { disclose_second_girl++; disclose_a_girl++; if (first == A_BOY) { disclose_second_girl_then_boy++; disclose_second_girl_pick_boy_win++; disclose_second_girl_pick_girl_lose++; disclose_a_girl_then_boy++; disclose_a_girl_pick_boy_win++; disclose_a_girl_pick_girl_lose++; } else if (first == A_GIRL) { disclose_second_girl_then_girl++; disclose_second_girl_pick_boy_lose++; disclose_second_girl_pick_girl_win++; disclose_a_girl_then_girl++; disclose_a_girl_pick_boy_lose++; disclose_a_girl_pick_girl_win++; } else assert(0); } else assert(0); } else assert(0); } /*------------------------------------------------------ ; output is in HTML, since this was for a blog post: ; ; http://boston.conman.org/2009/01/09.1 ; ;-------------------------------------------------------*/ printf( "\n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "
Number of kids
 ValuePercentage
Total # of kids %10lu %5.1f
Boys %10lu %5.1f
Girls %10lu %5.1f
\n" "\n", number_of_kids, pc(number_of_kids,number_of_kids), total_boys, pc(total_boys,number_of_kids), total_girls, pc(total_girls,number_of_kids) ); printf( "\n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "
Pair Stats
 ValuePercentage
Total # of pairs %10lu %5.1f
Boy/Boy %10lu %5.1f
Boy/Girl %10lu %5.1f
Girl/Boy %10lu %5.1f
Girl/Girl %10lu %5.1f
At least one Boy %10lu %5.1f
At least one Girl%10lu %5.1f
\n" "\n", number_of_pairs, pc(number_of_pairs,number_of_pairs), total_boy_boy, pc(total_boy_boy,number_of_pairs), total_boy_girl, pc(total_boy_girl,number_of_pairs), total_girl_boy, pc(total_girl_boy,number_of_pairs), total_girl_girl, pc(total_girl_girl,number_of_pairs), total_at_least_one_boy, pc(total_at_least_one_boy,number_of_pairs), total_at_least_one_girl,pc(total_at_least_one_girl,number_of_pairs) ); printf( "\n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "
Disclosure table #1—Overview
  Value Percentage
Total # of pairs %10lu %5.1f
Disclosed First Kid %10lu %5.1f
Disclosed Second Kid%10lu %5.1f
Disclosed Girl %10lu %5.1f
Disclosed Boy %10lu %5.1f
\n" "\n", number_of_pairs, pc(number_of_pairs,number_of_pairs), disclose_first, pc(disclose_first,number_of_pairs), disclose_second, pc(disclose_second,number_of_pairs), disclose_a_girl, pc(disclose_a_girl,number_of_pairs), disclose_a_boy, pc(disclose_a_boy,number_of_pairs) ); printf( "\n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" "
Disclosure table #2—disclosed a Girl
  Value Percentage
Disclosed Girl %10lu %5.1f
  First kid %10lu %5.1f
  Second kid %10lu %5.1f
Disclosed Girl, other girl %10lu %5.1f
  First kid %10lu %5.1f
  Second kid %10lu %5.1f
Disclosed Girl, other boy %10lu %5.1f
  First kid %10lu %5.1f
  Second kid %10lu %5.1f
Disclosed Girl, pick girl, correct %10lu %5.1f
  First kid %10lu %5.1f
  Second kid %10lu %5.1f
Disclosed Girl, pick girl, wrong %10lu %5.1f
  First kid %10lu %5.1f
  Second kid %10lu %5.1f
Disclosed Girl, pick boy, correct %10lu %5.1f
  First kid %10lu %5.1f
  Second kid %10lu %5.1f
Disclosed Girl, pick boy, wrong %10lu %5.1f
  First kid %10lu %5.1f
  Second kid %10lu %5.1f
\n" "\n", disclose_a_girl, pc(disclose_a_girl, disclose_a_girl), disclose_first_girl, pc(disclose_first_girl, disclose_a_girl), disclose_second_girl, pc(disclose_second_girl, disclose_a_girl), disclose_a_girl_then_girl, pc(disclose_a_girl_then_girl, disclose_a_girl), disclose_first_girl_then_girl, pc(disclose_first_girl_then_girl, disclose_a_girl), disclose_second_girl_then_girl, pc(disclose_second_girl_then_girl, disclose_a_girl), disclose_a_girl_then_boy, pc(disclose_a_girl_then_boy, disclose_a_girl), disclose_first_girl_then_boy, pc(disclose_first_girl_then_boy, disclose_a_girl), disclose_second_girl_then_girl, pc(disclose_second_girl_then_girl, disclose_a_girl), disclose_a_girl_pick_girl_win, pc(disclose_a_girl_pick_girl_win, disclose_a_girl), disclose_first_girl_pick_girl_win, pc(disclose_first_girl_pick_girl_win, disclose_a_girl), disclose_second_girl_pick_girl_win, pc(disclose_second_girl_pick_girl_win, disclose_a_girl), disclose_a_girl_pick_girl_lose, pc(disclose_a_girl_pick_girl_lose, disclose_a_girl), disclose_first_girl_pick_girl_lose, pc(disclose_first_girl_pick_girl_lose, disclose_a_girl), disclose_second_girl_pick_girl_lose, pc(disclose_second_girl_pick_girl_lose, disclose_a_girl), disclose_a_girl_pick_boy_win, pc(disclose_a_girl_pick_boy_win, disclose_a_girl), disclose_first_girl_pick_boy_win, pc(disclose_first_girl_pick_boy_win, disclose_a_girl), disclose_second_girl_pick_boy_win, pc(disclose_second_girl_pick_boy_win, disclose_a_girl), disclose_a_girl_pick_boy_lose, pc(disclose_a_girl_pick_boy_lose, disclose_a_girl), disclose_first_girl_pick_boy_lose, pc(disclose_first_girl_pick_boy_lose, disclose_a_girl), disclose_second_girl_pick_boy_lose, pc(disclose_second_girl_pick_boy_lose, disclose_a_girl) ); return EXIT_SUCCESS; }