Answer: The easiest way to do this would be to start from the first floor and drop the egg. If it doesn’t break, move on to the next floor. If it does break, then we know the maximum floor the egg will survive is 0. If we continue this process, we will easily find out the maximum floors the egg will survive with just one egg. So the maximum number of tries is 100 that is when the egg survives even at the 100th floor.

Can we do better? Of course we can. Let’s start at the second floor. If the egg breaks, then we can use the second egg to go back to the first floor and try again. If it does not break, then we can go ahead and try on the 4th floor (in multiples of 2). If it ever breaks, say at floor x, then we know it survived floor x-2. That leaves us with just floor x-1 to try with the second egg. So what is the maximum number of tries possible? It occurs when the egg survives 98 or 99 floors. It will take 50 tries to reach floor 100 and one more egg to try on the 99th floor so the total is 51 tries. Wow, that is almost half of what we had last time.

Can we do even better? Yes we can (Bob, the builder). What if we try at intervals of 3? Applying the same logic as the previous case, we need a max of 35 tries to find out the information (33 tries to reach 99th floor and 2 more on 97th and 98th floor).

Interval – Maximum tries

1 – 100

2 – 51

3 – 35

4 – 29

5 – 25

6 – 21

7 – 20

8 – 19

9 – 19

10 – 19

11 – 19

12 – 19

13 – 19

14 – 20

15 – 20

16 – 21

So picking any one of the intervals with 19 maximum tries would be fine.

Update: Thanks to RiderOfGiraffes for this solution.

Instead of taking equal intervals, we can increase the number of floors by one less than the previous increment. For example, let’s first try at floor 14. If it breaks, then we need 13 more tries to find the solution. If it doesn’t break, then we should try floor 27 (14 + 13). If it breaks, we need 12 more tries to find the solution. So the initial 2 tries plus the additional 12 tries would still be 14 tries in total. If it doesn’t break, we can try 39 (27 + 12) and so on. Using 14 as the initial floor, we can reach up to floor 105 (14 + 13 + 12 + … + 1) before we need more than 14 tries. Since we only need to cover 100 floors, 14 tries is sufficient to find the solution.

Therefore, 14 is the least number of tries to find out the solution.

]]>Don’t just use pop() to “dig” through your stack to find the max—do something that lets you return the max in constant time.

Solution

We could have an instance variable where we hold the max, but there’s a problem—when we pop that item from our stack it’s no longer the max. Now we have to “dig” through our stack to find the new max. Ideally we’d keep track of the current max as well as what the new max will be when that max is popped.

The trick is to have two instances of Stack inside our MaxStack. One holds the actual stack contents, while the other (call it maxesStack) holds the maxes. Whenever we push() an item, if it’s larger than the top item in maxesStack, we also push it to maxesStack. Whenever we pop() an item, if it’s the same as the top item in maxesStack(), we also pop() it from maxesStack.

So at any given point we can get the overall max in constant time be peeking at the top item in maxesStack.

]]>]]>“How many unique areas of human knowledge have the right size of passionate users to make it as a Stack Exchange site?”

Solving the initial problem of just reversing a string can either be a huge help or a frustrating hinderance. most likely the first attempt will be to solve it the same way, by swapping letters at the front of the string with letters at the back, and then adding some logic to keep the words in order. this attempt will lead to confusion pretty quickly.

for example, if we start by figuring out that “the” is 3 letters long and then try to put the “t” from “the” where the “l” from “blue” is, we encounter a problem. where do we put the “l” from “blue”? hmm… well we could have also figured out how long “blue” was and that would tell us where to put the “l” at… but the “e” from “blue” needs to go into the space after “the”. argh. its getting quite confusing. in fact, i would be delighted to even see a solution to this problem using this attack method. i don’t think its impossible, but i think it is so complex that it’s not worth pursuing.

here’s a hint. remember before when we just reversed “the house is blue”? what happened?

initial: the house is blue

reverse: eulb si esuoh eht

look at the result for a minute. notice anything? if you still don’t see it, try this.

initial: the house is blue

reverse: eulb si esuoh eht

wanted : blue is house the

the solution can be attained by first reversing the string normally, and then just reversing each word.

]]>

question: what state are the doors in after the last pass? which are open which are closed?

For example, after the first pass every door is open. on the second pass you only visit the even doors (2,4,6,8…) so now the even doors are closed and the odd ones are opened. the third time through you will close door 3 (opened from the first pass), open door 6 (closed from the second pass), etc..

question: what state are the doors in after the last pass? which are open which are closed?

solution: you can figure out that for any given door, say door #42, you will visit it for every divisor it has. so 42 has 1 & 42, 2 & 21, 3 & 14, 6 & 7. so on pass 1 i will open the door, pass 2 i will close it, pass 3 open, pass 6 close, pass 7 open, pass 14 close, pass 21 open, pass 42 close. for every pair of divisors the door will just end up back in its initial state. so you might think that every door will end up closed? well what about door #9. 9 has the divisors 1 & 9, 3 & 3. but 3 is repeated because 9 is a perfect square, so you will only visit door #9, on pass 1, 3, and 9… leaving it open at the end. only perfect square doors will be open at the end.

]]>

