Water Jug Problem

Moderate
0/80
Average time to solve is 15m
profile
Contributed by
5 upvotes
Asked in companies
AmazonOYOUber

Problem statement

You are given two water jugs with capacities X and Y litres respectively. Both the jugs are initially empty. There is an infinite amount of water supply available. The jugs do not have markings to measure smaller quantities.

The following operations are allowed:

• Fill any of the jugs entirely with water.
• Empty any of the jugs.
• Pour water from one jug into another till the other jug is full, or the first jug itself is empty.

You are required to tell whether it is possible to measure exactly ‘Z’ litres using both of the jugs.

If Z litres of water is measurable, you must have Z litres of water contained within one or both buckets by the end.

For example:

In order to measure 2 litres from jugs of 4 and 6 litres we can follow the following steps-

• Fill 6-litres jugs to its maximum capacity.
• Pour water from 6-litres jug to the jug with 4-litres capacity.
• Pour water from 6-litres jug to the jug with 4-litres capacity.
Detailed explanation ( Input/output format, Notes, Images )
Input Format :
The first line of input contains an integer ‘T’ denoting the number of test cases to run. Then the test cases follow.

The first line of each test case contains three space-separated integers ‘X’, ‘Y’ and ‘Z’ denoting the capacities of both the jugs and the target measure, respectively.
Output Format :
For each test case, print True if we can measure the required value else, print False.

Output for each test case will be printed in a new line. 
Note :
You do not need to print anything, it has already been taken care of. Just implement the given function.
Constraints :
 1 <= T <= 5 * 10^4
 0 <= X, Y, Z <= 5 * 10^4

Time Limit: 1 sec
Sample Input 1:
2
3 5 4
2 2 7
Sample Output 1:
True
False
Explanation of Input 1:
The following steps in test case 1 may be followed to measure 4 litres-
• Fill 5-litres jug to its maximum capacity.
• Transfer 3-litres from 5-litres jug to 3-litres jugs. 
• Empty the 3-litres jug.
• Transfer 2-litres from 5-litres jug to 3-litres jug.
• Fill 5-litres jug to its maximum capacity.
• Pour water to 3-litres jug from 5-litres jug until it’s full.

We will find that exactly 4 litres will be left in the jug with 5 litres capacity.

There is no way in test case 2 that we can measure 7 litres from two 2-litres jugs.
Sample Input 2:
1
8 6 14
Sample Output 2:
True
Hint

Can we use BFS to solve this problem?

Approaches (2)
Using BFS

We will run a breadth-first search(BFS), keeping states as water present in both the jugs. We will visit all the states, keeping a hashmap for visited states to not revisit the same state. If we reach a state such that the capacity of water in one of the jugs is equal to ‘Z’ liters or the sum of water in both the jugs is equal to ‘Z’ liters we return true else we return false

 

Below is the detailed algorithm:

 

  1. We will use a data structure like a queue for implementing the BFS based solution.
  2. We will insert the initial state, i.e. (0, 0) in the queue ‘STORE’.
  3. While (size of 'STORE' > 0):
    • We will pop out the front element ‘curr’ of the queue. Let the current water in the first jug be ‘CURR_A’ and in the second jug be ‘CURR_B’ respectively.
    • If one of the values in the ‘curr’ is ‘Z’ or the sum of both the values in ‘curr’ is equal to ‘Z’ we return true.
    • We now take the following cases:
      • Fill one of the buckets:
        • If 'CURR_A' < 'X' we can fill more water in the first jug. Hence, if ('X', 'CURR_B') is not there in the hashmap, we insert it in the queue and the hashmap.
        • If 'CURR_B' < Y we can fill more water in the second jug. Hence, if ('CURR_A', Y) is not there in the hashmap, we insert it in the queue and the hashmap.
      • Pour water into the other jug:
        • We will now try to pour water from one jug to another. We can pour min('X' - 'CURR_A', 'CURR_B') water from the second jug to the first jug. Hence, if ('CURR_A' + min('X' - 'CURR_A', 'CURR_B'), 'CURR_B' -  min('X' - 'CURR_A', 'CURR_B') ) is not there in the hashmap, we insert it in the queue and the hashmap.
        • Similarly, we can pour min('CURR_A', Y -  'CURR_B') water from the first jug to the second jug. Hence, if ('CURR_A' - min('CURR_A', Y - 'CURR_B'), 'CURR_B' + min('CURR_A', Y - 'CURR_B') ) is not there in the hashmap, we insert it in the queue and the hashmap.
      • Pour water to the ground:
        • We can also pour water from one of the jugs to the ground and empty it.  Hence, if (0, 'CURR_B') is not there in the hashmap, we insert it in the queue and the hashmap.
        • Similarly, if ('CURR_A', 0) is not there in the hashmap, we insert it in the queue and the hashmap.
  4. If we do not find any valid combination, we return false.
Time Complexity

O(X * Y), where X is the capacity of the first jug and Y is the capacity of the second jug.

 

The number of distinct states will be (X * Y). As in the worst case, we will be visiting all the states. Hence, time complexity will O(X * Y).

Space Complexity

O(X * Y), where X is the capacity of the first jug and Y is the capacity of the second jug.

 

The space complexity due to the hashmap and the queue will O(X * Y).

Code Solution
(100% EXP penalty)
Water Jug Problem
Full screen
Console