25.03.2013 Views

Cracking the Coding Interview - Fooo

Cracking the Coding Interview - Fooo

Cracking the Coding Interview - Fooo

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Solutions to Chapter 19 | Moderate<br />

19 10 Write a method to generate a random number between 1 and 7, given a method<br />

that generates a random number between 1 and 5 (i e , implement rand7() using<br />

rand5())<br />

SOLUTION<br />

2 7 7<br />

<strong>Cracking</strong> <strong>the</strong> <strong>Coding</strong> <strong>Interview</strong> | Additional Review Problems<br />

pg 90<br />

First, observe that we cannot do this in a guaranteed finite amount of time Why? Let’s see by<br />

a parallel example: How would you use rand2() to create rand3()?<br />

Observe that each call of rand2() and <strong>the</strong> corresponding decision you make can be represented<br />

by a decision tree On each node, you have two branches You take <strong>the</strong> left one when<br />

rand2() equals 0 (which happens with 1/2 probability) You take <strong>the</strong> right one when rand2()<br />

equals 1 (which happens with 1/2 probability) You continue branching left and right as you<br />

continue to call 1/2 When you reach a leaf, you return a result of 1, 2 or 3 (your rand3() results)<br />

» What’s <strong>the</strong> probability of taking each branch? 1/2<br />

» What’s <strong>the</strong> probability to reach a particular leaf node? 1/2^j (for some j)<br />

» What <strong>the</strong> probability of returning 3 (for example)? We could compute this by summing<br />

up <strong>the</strong> probabilities of reaching each leaf node with value 3 Each of <strong>the</strong>se paths has<br />

probability 1/2^j, so we know that <strong>the</strong> total probability of returning 3 must be a series<br />

of terms of reciprocal powers of 2 (e g , 1/2^x + 1/2^y + 1/2^z + …)<br />

We also know, however, that <strong>the</strong> probability of returning 3 must be 1/3 (because rand3()<br />

should be perfectly random) Can you find a series of reciprocal powers of 2 that sum to 1/3?<br />

No, because 3 and 2 are relatively prime<br />

We can similarly conclude that to solve this problem, we will need to accept a small (infinitesimally<br />

small) chance that this process will repeat forever That’s ok<br />

So, how do we solve this?<br />

In order to generate a random number between 1 and 7, we just need to uniformly generate<br />

a larger range than we are looking for and <strong>the</strong>n repeatedly sample until we get a number that<br />

is good for us We will generate a base 5 number with two places with two calls to <strong>the</strong> RNG<br />

public static int rand7() {<br />

while (true) {<br />

int num = 5 * (rand5() - 1) + (rand5() - 1);<br />

if (num < 21) return (num % 7 + 1);<br />

}<br />

}

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!