Skip to content

Commit 953b143

Browse files
committed
EPI: uniform random number (py)
1 parent 421a2ff commit 953b143

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

elements-of-programming-interviews/problem_mapping.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ problem_mapping = {
150150
"total": 7
151151
},
152152
"Python: uniform_random_number.py": {
153-
"passed": 0,
153+
"passed": 7,
154154
"total": 7
155155
}
156156
},

elements-of-programming-interviews/python/uniform_random_number.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,36 @@ def zero_one_random():
1111
return random.randrange(2)
1212

1313

14+
def uniform_random_wrong(lower_bound: int, upper_bound: int) -> int:
15+
# How about a binary search where hi vs lo is chosen randomly?
16+
# This doesn't work, because numbers towards the middle of the array
17+
# have a higher chance of being chosen than ones closer to the edge (there)
18+
# are more paths leading to them.
19+
while lower_bound <= upper_bound:
20+
mid = (lower_bound + upper_bound) // 2
21+
if zero_one_random():
22+
lower_bound = mid + 1
23+
else:
24+
upper_bound = mid - 1
25+
return lower_bound
26+
27+
1428
def uniform_random(lower_bound: int, upper_bound: int) -> int:
15-
# TODO - you fill in here.
16-
return 0
29+
"""
30+
We want to randomly generate a value in [lo, hi]. Note that if we can generate a value
31+
from [0, hi-lo], we can just add it to lo, which will range from lo (if the number is 0)
32+
to hi (if the number is hi-lo, since hi-lo+lo = hi). To generate a number from 0 to hi-lo,
33+
this function uses a dumb strategy of determining how many bits are in hi-lo, then selecting
34+
a value for each of those bits via zero_one_random(). If we overshoot hi-lo, we just retry.
35+
This might not work (e.g. suppose hi = 2^30 + c and lo = 1, so hi-lo is 30 bits long; we have
36+
potentially 1073741824 30-bit values that exceed 2^30, so we could be retrying for a long time.
37+
"""
38+
k = upper_bound-lower_bound
39+
bits = len(bin(k)[2:])
40+
val = k+1
41+
while val > k:
42+
val = int(''.join([str(zero_one_random()) for i in range(bits)]), 2)
43+
return val+lower_bound
1744

1845

1946
@enable_executor_hook
@@ -33,7 +60,10 @@ def uniform_random_runner(executor, lower_bound, upper_bound):
3360

3461

3562
if __name__ == '__main__':
63+
# print(uniform_random(0, 10))
64+
# """
3665
exit(
3766
generic_test.generic_test_main('uniform_random_number.py',
3867
'uniform_random_number.tsv',
3968
uniform_random_wrapper))
69+
# """

0 commit comments

Comments
 (0)