A clear explanation of solving the Water and Jug Problem using Bézout's identity and greatest common divisor.
Problem Restatement
We are given two jugs with capacities x liters and y liters.
There is an infinite water supply.
We need to decide whether it is possible to measure exactly target liters using the two jugs.
At the end, the total amount of water in both jugs must be exactly target.
Allowed operations:
| Operation | Meaning |
|---|---|
| Fill | Fill either jug completely |
| Empty | Empty either jug completely |
| Pour | Pour from one jug into the other until the source is empty or the destination is full |
The problem asks whether the total amount of water in both jugs can reach target using these operations. Example: x = 3, y = 5, target = 4 returns true.
Input and Output
| Item | Meaning |
|---|---|
| Input | x, y, and target |
| Output | True if exactly target liters can be measured |
| Jug capacities | x and y liters |
| Final condition | Water in both jugs together equals target |
| Operations | Fill, empty, and pour |
Example function shape:
def canMeasureWater(x: int, y: int, target: int) -> bool:
...Examples
Example 1:
x = 3
y = 5
target = 4This is possible.
One sequence is:
| Step | State |
|---|---|
| Start | (0, 0) |
| Fill 5-liter jug | (0, 5) |
| Pour 5 into 3 | (3, 2) |
| Empty 3-liter jug | (0, 2) |
| Pour 2 into 3 | (2, 0) |
| Fill 5-liter jug | (2, 5) |
| Pour 5 into 3 until 3 is full | (3, 4) |
| Empty 3-liter jug | (0, 4) |
Now the total water is 4.
So the answer is:
TrueExample 2:
x = 2
y = 6
target = 5This is impossible.
Both jug sizes are even, so every measurable amount is even.
The target 5 is odd.
So the answer is:
FalseExample 3:
x = 1
y = 2
target = 3Fill both jugs.
The total is:
1 + 2 = 3So the answer is:
TrueFirst Thought: Search All States
A direct solution is to model each state as:
(a, b)where:
| Variable | Meaning |
|---|---|
a | Current water in jug x |
b | Current water in jug y |
From each state, we can try all operations:
- Fill jug
x. - Fill jug
y. - Empty jug
x. - Empty jug
y. - Pour
xintoy. - Pour
yintox.
Then use BFS or DFS.
This works because capacities are bounded.
But the problem has a simpler mathematical solution.
Key Insight
The measurable amounts are exactly the multiples of:
gcd(x, y)within the total capacity limit.
This comes from Bézout’s identity.
For two integers x and y, all integer combinations:
a * x + b * yare multiples of gcd(x, y).
The fill and empty operations effectively add or remove whole jug capacities. Pouring transfers water between jugs without changing the total amount. Together, these operations can measure exactly the amounts that are multiples of the greatest common divisor.
So target is measurable if and only if:
target <= x + yand:
target % gcd(x, y) == 0The first condition matters because the two jugs together cannot hold more than x + y liters at one time.
Algorithm
- If
target > x + y, returnFalse. - Compute:
g = gcd(x, y)- Return whether:
target % g == 0For the official constraints, x, y, and target are positive, so no special zero-capacity handling is needed in the standard version. The statement uses capacities and target at least 1.
Correctness
The total water held by both jugs can never exceed x + y, because those are the two jug capacities. Therefore, if target > x + y, the answer must be False.
Every amount produced by fill and empty operations changes the total water by whole multiples of x or y. Pouring only moves water between jugs and does not change the total. Therefore, every reachable target amount must be an integer combination of x and y.
By Bézout’s identity, an integer combination of x and y can equal target exactly when target is divisible by gcd(x, y).
If target is divisible by gcd(x, y) and target <= x + y, the classical water jug construction can measure that amount using fill, empty, and pour operations.
Therefore, the algorithm returns True exactly for measurable targets.
Complexity
| Metric | Value | Why |
|---|---|---|
| Time | O(log min(x, y)) | Euclidean algorithm for GCD |
| Space | O(1) | Only a few integer variables |
Implementation
from math import gcd
class Solution:
def canMeasureWater(self, x: int, y: int, target: int) -> bool:
if target > x + y:
return False
return target % gcd(x, y) == 0Code Explanation
First check capacity:
if target > x + y:
return FalseEven if the target is mathematically reachable as a linear combination, the two jugs cannot hold more than x + y liters at the same time.
Then compute the GCD:
gcd(x, y)The target is measurable only when it is divisible by that GCD:
target % gcd(x, y) == 0For example:
x = 2
y = 6
target = 5The GCD is:
2Since:
5 % 2 != 0the answer is False.
Alternative Implementation: BFS
The BFS version is useful for understanding the operations directly.
from collections import deque
class Solution:
def canMeasureWater(self, x: int, y: int, target: int) -> bool:
if target > x + y:
return False
queue = deque([(0, 0)])
seen = {(0, 0)}
while queue:
a, b = queue.popleft()
if a + b == target:
return True
states = []
states.append((x, b))
states.append((a, y))
states.append((0, b))
states.append((a, 0))
pour = min(a, y - b)
states.append((a - pour, b + pour))
pour = min(b, x - a)
states.append((a + pour, b - pour))
for state in states:
if state not in seen:
seen.add(state)
queue.append(state)
return FalseThis version explores reachable jug states.
Its time and space are:
O(x * y)because there are at most (x + 1) * (y + 1) states.
The GCD solution is preferred.
Testing
def run_tests():
s = Solution()
assert s.canMeasureWater(3, 5, 4) is True
assert s.canMeasureWater(2, 6, 5) is False
assert s.canMeasureWater(1, 2, 3) is True
assert s.canMeasureWater(6, 10, 8) is True
assert s.canMeasureWater(6, 10, 7) is False
assert s.canMeasureWater(4, 9, 13) is True
assert s.canMeasureWater(4, 9, 14) is False
print("all tests passed")
run_tests()Test meaning:
| Test | Why |
|---|---|
(3, 5, 4) | Classic reachable case |
(2, 6, 5) | Target not divisible by GCD |
(1, 2, 3) | Target equals total capacity |
(6, 10, 8) | Reachable multiple of GCD |
(6, 10, 7) | Not divisible by GCD |
(4, 9, 13) | Fill both jugs |
(4, 9, 14) | Larger than total capacity |