File: water-bottles/solution.py

Date: 2026-06-06

Time: 19:42

Purpose

This file solves LeetCode 1518 — Water Bottles. It belongs to the leetcode-implementations repo, where each problem gets its own directory with solution.py, test_solution.py, plan.md, and review.md. This file owns the single algorithm: given an initial count of full bottles and an exchange rate, compute the maximum number of bottles you can drink.

Key Components

numWaterBottles(numBottles: int, numExchange: int) -> int

A standalone function (no class wrapping) that simulates the bottle-exchange process. Contract:

Patterns

Simulation loop with accumulator. Rather than using a closed-form formula, the solution simulates rounds of drinking and exchanging. Each iteration of the while loop represents one exchange round:

1. Integer-divide empties by numExchange to get new_full bottles

2. Update empties to leftover empties + the new bottles (which will themselves become empty after drinking)

3. Accumulate new_full into total

This is the canonical greedy simulation approach for this problem — drink everything you can, exchange, repeat.

Flat module function. No Solution class, which diverges from LeetCode's typical class-based template. The function is importable directly.

Dependencies

Imports: None — zero external dependencies, pure standard Python.

Imported by: water-bottles/test_solution.py directly. The "Imported By" list in the prompt is misleading — those hundreds of test files don't actually import *this* solution. That list appears to be an artifact of the repo's test infrastructure (likely a shared test runner or conftest), not direct imports of numWaterBottles.

Flow


total = numBottles        # drink all initial bottles
empties = numBottles      # all become empty

loop while empties >= numExchange:
    new_full  = empties // numExchange    # exchange empties for full
    empties   = empties % numExchange     # leftover empties
              + new_full                  # newly emptied after drinking
    total    += new_full                  # count the drinks

Example trace: numBottles=9, numExchange=3

Invariants

Error Handling

None. The function trusts its caller to provide valid inputs per the LeetCode constraints (1 <= numBottles <= 100, 2 <= numExchange <= 100). Passing numExchange=0 or numExchange=1 would cause a division-by-zero or infinite loop respectively — but those are outside the problem's contract.

Topics to Explore

Beliefs