Water Bottles

Updated on 11 July, 2025
Water Bottles header image

Problem Statement

In this problem, you are initially given numBottles, which are entirely full of water. There exists a system where you can exchange numExchange empty water bottles to receive one full bottle in return. After consuming a full bottle, it becomes empty. Using these rules, you need to determine the maximum number of water bottles you can consume. You start with the numBottles and continue drinking and exchanging as long as possible under the given constraints of numExchange.

Examples

Example 1

Input:

numBottles = 9, numExchange = 3

Output:

13

Explanation:

You can exchange 3 empty bottles to get 1 full water bottle.
Number of water bottles you can drink: 9 + 3 + 1 = 13.

Example 2

Input:

numBottles = 15, numExchange = 4

Output:

19

Explanation:

You can exchange 4 empty bottles to get 1 full water bottle.
Number of water bottles you can drink: 15 + 3 + 1 = 19.

Constraints

  • 1 <= numBottles <= 100
  • 2 <= numExchange <= 100

Approach and Intuition

  1. Start with the initial number of full bottles (numBottles).
  2. Continue the process of drinking from these bottles, turning them into empties, and then exchanging a specific number (numExchange) of empty bottles to get a new full bottle.
  3. Implement this logic:
    • Drink from all available full bottles and tally these as drunk bottles.
    • See how many new bottles can be gained by exchanging the empty ones.
    • If the empties are not enough to exchange for at least one bottle, the loop stops.
    • Otherwise, obtain the new bottles, add to your count, and repeat the procedure.
  4. This process will maximize the number of bottles you drink until you cannot exchange the empties for a new full bottle anymore, effectively squeezing the most utility from the given resource limits.

Example realizations from the provided scenarios illustrate this principle:

  • For numBottles = 9, numExchange = 3: Starting with 9 bottles, after consuming them, you get 9 empties. Exchange these for 3 new bottles, drink them to get 3 more empties, and finally exchange these for 1 more bottle. Total drunk bottles tally to 13.
  • For numBottles = 15, numExchange = 4: Starting with 15 bottles, after consuming them, you collect 15 empty bottles. These can be exchanged for 3 new bottles (12 empties needed, leave 3 behind). Drink the 3 new bottles and combine remainders to get 1 more. The total tally here comes to 19.

Solutions

  • C++
cpp
class Solution {
public:
    int calculateTotalDrinks(int initialBottles, int exchangeRate) {
        int totalDrank = 0;
    
        while (initialBottles >= exchangeRate) {
            int newBottles = initialBottles / exchangeRate;
            totalDrank += exchangeRate * newBottles;
            initialBottles -= exchangeRate * newBottles;
            initialBottles += newBottles;
        }
    
        return totalDrank + initialBottles;
    }
};

In this solution, you effectively tackle the problem of calculating the total number of water bottles one can drink given an initial number of bottles and an exchange rate for empty bottles. The process involves repeatedly exchanging empty bottles for new ones until you cannot meet the exchange rate requirement. Here’s a breakdown of the implemented C++ solution:

  • Start with a function calculateTotalDrinks, which accepts initialBottles and exchangeRate as parameters.
  • Initialize a counter, totalDrank, to zero. This counter will accumulate the count of bottles drank.
  • Use a loop to simulate drinking and exchanging bottles:
    • Calculate the number of new bottles you can get by dividing initialBottles by exchangeRate.
    • Increase totalDrank by the number of bottles consumed, which is the product of the exchange rate and the new bottles gained.
    • Decrease initialBottles by the same number (the empty bottles handed in for exchange).
    • Increment initialBottles by the number of new full bottles obtained through the exchange.
  • Exit the loop when initialBottles is less than the exchangeRate, implying no further exchanges can be made.
  • Add any remaining initialBottles that couldn’t be exchanged to totalDrank.
  • Return the value of totalDrank, which now represents the total bottles consumed, including those that were drunk directly and those obtained through exchange.

This method ensures all possible bottles to be consumed are accounted for, given the limitations set by the exchange rate.

  • Java
java
class Solution {
    
    public int calculateDrinks(int totalBottles, int exchangeRate) {
        int totalConsumed = 0;
    
        while (totalBottles >= exchangeRate) {
            int newBottles = totalBottles / exchangeRate;
    
            totalConsumed += exchangeRate * newBottles;
            totalBottles -= exchangeRate * newBottles;
    
            totalBottles += newBottles;
        }
    
        return totalConsumed + totalBottles;
    }
}

The solution provided tackles the problem of determining the maximum number of drinks one can consume given a certain number of water bottles and an exchange rate for how many empty bottles can be traded for a new bottle. This is implemented in Java.

The method calculateDrinks accepts two parameters:

  • totalBottles, representing the initial number of full water bottles available.
  • exchangeRate, indicating how many empty bottles are needed to obtain a new full bottle.

Here is a step-by-step breakdown of the method:

  1. Initialize totalConsumed to 0. This variable will accumulate the total number of drinks consumed.

  2. Enter a loop that continues as long as totalBottles is greater than or equal to the exchangeRate. This loop is crucial as it simulates the continuous process of consuming bottles and then exchanging the empties for new bottles.

  3. Within the loop:

    • Calculate newBottles, which is the number of new bottles you can get by dividing totalBottles by exchangeRate.
    • Increase totalConsumed by the number of bottles consumed in this cycle, which would be exchangeRate * newBottles.
    • Reduce totalBottles by the same number, essentially simulating that these bottles have been consumed and cannot be reused as full bottles.
    • Add the newBottles to totalBottles, representing the new bottles obtained from exchanging the empty ones.
  4. Eventually, when totalBottles is less than exchangeRate, exit the loop. At this point, add the remaining totalBottles to totalConsumed.

  5. Return totalConsumed + totalBottles as the result. This gives the total number of bottles consumed, including those that can't be exchanged anymore.

This solution effectively calculates the maximum consumption of water bottles based on an exchange system, ensuring that every possible bottle, either initially full or obtained through exchange, is accounted for in the total consumption.

  • Python
python
class Solution:
    def calculateDrinks(self, bottles: int, exchange: int) -> int:
        total_drinks = 0
        while bottles >= exchange:
            full_exchanges = bottles // exchange
    
            total_drinks += exchange * full_exchanges
            bottles -= exchange * full_exchanges
    
            bottles += full_exchanges
    
        return total_drinks + bottles

This Python solution addresses the problem of determining how many total drinks one can have given an initial number of water bottles and an ability to exchange a set number of empty bottles for a new one. The calculateDrinks function efficiently computes this by continually trading in empty bottles for full ones until no further trades can be made.

  • Initialize total_drinks to zero. This variable will keep count of all the drinks you can have.
  • Use a while loop to perform the exchange as long as the number of bottles you have is greater than or equal to the number required for an exchange.
  • Inside the loop, calculate full_exchanges, which represents the number of full bottles you can get by exchanging empty ones.
  • Increase total_drinks by the number of bottles consumed, which at each step is exchange * full_exchanges.
  • Decrease the count of bottles by the same number, since they are exchanged for new ones.
  • Add back the full bottles received from the exchange to have them available in the next iteration.

When no more exchanges can be performed, add the remaining bottles to the total drinks since these can also be consumed, and return total_drinks + bottles as the final result. This solution ensures that all bottles, whether exchanged or not, are accounted for.

Comments

No comments yet.