Chance! chance is easy if you know how to do the formula. we know that we have two choices to make. first we’ll pick a jar, and each jar will have a 1/2 chance of being picked. then we’ll pick a marble, and depending how we stack the marbles, we’ll have a (# of red marbles in jar)/(# of total marbles in jar) chance of getting a red one.

for example, say we put all the red marbles into **jar A** and all the blue ones into **jar B**. then our chances for picking a red one are:

1/2 chance we pick **jar A** * 50/50 chance we pick a red marble

1/2 chance we pick **jar B** * 0/50 chance we pick a red marble

do the math and you get 1/2 chance for a red marble from **jar A** and a 0/2 chance for a red marble from **jar B**. add ‘em up and you get the result = 1/2 chance for picking a red marble.

think about it for awhile and see if you can figure out the right combination. we had a 50/50 (guaranteed) chance in picking a red marble from **jar A**, but we didn’t have to have 50 red marbles in there to guarantee those fantastic odds, did we? we could’ve just left 1 red marble in there and the odds are still 1/1. then we can take all those other marbles and throw them in **jar B** to help the odds out there.

let’s look at those chances:

1/2 we pick **jar A** * 1/1 we pick a red marble

1/2 we pick **jar B** * 49/99 we pick a red marble

do the math and add them up to get 1/2 + 49/198 = 148/198, which is almost 3/4.

we can prove these are the best odds in a somewhat non-formal way as follows. our goal is to maximize the odds of picking a red marble. therefore we can subdivide this goal into maximizing the odds of picking a red marble in **jar A** and maximizing the odds of picking a red marble in **jar B**. if we do that, then we will have achieved our goal. it is true that by placing more red marbles into a jar we will increase the chances of picking a red marble. it is also true that by reducing the number of blue marbles in a jar we will increase the odds also. we’ve maximized the odds in **jar A** since 1/1 is the maximum odds by reducing the number of blue marbles to 0 (the minimum). we’ve also maximized the number of red marbles in **jar B**. if we added any more red marbles to **jar B** we would have to take them out of **jar A** which reduce the odds there to 0 (very bad). if we took any more blue ones out of **jar B** we would have to put them in **jar A** which reduce the odds there by 50% (very bad).

it wasn’t really a good proof, but QED anyway

]]>

solution: this puzzle falls pretty high on my aha scale. my first inclination when i heard it was to think “ok, so i just need to sum up the distances that the bee travels…” but then you quickly realize that its a difficult (not impossible) summation which the interviewer could hardly expect you to answer (unless i guess if you are looking for a job as a quant). “there must be a trick” you say. eh, sort of i guess, enough to say that this question is a stupid interview question.

the tunnel is 200 miles long. the trains meet in the middle travelling at 100 mph, so it takes them an hour to reach the middle. the bee is travelling 1000 mph for an hour (since its flying the whole time the trains are racing toward one another) – so basically the bee goes 1000 miles.

there is no process to explain, so this question can’t possibly teach you anything about the person. they either know it or they don’t and if they already knew it before you asked, you’re not going to be able to tell when they give you the answer. so don’t ask this question. and if someone asks you this question, just tell them you’ve already heard it before.

]]>

string manipulation functions are great programming questions. they test whether the user can understand and translate into code simple algorithms. string functions test pointer arithmetic which usually shows a knowledgeable programmer. also there are usually multiple solutions, some more efficient than others. plus people use them all the time so they should understand how they work. my favorite is atoi and i start the problem like this:

`int atoi( char* pStr )`

write the definition for this function *without using any built-in functions*. if pStr is null, return 0. if pStr contains non-numeric characters, either return 0 (ok) or return the number derived so far (better) (e.g. if its “123A”, then return 123). assume all numbers are positive. plus or minus signs can be considered non-numeric characters. in order to solve this program, the programmer must understand the difference between the integer 0 and the character ‘0’, and how converting ‘0’ to an int, will not result in 0. in other words, they have to understand what ascii is all about. if they are stuck solving this problem, just ask them first to write:

`charToInt(char c)`

if they can’t do that then they basically missed half the problem. any moderately talented programmer who has a CS degree knows how to convert a char to an int. (note i said convert, not cast. `charToInt('9')`

should return 9.)

when they start to solve the problem you will notice that they must make a choice in how they will process the string – from left to right or right to left. i will discuss both methods and the difficulties encountered in each.

“right to left” – this method starts at the right hand letter of the string and converts that character to an int. it then stores this value after promoting it to its correct “tens” place.

int atoi( char* pStr )

{

int iRetVal = 0;

int iTens = 1;

if ( pStr )

{

char* pCur = pStr;

while (*pCur)

pCur++;

pCur--;

while ( pCur >= pStr && *pCur <= '9' && *pCur >= '0' )

{

iRetVal += ((*pCur - '0') * iTens);

pCur--;

iTens *= 10;

}

}

return iRetVal;

}

“left to right” – this method keeps adding the number and multiplying the result by ten before continuing to the next number. e.g. if you had “6234” and you processed from left to right you’d have 6, then if you kept reading you’d multiply your result by 10 (6*10) to add a zero for where the next number would go. 60, and then you’d slide the 2 into the zero place you just made. 62. do it again, 620, slide the next number in, 623.

int atoi( char* pStr )

{

int iRetVal = 0;

if ( pStr )

{

while ( *pStr && *pStr <= '9' && *pStr >= '0' )

{

iRetVal = (iRetVal * 10) + (*pStr - '0');

pStr++;

}

}

return iRetVal;

}

i think the “left to right” method is a little bit cleaner, or maybe its just cooler. but both are “correct”.

remember that debugging code on paper is somewhat hard. most programmers aren’t used to studying code that much when you can just hit F-7, compile and see if the compiler barfs or not. if you notice an error, just ask them to step through a sample string drawing out what is happening with all the variables and the pointers in every step. they should find their mistake then and fix it (no points deducted).

]]>