A few weeks ago a colleague of mine proposed me an interesting problem which years ago he found very challenging and a lot of fun and of course you can’t just tell this kind of thing to a computer scientist and expect no reaction whatsoever, so I went ahead and started thinking of a solution. The first thing to say about this problem is that it can have more than one solution and that the only way to compare them is by calculating the average time it would take for the problem to be solved following that particular approach. The goal of this post is not to do a mathematical examination of all the possible solutions but only to talk about the solution I came up with, leaving the problem open to the readers imagination. If you come up with more solutions, please don’t hesitate to comment about them! The problem statement is the following:
There is a prison with 100 prisoners isolated from each other and a very bored prison warden who proposes a challenge: each day he will select a prisoner at random and put him in a special room fitted with nothing more than a lamp and he will give that particular prisoner the opportunity to tell him when all of the prisoners have been at least once in that room. If the prisoner is right all of them would be given a pardon and if he is wrong all of them die. Since the prisoners are isolated, he will give them one hour to elaborate a plan between them, after which they won’t be able to communicate again until the game is over.
At first glance, it’s obvious that the only link between each prisoner in the room and the next one is the lamp, so it has to be used as a method for communicating the next prisoner some message. Defining the lamp as a method to convey a message seems trivial, but given that it can only hold one bit of information it seems that we need something more in order for this message to have a meaning, we will call this extra information the context of the message.
Now, the main difficulty of the problem is defining a context with which to assign a meaning to the message, or rather define how the prisoner going into the room will interpret the lamp being on or off. One way to look at it is that we need something to accumulate information so that whenever a prisoner goes into the room he has a bigger picture than just one bit, I propose this accumulator to be another prisoner which will interpret the message left in the room and accumulate the information, thus acting like an 100 bit message himself.
Given that one of our prisoners is an 100 bit accumulator, who does this job has to be decided during the planning hour, and also how and what the other prisoners should convey through the lamp. For this particular approach, each of the other prisoners will have to inform the accumulator if they have been in the room or not by turning the lamp on, but they will only do so if when they entered the room the lamp was off and if it’s the first time they’ve been there, this way the lamp will inform the accumulator that at least one of the other prisoners has been there for the first time. Finally, the accumulator has to turn off the lamp every time he goes into the room and finds it on, so that a new cycle can start.
With this solution, the accumulator prisoner (or counter as I called it in the following code) will have to go at least 99 times to the room to be able to tell the warden with complete certainty that all of the prisoners have already been there. Considering the best case, this would take him as least as 198 days if he went after each prisoner and for every prisoner this was the first time. If we assume now that on every 100 day cycle at least one new prisoner has been into the prison and that the accumulator is always the last, it would take him 9900 days which is quite a bad prospect for the prisoners and probably most of them will be already out by then.
The following code attempts to simulate the situation by creating random numbers as if it was the warden picking a random prisoner, it also includes the solution by having the accumulator (counter) prisoner and a lookup table for each of the prisoners (in order to store if they have been in or not).
int main() { // ID of the prisoner in charge of counting const int prisoner_counter_id = 0; // Prisoner state (been with lamp off or not) int prisoner_lookup[100]; // Number of counts by prisoner in charge of counting int prisoner_counter = 0; // State of the lamp int lamp = 0; // Current prisoner in the room int prisoner_room; memset(prisoner_lookup, 0, 100*sizeof(int)); while (prisoner_counter < 99) { // Select a random prisoner prisoner_room = rand() % 100; if (prisoner_room == prisoner_counter_id) { // Random prisoner is the counter // If the lamp is on, count it prisoner_counter += lamp; // Turn off the lamp lamp = 0; } else if ((lamp == 0) && (prisoner_lookup[prisoner_room] == 0)) { // If the lamp is off and prisoners "first time" // Turns on the lamp lamp = 1; // He has now completed his visit to the room prisoner_lookup[prisoner_room] = 1; } } printf("Counter counts %d\n", prisoner_counter + 1); return 0; }
As I said, there are other solutions to this problem although it seems a bit difficult to come up with them once you already have a solution. I suggest you give it a try and see what you can get. If you still can’t find any other solutions, I’m sure a fast search will give you many results, but what would be the challenge in that?
Lamp Image |
Posted In:
Tagged:
- C
- Problem
If this solution were presented, I would expect the other prisoners to bludgeon the suggester, in order to reduce the count to 99. 😉
Since all of the solutions make assumptions (like this one assuming the light will not be turned on/off by the warden) I will take that route as well. Divide the room into a 10×10 cell. The first day, the prisoner puts it in the bottom left corner, cell 0-0. Each time a prisoner is in the room for the first time, he moves the lamp 1/10th along the path to the opposite wall, or back to the front wall and further to the right to start the next set of 10. Once a prisoner moves it to the top right corner, cell 10×10, he knows all prisoners have been there, and it will be the earliest possible time to answer yes.
@Fosco, very creative, but query whether that assumption is consistent with the problem statement insofar as it provides that the room is “fitted with” a lamp. 😉
At the beginning, the prisoners select a leader. Whenever a person (with the exception of the leader) comes into a room, he turns the lights on (but he does this only once). If the lights are already on, he does nothing. When the leader goes into the room, he turns off the lights. When he will have turned off the lights 99 times, he is 100% sure that everyone has been in the room.
First person smashes the bulb, selects 99 pieces (counting very carefully), stashes them in a corner. Each person removes a piece on their first visit.
Hey, (i am not a native english speaker so please oversee my mistakes) the Problem inspired me and my friend, so we thought a while about it, and we descided its better to find a solution wich is not a 100% sure, but much more quicker.
Because if u wait untill the one Leader was 100 Times in the room it is likely (if they are been pickt absolutely random) that all the onter persons also have been 100 times in the room wich brings us to a total of 100×100 = 10.000 Days on average to solve the Problem, but this is around 30 Years wich is a little bit much.
So we tried to just count 25 prisoners who have been in the room at least 4 times. (we let ouer computer do that 10.000.000 Times; neded about 2h) and we had an average of about 3000 days to acomplish and in about 98,35% of the tries the Leader was right. BUT, in 1,65% of all tries the Prisoners died.
So we improoved, and came up with counting only 7 prisoners who have been at least 7 times in the room. (and again we did that 10.000.000 times) and with this we had more than 99.98% the right awnser and it only took about 2300 days.
I dont know if this method is good, but it is more realistic than waiting 10.000 days 🙂
What do u think?