Skip to Content
Author's profile photo Former Member

Simulation of statistic riddle

I have two children. One is a boy born on a Tuesday. What is the probability I have two boys?

You can read the article with the riddle here: Hype about conditional probability puzzles

The riddle was also mentioned this week on SPON: DE Das Geschwister-Problem

As normal there is a lot of discussion in the article comments about the solution 13/27.

So just proof the solution with a simulation.

  1. Create 1.000.000 families with two children {m,f} 50:50 and born on {sa,su,mo,tu,we,th,fr} 1:7
  2. Count chance, that family has two boys 1/4
  3. Count chance, that family has two boys, if you know that one child is a boy 1/3
  4. Count chance, that family has two boys, if you know that one child is a boy and born on tuesday 13/27

If you program it, it is obvious, that each additional information (one child is a boy, one child is a boy born on tuesday) changes the sample for the probability calculation.

Simple ABAP program
  CONSTANTS:
    c_female    TYPE i VALUE 0,
    c_male      TYPE i VALUE 1,
    c_saturday  TYPE i VALUE 0,
    c_sunday    TYPE i VALUE 1,
    c_monday    TYPE i VALUE 2,
    c_tuesday   TYPE i VALUE 3,
    c_wednesday TYPE i VALUE 4,
    c_thursday  TYPE i VALUE 5,
    c_friday    TYPE i VALUE 6.

  TYPES:
    BEGIN OF ys_family,
      child1_gender          TYPE i,
      child1_day_of_the_week TYPE i,
      child2_gender          TYPE i,
      child2_day_of_the_week TYPE i,
    END OF ys_family.

  DATA:
    lo_rnd    TYPE REF TO cl_random_number,
    ls_family TYPE ys_family,
    lt_family TYPE TABLE OF ys_family,
    li_won    TYPE i,
    li_lost   TYPE i,
    li_total  TYPE i.

  CREATE OBJECT lo_rnd.
  CALL METHOD lo_rnd->if_random_number~init.

  DO 1000000 TIMES.

    ls_family-child1_gender = lo_rnd->if_random_number~get_random_int( 1 ).
    ls_family-child1_day_of_the_week = lo_rnd->if_random_number~get_random_int( 6 ).
    ls_family-child2_gender = lo_rnd->if_random_number~get_random_int( 1 ).
    ls_family-child2_day_of_the_week = lo_rnd->if_random_number~get_random_int( 6 ).
    APPEND ls_family TO lt_family.

  ENDDO.

  WRITE: / 'Chance to have two male children'.
  CLEAR: li_won, li_lost.
  LOOP AT lt_family INTO ls_family.
    ADD 1 TO li_total.
    IF ls_family-child1_gender EQ c_male AND
       ls_family-child2_gender EQ c_male.
      ADD 1 TO li_won.
    ELSE.
      ADD 1 TO li_lost.
    ENDIF.
  ENDLOOP.
  WRITE: / 'total', li_total, 'Won:', li_won, 'Lost:', li_lost.
  li_won = li_won * 100 / li_total.
  li_lost = li_lost * 100 / li_total.
  li_total = li_total * 100 / li_total.
  WRITE: / 'total', li_total, '%', 'Won:', li_won, '%', 'Lost:', li_lost, '%'.

  ULINE.

  WRITE: / 'Chance to have two male children, if you know that first child is male'.
  CLEAR: li_won, li_lost.
  LOOP AT lt_family INTO ls_family.
    IF ls_family-child1_gender EQ c_male OR
       ls_family-child2_gender EQ c_male.
      ADD 1 TO li_total.
      IF ls_family-child1_gender EQ c_male AND
         ls_family-child2_gender EQ c_male.

        ADD 1 TO li_won.
      ELSE.
        ADD 1 TO li_lost.
      ENDIF.
    ENDIF.
  ENDLOOP.
  WRITE: / 'total', li_total, 'Won:', li_won, 'Lost:', li_lost.
  li_won = li_won * 100 / li_total.
  li_lost = li_lost * 100 / li_total.
  li_total = li_total * 100 / li_total.
  WRITE: / 'total', li_total, '%', 'Won:', li_won, '%', 'Lost:', li_lost, '%'.

  ULINE.

  WRITE: / 'Chance to have two male children, if you know that first child is male and born on tuesday'.
  CLEAR: li_won, li_lost.
  LOOP AT lt_family INTO ls_family.
    IF ls_family-child1_gender EQ c_male OR
       ls_family-child2_gender EQ c_male.
      IF ( ls_family-child1_gender EQ c_male AND
           ls_family-child1_day_of_the_week EQ c_tuesday ) OR
         ( ls_family-child2_gender EQ c_male AND
           ls_family-child2_day_of_the_week EQ c_tuesday ).
        ADD 1 TO li_total.
        IF ls_family-child1_gender EQ c_male AND
           ls_family-child2_gender EQ c_male.
          ADD 1 TO li_won.
        ELSE.
          ADD 1 TO li_lost.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDLOOP.
  WRITE: / 'total', li_total, 'Won:', li_won, 'Lost:', li_lost.
  li_won = li_won * 100 / li_total.
  li_lost = li_lost * 100 / li_total.
  li_total = li_total * 100 / li_total.
  WRITE: / 'total', li_total, '%', 'Won:', li_won, '%', 'Lost:', li_lost, '%'.
