Boy or Girl?

January 1, 2009

UPDATE: OK, I was wrong, do not read the post :-) . And remember you should not do the math if you are after a party ;-) .

Recently Jeff Atwood posted The Problem of the Unfinished Game.

It is a simple question:

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?

Using common sense you can tell that the answer is 50%. Every child is completely independent event, and assuming that probability of having a boy or a girl is equal to 50% you have to guess only the second child. It can be boy or a girl. Each have 50%. You want boy, so the answer is 50%.

In the comments there are many opinions. One of them is summed up here: Boy or Girl?.

It can be proven wrong by reduction to absurd. The answer states that if person says the gender of one of her two children then we know with higher probability that she has a mixed gender children. It does not matter if she says it is a boy, or it is a girl. If you know one gender then the probability is 2/3. It is plain stupid.

If she didn’t tell me I would still know that her child is either boy or a girl and this changes nothing to me. The gender of the second child is still not known. And it still can be boy or a girl equally probably.

I think that for this particular resoning the error is in the sample space:
{BB, BG, GB, GG} – it is not it. We are not interested in order of births. We should have sets: {{B, B}, {B, G}, {G, G}}, where {B, B} and {G, G} are 25% and {B, G} is 50% probable. But, if I know the have a girl then sample space is: {{B, G}, {G, G}}. And the probabilities are equal not 2/3 and 1/3 because only the one child is unknown (so it is the same as the space would be: {B, G}).

The reasoning with the tree is also wrong. All probabilities have to change because of our knowledge. We can’t just divide probability equaly between the leaves… We know that she have girl. And we can back-propagate that knowledge to the probability tree. And if I am correct we can say that the her first child was a girl with 0.75 probability. But do the math yourself :)

Bet

And if I am wrong, here is the bet:
I toss a coin two times. I tell you one of the outcomes. You always bet the that the other outcome is different. If I win you pay me 60 cents, If you win I pay you 40 cents. We repeat it 999 times. Because different outcomes are more probable – 2 of 3 times – you should win 999 * 2/3 = 666 times and I 333 times. So you get 666 * 0.4 – 333 * 0.6 = 66.6 dollar. Are you in? I’d be glad, because I am sure I would one hundred backs easily.

And here is an interesting movie in the topic: How juries are fooled by statistics :)

Recently I was reading about planned closures in Java. One of the easy looking examples:

public class Test {
 private static final int N = 10;
 public static void main(String[] args) {
  List<{ => int}> closures = new ArrayList<{ => int}>();

  for (int i = 0; i < N; i++)
   closures.add( { => i } );

  int total = 0;
  for ({ => int} closure : closures)
   total += closure.invoke();
  System.out.println(total);
 }
}

gave quite unexpected results — 100 instead of 45. I thought, well it is a Java problem, Ruby sure got it right. But is it? Here is the code:

procs = []
for i in 1…10
 procs << Proc.new {i}
end
puts procs.inject(0) { |sum, f| sum + f.call() }

And guess what – result is 81. Now a bit confused I started adding some more similar code:

procs = []
(1…10).each do |i|
 procs << Proc.new { i }
end
puts procs.inject(0) { |sum, f| sum + f.call() }

But gosh – still 81. I started googling and wondering what is wrong. After some time I started over with:

(1…10).map { |i| Proc.new {i} }.inject(0) { |sum, f| sum + f.call() }

And yes, it works – the result is 45. Nice, but still why previous examples failed? I added:

procs = []
(1…10).each { |i| procs << Proc.new {i} }
puts procs.inject(0) { |sum, f| sum + f.call() }

And it still working. Hmm… Looks almost the same as one of the previous 'wrong' examples.

Cause of this weird behaviour is that nevertheless you can read
here that:

Syntax:

for lhs… in expr [do]
 expr..
end

Executes body for each element in the result of
expression. for is the syntax sugar for:

(expr).each `{' `|' lhs..`|' expr.. `}'

or here:

But we're getting ahead of ourselves. for is really
another way of writing each, which, it so happens, is our first
example of an iterator. The following two forms are
equivalent:

#  If you’re used to C or Java, you might prefer this.
for element in collection
  …
end

#  A Smalltalk programmer might prefer this.
collection.each {|element|
  …
}

it is not all the truth. They differ in small but important factor – scope.
Pragmatic Programmer's Guide gives the right answer:

The only difference between the for loop and the each form is the scope of local variables that are defined in the body.

So this one:

array = 1...10
puts array.map { |i| Proc.new {i} }.inject(0) { |sum, f| sum + f.call() }
i = nil #or the for loop which also defines local variable
puts array.map { |i| Proc.new {i} }.inject(0) { |sum, f| sum + f.call() }

produces 45 and 81.

I think that is not an easy to find such an error in your code.