This is the first post in my new blog series focusing on solving puzzles in C# & LINQPad!
In the team I work with, it has become common practice for people to taunt their fellow developers by proposing interesting and sometimes mind bending puzzles.
Coins in a Bag
(courtesy of Mitch Wheat)
"Two indistinguishable coins are placed in a black bag. One coin is biased towards heads -- it comes up heads with probability 0.6
The other coin is biased towards tails -- it comes up heads with probability 0.4. For both coins, the outcomes of successive flips are independent.
You select a coin at random from the bag and flip it 5 times. It comes up heads 3 times -- what is the probability that it was the coin that is biased towards tails?"
LINQPad Solution
Although it is likely that the author of the puzzle intended us to use real maths, this problem is remarkably easy to simulate with a program.
static Random r = new Random();
// Flip the heads weighted coin
public static string Heads()
{
return r.Next(1000) >= 400 ? "Heads" : "Tails";
}
// Flip the tails weighted coin
public static string Tails()
{
return r.Next(1000) >= 400 ? "Tails" : "Heads";
}
OK, now that we've modelled the two different coins, we can write a LINQ query that simulates the exact scenario outlined in the puzzle definition.
var query =
// run the test 1 million times
from e in Enumerable.Range(1,1000000)
// take a coin from the bag
let isHeads = r.Next() % 2 == 0
// flip the coin 5 times
let results = isHeads
// calling our weighted to heads function
? Enumerable.Range(0,5).Select(_ => Heads()).ToArray()
// or call our weighted to tails function
: Enumerable.Range(0,5).Select(_ => Tails()).ToArray()
// we're only results where we managed to get 3x heads in a row
where results.Count(x => x == "Heads") == 3
select isHeads;
If you'd like to play with this, I've uploaded the solution to "LINQPad Instant Share".
Enjoy!
Comments