Showing posts with label Puzzles. Show all posts
Showing posts with label Puzzles. Show all posts

Wednesday, November 23, 2011

Puzzler Solution: Prisoners and Hats and a Jungle

Can’t believe it’s been 2 months since I posted the puzzle. I’ve been involved in test automation using Selenium WebDriver over last couple of months and it has been a great experience designing and coding the test suite. The 1st step is complete - smoke tests for 2 of our applications have been automated and can be run on different browsers concurrently. Now we’re moving to the next steps (which are still TBD). I have lots of ideas in my head but I have to evaluate their feasibility and to break them into different phases so we can realize the added value as we continue to improve the automation suite.

Back to the puzzler solution. For reference, here is the puzzle statement and the code. My implementation of the guessStrategy method is below.

The strategy is that the 1st person to guess speaks the color of the odd hats ahead. So if the (number of black hats ahead) % 2 == 0, the guess is “Black” (lines 4-8). How does it help that person? It doesn’t, that prisoner is unlucky enough to be the 1st one to guess (end of the line) and has a 50% chance. But the rest of the prisoners can guess the color of their hat correctly now that they know the initial guess, all guesses since then and the color of hats ahead. So for example, if the 1st prisoner guesses black, there must be odd black hats ahead. Now if the 2nd prisoner sees odd black hats ahead, s/he must be wearing a white hat because the previous prisoner also saw odd black hats. And the logic goes on like that…if the nth prisoner sees odd number of black hats, and previously, odd number of people have guessed black, then s/he must be wearing a white hat (lines 13-23).
   1: public static char guessStrategy(String prevGuesses, String remArr) {
2: int numB = getNumOfChars(remArr, 'B');
3: int numPrevB;
4: if (prevGuesses.length() == 0) { // initial guess
5: if (numB % 2 == 0)
6: return 'W'; // if B is even, return W
7: else
8: return 'B'; // else return B
9: } else {
10: // strategy: if previously even number of people have said black,
11: // and I see even black hats, I have a white hat, else black
12: numPrevB = getNumOfChars(prevGuesses, 'B');
13: if (numPrevB % 2 == 0) {
14: if (numB % 2 == 0)
15: return 'W';
16: else
17: return 'B';
18: } else {
19: if (numB % 2 == 0)
20: return 'B';
21: else
22: return 'W';
23: }
24: }
25: }
26: 
27: /**
28: * @param arr
29: * @param ch
30: * @return number of times the specified char appears in the array
31: */
32: public static int getNumOfChars(String arr, char ch) {
33: int num = 0;
34: for (int i = 0; i < arr.length(); i++) {
35: if (arr.charAt(i) == ch)
36: num++;
37: }
38: return num;
39: }

Thursday, September 29, 2011

Puzzler: Prisoners and Hats and a Jungle, Oh My!

This puzzler was mentioned in Car Talk sometime ago and I really liked it. In brief, it goes like this:
A prison has 30 prisoners sentenced to be executed and the warden, who has the authority to pardon, decides to give them a chance to escape the punishment. He will stand all the prisoners in a straight line with each prisoner able to see the heads of all prisoners in front of him but not of those behind him. Next, he will put either a white or black hat on each prisoner’s head and ask them to guess the color of their hat one by one (starting with the 1st prisoner in the back of the line who can see all 29 other prisoners’ heads). If he guesses correctly, he’s pardoned. What is the strategy that the prisoners can use to maximize their chances of being pardoned?
The answer I came up with was grossly wrong so when these guys gave the answer (link to which I’m not posting here but can be found easily), I was intrigued. When listening to the answer, it sounded very simple but when I actually thought about it some more, I had to listen to it again to understand the strategy. For example, does the current prisoner need to know all the previous guesses or only the most previous guess?

I decided to write a simple program for this. The line of prisoners here is a StringBuffer of predefined size (in this case, 30) that is randomly filled with ‘B’ or ‘W’ chars. The objective is to write a method that will be called for each character in the StringBuffer with all the previous guesses (as a String) and remaining series (as a String). The method has to return the current character and should be implemented in such a way as to maximize the correct answers. Here’s the code:
   1: import java.util.Random;
2: public class Test {
3: static int SIZE = 30;
4:
5: public static void main(String[] args){
6: int correctGuesses = 0;
7: StringBuffer pRow = new StringBuffer(SIZE);
8: StringBuffer prevGuesses = new StringBuffer(SIZE-1);
9: char currGuess;
10:
11: Random rnd = new Random(System.currentTimeMillis());
12: //---print the series
13: System.out.print("Series:\t");
14: for (int i=0;i<SIZE;i++){
15: if (rnd.nextInt(2) == 0) //0=black, 1=white
16: pRow.append('B');
17: else pRow.append('W');
18: System.out.print(pRow.charAt(i) + " ");
19: }
20: //---strategy
21: System.out.print("\nStrat:\t");
22:
23: for (int i=0;i<SIZE;i++){
24: currGuess = guessStrategy(prevGuesses.toString(),pRow.substring(i+1));
25: System.out.print(currGuess + " ");
26: if(currGuess == pRow.charAt(i)) correctGuesses++;
27: prevGuesses.append(currGuess);
28: }
29: System.out.print("\nCorrect Guesses=" + correctGuesses);
30: }
31: 
32: public static char guessStrategy(String prevGuesses, String remArr){
33: //random
34: Random rnd = new Random(System.currentTimeMillis());
35: if (rnd.nextInt(2) == 0) //0=black, 1=white
36: return 'B';
37: else return 'W';
38: }
39: }


First, I generate the series and print it (lines 13-19). And then I call the guessStrategy method for each character in the series with all the previous guesses and the remaining series. But currently, there is no strategy and each time, it randomly returns ‘B’ or ‘W’. And obviously, result is that correct guesses average around 15. Your job, should you decide to accept this assignment is to provide a better implementation of the guessStrategy method which maximizes the chances of guessing correctly. If you’re stuck, you can look at the Car Talk website or search on internet to find the answer and then try to implement it.

I’ll post my implementation of the method in a few days. Hopefully it provides enough of a challenge to some people to work on this besides their otherwise busy life.

Thursday, May 28, 2009

12 Balls

Wednesday morning, out of sheer impulse I navigated to Willy Wu’s riddles site consisting of the best puzzle compilation on internet (I added the site to the links section as well). The puzzle that was staring at me was the 12 Balls one:

You have 12 identical-looking balls. One of these balls has a different weight from all the others. You also have a two-pan balance for comparing weights. Using the balance in the smallest number of times possible, determine which ball has the unique weight, and also determine whether it is heavier or lighter than the others.

I figured the solution once I was able to find time to put some random thoughts to this puzzle. I’m currently working on creating a visio diagram to display the solution but if you’re not familiar with the puzzle and feel challenged enough to attempt a stab at it without searching online for a solution, feel free.

If after putting some time into it, you’re feeling frustrated and just want the solution, go ahead and google. If you just want some hint(s) and not the complete solution, let me know and I’ll post it before I post the solution.