Time for another probability brain teaser. This one comes to us from Braingle. Here’s a quick rundown of the problem:
You are a prisoner sentenced to death. The Emperor offers you a chance to live by playing a simple game. He gives you 50 black marbles, 50 white marbles and 2 empty bowls. He then says, “Divide these 100 marbles into these 2 bowls. You can divide them any way you like as long as you use all the marbles. Then I will blindfold you and mix the bowls around. You then can choose one bowl and remove ONE marble. If the marble is WHITE you will live, but if the marble is BLACK… you will die.”
How do I want to solve this? Unless I can figure out the answer with my own intuition, we’re going to have to brute force this thing. So, the most obvious thing to do would be set up a simulation where we:
• Figure out all possible marble arrangement scenarios
• Run each scenario a lot of times and check how many times we survive
• Sort the results by % of times we survivce
The fun part here is building a digital model of the problem. We have a couple of pieces to account for. Two “pouches,” 100 “marbles,” and a random selector. For the pouches, we’ll use an array of two arrays, and fill it with “marble” elements, and a the ruby method sample
to randomly choose which “pouch” to pick from, and sample
again to pick an element from the sub-array (the pouch). In order to set this experiment up to run all at once, we’ll collect all the pouches in a hash. This way, we can store both the pouches and some descriptive info so we can discern the results later.
1 2 3 4 5 6 7 8 9 |
|
The tricky part from a Ruby perspective is going to be populating the arrays with every possible marble arrangement. There are no limitations on how you can arrange the marbles. We don’t need to set up both pouches, just figure out what one pouch looks like, and make the other pouch the inverse.
This means there can be anywhere between 0-50 white marbles in one pouch, accompanied by anywhere from 0-50 black marbles. So 51 possible white marble arrangements, each with 51 possible black marble arrangements. 51 * 51 means there are 2601 possible combinations.
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 |
|
So now, we have a hash where the key describes the contents of the first pouch (we’ll just infer the contents of the second pouch): something like “20 white, 30 black.” The value is then an array with two arrays representing the pouches. But instead of “white” and “black”, we’ll use the values true
and false
to represent white and black since it will be pretty easy to translate the boolean into passing or failing the Emperor’s test.
Now that the pouches are filled, its time to run some tests. For each set of pouches, let’s say we’re going to run the test 10,000 times and store the results in a results = {}
hash. In short, the emperor will randomly choose a pouch, and then randomly choose an element from that pouch. If it comes back true, add 1 point to the current marble configuration. For argument’s sake, we’ll say that if you choose a pouch with zero marbles in it, that will count as a death sentence!
1 2 3 4 5 6 7 8 |
|
Now all we have to do is sort the results hash and print the winner.
1 2 3 4 5 6 7 8 |
|
We can delegate the entire operation to a single call
method.
1 2 3 4 5 |
|
So running the following Emperor.new(100).call
gives us the following result:
1 white, 0 black will win 74.96% of the time
Interesting! The best scenario is putting one white marble in the first pouch, and the remaining 49 white and all 50 of the black marbles in the second pouch.
Why is this the case? An even split of marbles will produce odds of 50%. But if we limit the range of possiblities for the one of the pouches, we can guarantee that every time the emperor picks that pouch we get the desired outcome, while picking the second pouch is almost a 50/50 shot. So we get closer and closer to 75% chance of living. That’s really the best odds this poor sap can hope for.
Complete code
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 |
|