Guess the answer, then check it
Find the smallest speed that finishes the job in time, by halving the range of possible speeds. About 15 minutes.
A check that only goes one way
A monkey has piles of bananas and must finish them all within a number of hours. Each hour it picks one pile and eats up to its speed from it. If a pile has fewer left, the monkey wastes the rest of that hour. What is the smallest speed that finishes in time?
Checking a given speed is easy: add up how many hours each pile takes, rounding up. And a faster speed never takes more hours. That one-way behaviour is what lets you halve.
def hours_needed(speed):
total = 0
for pile in piles:
total += (pile + speed - 1) // speed
return totalAny speed from 1 to 11 might be the answer. Try the middle, speed 6.
Halve the range
The smallest possible speed is 1 and the largest worth trying is the biggest pile, since faster than that gains nothing. Look at the middle speed. If it finishes in time, the answer is that speed or something smaller, so keep the lower half including mid. If not, the answer is bigger, so move past mid.
Stop when the range is a single speed. That speed is the first yes.
low, high = 1, max(piles)
while low < high:
mid = (low + high) // 2
if hours_needed(mid) <= hours:
high = mid
else:
low = mid + 1
return lowA speed of 7 finishes in time. What does that tell you about a speed of 9?
- A9 also finishes in time, since faster is never slower
- B9 might fail
- CYou have to test 9 to know
Show the answer
9 also finishes in time, since faster is never slower. The check is one-way, so every speed above a working speed works too.
Smallest eating speed
piles[i] is the number of bananas in pile i. A monkey must finish all the piles within hours hours. Each hour it chooses one pile and eats up to k bananas from it; if the pile has fewer than k, it eats them all and does nothing else that hour. Return the smallest whole k that lets the monkey finish in time. It is guaranteed that hours is at least the number of piles.
piles = [3, 6, 7, 11], hours = 8 → 4
1 ≤ piles ≤ 100,000 · 1 ≤ pile ≤ 1,000,000,000 · piles ≤ hours ≤ 1,000,000,000