• From all families with two children, at least one of whom is a boy, a family is chosen at random. This would yield the answer of 1/3.
  • From all families with two children, one child is selected at random, and the sex of that child is specified to be a boy. This would yield an answer of 1/2.

The subtle difference between those two interpretations from https://en.wikipedia.org/wiki/Boy_or_Girl_paradox was hard for me to grasp, so I wrote some code to see it myself.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <random>
#include <iostream>

using namespace std;

enum gender {
B,
G,
};

gender db[4][2] = {
{B, B},
{B, G},
{G, B},
{G, G},
};

constexpr int count = 100*1000;

int total;
int found;

void f() {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> array_index_gen(0, 3);
uniform_int_distribution<> sub_index_gen(0, 1);

total = found = 0;
for (auto n = 0; n < count; ++n) {
auto i = array_index_gen(gen);
if (db[i][0] == B || db[i][1] == B) {
total++;
if (db[i][0] == db[i][1]) {
found++;
}
}
}

cout << "found/total: " << found << "/" << total
<< " = " << found * 100.0/total
<< endl;
}

void g() {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> array_index_gen(0, 3);
uniform_int_distribution<> sub_index_gen(0, 1);

total = found = 0;
for (auto n = 0; n < count; ++n) {
auto i = array_index_gen(gen);
auto j = sub_index_gen(gen);
if (db[i][j] == B) {
total++;
if (db[i][1-j] == B) {
found++;
}
}
}

cout << "found/total: " << found << "/" << total
<< " = " << found * 100.0/total
<< endl;
}

int main()
{
f();
g();

return 0;
}

The output is

1
2
found/total: 25184/74954 = 33.5993
found/total: 25076/50259 = 49.8936

In summary, how we came by this piece of info, “at least one is a boy”, plays a vital role in the final result.

§references