Water Bottles II

medium math simulation greedy

Problem

You start with numBottles full water bottles. Each turn you may drink any number of full bottles (each becomes empty), or exchange numExchange empty bottles for one full bottle — and right after that exchange numExchange increases by one. You can never reuse the same numExchange price for two batches. Return the maximum number of water bottles you can drink.

InputnumBottles = 13, numExchange = 6
Output15
Drink 13. Exchange 6 empties (price→7) for 1, drink it (14). Exchange 7 empties (price→8) for 1, drink it (15). Now only 2 empties remain, less than 8, so stop.

def maxBottlesDrunk(numBottles, numExchange):
    drunk = numBottles            # drink every full bottle right away
    empty = numBottles            # each one drunk becomes an empty
    while empty >= numExchange:    # can we still afford an exchange?
        empty -= numExchange      # hand over numExchange empties
        numExchange += 1          # the price goes up by one
        drunk += 1                # we get one full bottle and drink it
        empty += 1                # that bottle is now empty too
    return drunk                  # no exchange possible -> answer
function maxBottlesDrunk(numBottles, numExchange) {
  let drunk = numBottles;          // drink every full bottle right away
  let empty = numBottles;          // each one drunk becomes an empty
  while (empty >= numExchange) {    // can we still afford an exchange?
    empty -= numExchange;          // hand over numExchange empties
    numExchange += 1;              // the price goes up by one
    drunk += 1;                    // we get one full bottle and drink it
    empty += 1;                    // that bottle is now empty too
  }
  return drunk;                    // no exchange possible -> answer
}
int maxBottlesDrunk(int numBottles, int numExchange) {
    int drunk = numBottles;          // drink every full bottle right away
    int empty = numBottles;          // each one drunk becomes an empty
    while (empty >= numExchange) {    // can we still afford an exchange?
        empty -= numExchange;        // hand over numExchange empties
        numExchange += 1;            // the price goes up by one
        drunk += 1;                  // we get one full bottle and drink it
        empty += 1;                  // that bottle is now empty too
    }
    return drunk;                    // no exchange possible -> answer
}
int maxBottlesDrunk(int numBottles, int numExchange) {
    int drunk = numBottles;          // drink every full bottle right away
    int empty = numBottles;          // each one drunk becomes an empty
    while (empty >= numExchange) {    // can we still afford an exchange?
        empty -= numExchange;        // hand over numExchange empties
        numExchange += 1;            // the price goes up by one
        drunk += 1;                  // we get one full bottle and drink it
        empty += 1;                  // that bottle is now empty too
    }
    return drunk;                    // no exchange possible -> answer
}
Time: O(√numBottles) Space: O(1)