Water Bottles

Solution 1: Recursion

def numWaterBottles(numBottles, numExchange):
    return recurse(numBottles, 0, numExchange)
 
def recurse(numBottles, numEmptyBottles, numExchange):
    if numBottles == 0:
        return 0
    return numBottles + recurse(
        *divmod(numBottles + numEmptyBottles, numExchange),
        numExchange
    )

Solution 2: Simulation

numEmpty = total = 0
while numBottles:
    total += numBottles
    numBottles, numEmpty = divmod(numEmpty + numBottles, numExchange)
return total

Solution 3: One-Line

return numBottles + (numBottles - 1) // (numExchange - 1)

Intuition:

  • How do we consume the empty bottles without having multiple steps? Borrow a full bottle, drink it, take numExchange - 1 empty bottles, exchange for a full bottle, and return.
  • Also notice the fact that when we have numBottls == numExchange - 1, in fact there’s nowhere to borrow this full bottle, hence numBottls - 1.