Output example
Chance to have two male children
 total 1.000.000 Won: 250.442 Lost: 749.558
 total 100 % Won: 25 % Lost: 75 %

Chance to have two male children, if you know that first child is male
 total 750.485 Won: 250.442 Lost: 499.943
 total 100 % Won: 33 % Lost: 67 %

Chance to have two male children, if you know that first child is male and born on Tuesday
 total 138.231 Won: 66.430 Lost: 71.701
 total 100 % Won: 48 % Lost: 52 %

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Matthew Billingham
      Matthew Billingham

      Now do Monty Hall. As an additional challenge, use the Strategy Pattern.

      Author's profile photo Former Member
      Former Member
      Blog Post Author

      Hm, there is not so much logic to implement, if you want to reuse the same simulation from the starting problem.

      It is just another win condition 'I give you two boxes, if you give me your box back.', but no filter on the opened box by the moderator.

      Output
      Program ZSDN_RIDDLE_SIMULATION
      
      Condition: two girls - Filter:
      total 100.000 Won: 24.967 Lost: 75.033
      total 100 % Won: 25 % Lost: 75 %
      
      Condition: two girls - Filter: one girl
      total 74.845 Won: 24.967 Lost: 49.878
      total 100 % Won: 33 % Lost: 67 %
      
      Condition: two girls - Filter: one girl on tuesday
      total 13.637 Won: 6.589 Lost: 7.048
      total 100 % Won: 48 % Lost: 52 %
      
      And Now for Something Completely Different.
      
      Condition: box 1 is car - Filter:
      total 100.000 Won: 33.415 Lost: 66.585
      total 100 % Won: 33 % Lost: 67 %
      
      Condition: box 2/3 is car - Filter:
      total 100.000 Won: 66.585 Lost: 33.415
      total 100 % Won: 67 % Lost: 33 %
      Code
      *&---------------------------------------------------------------------*
      *& Report  ZSDN_RIDDLE_SIMULATION
      *&
      *&---------------------------------------------------------------------*
      REPORT zsdn_riddle_simulation.
      
      CLASS ycl_sdn_sample DEFINITION ABSTRACT.
      ENDCLASS.
      
      INTERFACE ycl_sdn_filter.
        METHODS:
          name RETURNING VALUE(ec_name) TYPE string,
          apply IMPORTING io_sample        TYPE REF TO ycl_sdn_sample
                RETURNING VALUE(eb_result) TYPE abap_bool.
      ENDINTERFACE.
      
      INTERFACE ycl_sdn_condition.
        METHODS:
          name RETURNING VALUE(ec_name) TYPE string,
          apply IMPORTING io_sample        TYPE REF TO ycl_sdn_sample
                RETURNING VALUE(eb_result) TYPE abap_bool.
      ENDINTERFACE.
      
      CLASS ycl_sdn_simulation DEFINITION.
        PUBLIC SECTION.
          DATA:
            mt_sample         TYPE TABLE OF REF TO ycl_sdn_sample,
            mc_filter_name    TYPE string,
            mc_condition_name TYPE string,
            mi_total          TYPE i,
            mi_won            TYPE i,
            mi_lost           TYPE i.
      
          METHODS:
            constructor IMPORTING ic_sample  TYPE classname
                                  ii_samples TYPE i,
            clear,
            run IMPORTING ic_filter    TYPE classname
                          ic_condition TYPE classname,
            print.
      ENDCLASS.
      
      CLASS ycl_sdn_simulation IMPLEMENTATION.
      
        METHOD constructor.
          DATA:
            lo_sample TYPE REF TO ycl_sdn_sample.
      
          DO ii_samples TIMES.
            CREATE OBJECT lo_sample TYPE (ic_sample).
            APPEND lo_sample TO mt_sample.
          ENDDO.
        ENDMETHOD.
      
        METHOD clear.
          CLEAR:
            mi_total,
            mi_won,
            mi_lost.
        ENDMETHOD.
      
        METHOD run.
          DATA:
            lo_sample    TYPE REF TO ycl_sdn_sample,
            lo_filter    TYPE REF TO ycl_sdn_filter,
            lo_condition TYPE REF TO ycl_sdn_condition.
          CREATE OBJECT lo_filter TYPE (ic_filter).
          mc_filter_name = lo_filter->name( ).
          CREATE OBJECT lo_condition TYPE (ic_condition).
          mc_condition_name = lo_condition->name( ).
          LOOP AT mt_sample INTO lo_sample.
            IF lo_filter->apply( lo_sample ) EQ abap_true.
              ADD 1 TO mi_total.
              IF lo_condition->apply( lo_sample ) EQ abap_true.
                ADD 1 TO mi_won.
              ELSE.
                ADD 1 TO mi_lost.
              ENDIF.
            ENDIF.
          ENDLOOP.
        ENDMETHOD.
      
        METHOD print.
          DATA:
            li_won   TYPE i,
            li_lost  TYPE i,
            li_total TYPE i.
          WRITE: 'Condition:', mc_condition_name, '-', 'Filter:', mc_filter_name.
          WRITE: / 'total', mi_total, 'Won:', mi_won, 'Lost:', mi_lost.
          li_won = mi_won * 100 / mi_total.
          li_lost = mi_lost * 100 / mi_total.
          li_total = mi_total * 100 / mi_total.
          WRITE: / 'total', li_total, '%', 'Won:', li_won, '%', 'Lost:', li_lost, '%'.
        ENDMETHOD.
      
      ENDCLASS.
      
      CLASS ycl_sdn_sample_family DEFINITION INHERITING FROM ycl_sdn_sample.
        PUBLIC SECTION.
          CONSTANTS:
            c_female    TYPE i VALUE 0,
            c_male      TYPE i VALUE 1,
            c_saturday  TYPE i VALUE 0,
            c_sunday    TYPE i VALUE 1,
            c_monday    TYPE i VALUE 2,
            c_tuesday   TYPE i VALUE 3,
            c_wednesday TYPE i VALUE 4,
            c_thursday  TYPE i VALUE 5,
            c_friday    TYPE i VALUE 6.
          CLASS-DATA:
            so_rnd TYPE REF TO cl_random_number.
          DATA:
            mi_child1_gender    TYPE i,
            mi_child2_gender    TYPE i,
            mi_child1_dayofweek TYPE i,
            mi_child2_dayofweek TYPE i.
          CLASS-METHODS:
            class_constructor.
          METHODS:
            constructor.
      ENDCLASS.
      
      CLASS ycl_sdn_sample_family IMPLEMENTATION.
      
        METHOD class_constructor.
          CREATE OBJECT so_rnd.
          CALL METHOD so_rnd->if_random_number~init.
        ENDMETHOD.
      
        METHOD constructor.
          super->constructor( ).
          mi_child1_gender = so_rnd->if_random_number~get_random_int( 1 ).
          mi_child1_dayofweek = so_rnd->if_random_number~get_random_int( 6 ).
          mi_child2_gender = so_rnd->if_random_number~get_random_int( 1 ).
          mi_child2_dayofweek = so_rnd->if_random_number~get_random_int( 6 ).
        ENDMETHOD.
      
      ENDCLASS.
      
      CLASS ycl_sdn_filter_none DEFINITION.
        PUBLIC SECTION.
          INTERFACES:
            ycl_sdn_filter.
      ENDCLASS.
      
      CLASS ycl_sdn_filter_none IMPLEMENTATION.
        METHOD ycl_sdn_filter~name.
          ec_name = ''.
        ENDMETHOD.
        METHOD ycl_sdn_filter~apply.
          eb_result = abap_true.
        ENDMETHOD.
      ENDCLASS.
      
      CLASS ycl_sdn_filter_one_girl DEFINITION INHERITING FROM ycl_sdn_filter_none.
        PUBLIC SECTION.
          METHODS:
            ycl_sdn_filter~name REDEFINITION,
            ycl_sdn_filter~apply REDEFINITION.
      ENDCLASS.
      
      CLASS ycl_sdn_filter_one_girl IMPLEMENTATION.
        METHOD ycl_sdn_filter~name.
          ec_name = 'one girl'.
        ENDMETHOD.
        METHOD ycl_sdn_filter~apply.
          DATA:
            lo_family TYPE REF TO ycl_sdn_sample_family.
          eb_result = super->ycl_sdn_filter~apply( io_sample ).
          IF eb_result EQ abap_true.
            lo_family ?= io_sample.
            IF lo_family->mi_child1_gender EQ ycl_sdn_sample_family=>c_female OR
               lo_family->mi_child2_gender EQ ycl_sdn_sample_family=>c_female.
              eb_result = abap_true.
            ELSE.
              eb_result = abap_false.
            ENDIF.
          ENDIF.
        ENDMETHOD.
      ENDCLASS.
      
      CLASS ycl_sdn_filter_one_girl_on_tu DEFINITION INHERITING FROM ycl_sdn_filter_one_girl.
        PUBLIC SECTION.
          METHODS:
            ycl_sdn_filter~name REDEFINITION,
            ycl_sdn_filter~apply REDEFINITION.
      ENDCLASS.
      
      CLASS ycl_sdn_filter_one_girl_on_tu IMPLEMENTATION.
        METHOD ycl_sdn_filter~name.
          ec_name = 'one girl on tuesday'.
        ENDMETHOD.
        METHOD ycl_sdn_filter~apply.
          DATA:
            lo_family TYPE REF TO ycl_sdn_sample_family.
          eb_result = super->ycl_sdn_filter~apply( io_sample ).
          IF eb_result EQ abap_true.
            lo_family ?= io_sample.
            IF ( lo_family->mi_child1_gender EQ ycl_sdn_sample_family=>c_female AND
                 lo_family->mi_child1_dayofweek EQ ycl_sdn_sample_family=>c_tuesday ) OR
               ( lo_family->mi_child2_gender EQ ycl_sdn_sample_family=>c_female AND
                 lo_family->mi_child2_dayofweek EQ ycl_sdn_sample_family=>c_tuesday ).
              eb_result = abap_true.
            ELSE.
              eb_result = abap_false.
            ENDIF.
          ENDIF.
        ENDMETHOD.
      ENDCLASS.
      
      CLASS ycl_sdn_condition_two_girls DEFINITION.
        PUBLIC SECTION.
          INTERFACES:
            ycl_sdn_condition.
      ENDCLASS.
      
      CLASS ycl_sdn_condition_two_girls IMPLEMENTATION.
        METHOD ycl_sdn_condition~name.
          ec_name = 'two girls'.
        ENDMETHOD.
        METHOD ycl_sdn_condition~apply.
          DATA:
            lo_family TYPE REF TO ycl_sdn_sample_family.
          lo_family ?= io_sample.
          IF lo_family->mi_child1_gender EQ ycl_sdn_sample_family=>c_female AND
             lo_family->mi_child2_gender EQ ycl_sdn_sample_family=>c_female.
            eb_result = abap_true.
          ELSE.
            eb_result = abap_false.
          ENDIF.
        ENDMETHOD.
      ENDCLASS.
      
      CLASS ycl_sdn_sample_monty_hall DEFINITION INHERITING FROM ycl_sdn_sample.
        PUBLIC SECTION.
          CONSTANTS:
            c_goat      TYPE i VALUE 0,
            c_moderator TYPE i VALUE 1,
            c_car       TYPE i VALUE 2.
          CLASS-DATA:
            so_rnd TYPE REF TO cl_random_number.
          DATA:
            mi_box1 TYPE i,
            mi_box2 TYPE i,
            mi_box3 TYPE i.
          CLASS-METHODS:
            class_constructor.
          METHODS:
            constructor.
      ENDCLASS.
      
      CLASS ycl_sdn_sample_monty_hall IMPLEMENTATION.
      
        METHOD class_constructor.
          CREATE OBJECT so_rnd.
          CALL METHOD so_rnd->if_random_number~init.
        ENDMETHOD.
      
        METHOD constructor.
          DATA:
            li_box TYPE i.
          FIELD-SYMBOLS:
            <li_vbox1> TYPE i,
            <li_vbox2> TYPE i.
          super->constructor( ).
      
          li_box = so_rnd->if_random_number~get_random_int( 2 ).
          CASE li_box.
            WHEN 0.
              mi_box1 = c_car.
              ASSIGN mi_box2 TO <li_vbox1>.
              ASSIGN mi_box3 TO <li_vbox2>.
            WHEN 1.
              ASSIGN mi_box1 TO <li_vbox1>.
              mi_box2 = c_car.
              ASSIGN mi_box3 TO <li_vbox2>.
            WHEN 2.
              ASSIGN mi_box1 TO <li_vbox1>.
              ASSIGN mi_box2 TO <li_vbox2>.
              mi_box3 = c_car.
          ENDCASE.
          li_box = so_rnd->if_random_number~get_random_int( 1 ).
          CASE li_box.
            WHEN 0.
              <li_vbox1> = c_moderator.
            WHEN 1.
              <li_vbox2> = c_moderator.
          ENDCASE.
        ENDMETHOD.
      
      ENDCLASS.
      
      CLASS ycl_sdn_condition_box1 DEFINITION.
        PUBLIC SECTION.
          INTERFACES:
            ycl_sdn_condition.
      ENDCLASS.
      
      CLASS ycl_sdn_condition_box1 IMPLEMENTATION.
        METHOD ycl_sdn_condition~name.
          ec_name = 'box 1 is car'.
        ENDMETHOD.
        METHOD ycl_sdn_condition~apply.
          DATA:
            lo_monty_hall TYPE REF TO ycl_sdn_sample_monty_hall.
          lo_monty_hall ?= io_sample.
          IF lo_monty_hall->mi_box1 EQ ycl_sdn_sample_monty_hall=>c_car.
            eb_result = abap_true.
          ELSE.
            eb_result = abap_false.
          ENDIF.
        ENDMETHOD.
      ENDCLASS.
      
      CLASS ycl_sdn_condition_box23 DEFINITION.
        PUBLIC SECTION.
          INTERFACES:
            ycl_sdn_condition.
      ENDCLASS.
      
      CLASS ycl_sdn_condition_box23 IMPLEMENTATION.
        METHOD ycl_sdn_condition~name.
          ec_name = 'box 2/3 is car'.
        ENDMETHOD.
        METHOD ycl_sdn_condition~apply.
          DATA:
            lo_monty_hall TYPE REF TO ycl_sdn_sample_monty_hall.
          lo_monty_hall ?= io_sample.
          IF lo_monty_hall->mi_box2 EQ ycl_sdn_sample_monty_hall=>c_car OR
             lo_monty_hall->mi_box3 EQ ycl_sdn_sample_monty_hall=>c_car.
            eb_result = abap_true.
          ELSE.
            eb_result = abap_false.
          ENDIF.
        ENDMETHOD.
      ENDCLASS.
      
      CLASS ycl_sdn_flow_logic DEFINITION.
        PUBLIC SECTION.
          CONSTANTS:
            c_sample_family              TYPE classname VALUE 'YCL_SDN_SAMPLE_FAMILY',
            c_filter_none                TYPE classname VALUE 'YCL_SDN_FILTER_NONE',
            c_filter_one_girl            TYPE classname VALUE 'YCL_SDN_FILTER_ONE_GIRL',
            c_filter_one_girl_on_tuesday TYPE classname VALUE 'YCL_SDN_FILTER_ONE_GIRL_ON_TU',
            c_condition_two_girls        TYPE classname VALUE 'YCL_SDN_CONDITION_TWO_GIRLS',
      
            c_sample_monty_hall          TYPE classname VALUE 'YCL_SDN_SAMPLE_MONTY_HALL',
            c_condition_box1             TYPE classname VALUE 'YCL_SDN_CONDITION_BOX1',
            c_condition_box23            TYPE classname VALUE 'YCL_SDN_CONDITION_BOX23'.
      
          CLASS-METHODS:
            start_of_selection.
      ENDCLASS.
      
      CLASS ycl_sdn_flow_logic IMPLEMENTATION.
        METHOD start_of_selection.
          DATA:
            lo_simulation TYPE REF TO ycl_sdn_simulation.
      
          CREATE OBJECT lo_simulation
            EXPORTING
              ic_sample  = c_sample_family
              ii_samples = 100000.
      
          lo_simulation->clear( ).
          lo_simulation->run( ic_filter = c_filter_none
                              ic_condition = c_condition_two_girls ).
          lo_simulation->print( ).
      
          ULINE.
      
          lo_simulation->clear( ).
          lo_simulation->run( ic_filter = c_filter_one_girl
                              ic_condition = c_condition_two_girls ).
          lo_simulation->print( ).
      
          ULINE.
      
          lo_simulation->clear( ).
          lo_simulation->run( ic_filter = c_filter_one_girl_on_tuesday
                              ic_condition = c_condition_two_girls ).
          lo_simulation->print( ).
      
          ULINE.
      
          WRITE: / 'And Now for Something Completely Different.'.
      
          ULINE.
      
          CREATE OBJECT lo_simulation
            EXPORTING
              ic_sample  = c_sample_monty_hall
              ii_samples = 100000.
      
          lo_simulation->clear( ).
          lo_simulation->run( ic_filter = c_filter_none
                              ic_condition = c_condition_box1 ).
          lo_simulation->print( ).
      
          ULINE.
      
          lo_simulation->clear( ).
          lo_simulation->run( ic_filter = c_filter_none
                              ic_condition = c_condition_box23 ).
          lo_simulation->print( ).
      
        ENDMETHOD.
      ENDCLASS.
      
      START-OF-SELECTION.
        ycl_sdn_flow_logic=>start_of_selection( ).

       

      Author's profile photo Michelle Crapo
      Michelle Crapo

      I have to say that the win would be if it was a girl..   😉  Of course ask any parent and the win is if they had a health, happy baby.     I had to add that.

      Very cool blog - I liked it!

      Michelle