Related Articles
Water Jug problem using BFS
• Difficulty Level : Hard
• Last Updated : 05 Feb, 2021

You are given a m liter jug and a n liter jug. Both the jugs are initially empty. The jugs don’t have markings to allow measuring smaller quantities. You have to use the jugs to measure d liters of water where d is less than n.

(X, Y) corresponds to a state where X refers to amount of water in Jug1 and Y refers to amount of water in Jug2
Determine the path from initial state (xi, yi) to final state (xf, yf), where (xi, yi) is (0, 0) which indicates both Jugs are initially empty and (xf, yf) indicates a state which could be (0, d) or (d, 0).

The operations you can perform are:

1. Empty a Jug, (X, Y)->(0, Y) Empty Jug 1
2. Fill a Jug, (0, 0)->(X, 0) Fill Jug 1
3. Pour water from one jug to the other until one of the jugs is either empty or full, (X, Y) -> (X-d, Y+d)

Examples:

```Input : 4 3 2
Output : {(0, 0), (0, 3), (4, 0), (4, 3),
(3, 0), (1, 3), (3, 3), (4, 2),
(0, 2)}```

We have discussed one solution in The Two Water Jug Puzzle
In this post a BFS based solution is discussed.

We run breadth first search on the states and these states will be created after applying allowed operations and we also use visited map of pair to keep track of states that should be visited only once in the search. This solution can also be achieved using depth first search.

## C++

 `#include ``#define pii pair``#define mp make_pair``using` `namespace` `std;` `void` `BFS(``int` `a, ``int` `b, ``int` `target)``{``    ``// Map is used to store the states, every``    ``// state is hashed to binary value to``    ``// indicate either that state is visited``    ``// before or not``    ``map m;``    ``bool` `isSolvable = ``false``;``    ``vector path;` `    ``queue q; ``// queue to maintain states``    ``q.push({ 0, 0 }); ``// Initialing with initial state` `    ``while` `(!q.empty()) {` `        ``pii u = q.front(); ``// current state` `        ``q.pop(); ``// pop off used state` `        ``// if this state is already visited``        ``if` `(m[{ u.first, u.second }] == 1)``            ``continue``;` `        ``// doesn't met jug constraints``        ``if` `((u.first > a || u.second > b ||``            ``u.first < 0 || u.second < 0))``            ``continue``;` `        ``// filling the vector for constructing``        ``// the solution path``        ``path.push_back({ u.first, u.second });` `        ``// marking current state as visited``        ``m[{ u.first, u.second }] = 1;` `        ``// if we reach solution state, put ans=1``        ``if` `(u.first == target || u.second == target) {``            ``isSolvable = ``true``;``            ``if` `(u.first == target) {``                ``if` `(u.second != 0)` `                    ``// fill final state``                    ``path.push_back({ u.first, 0 });``            ``}``            ``else` `{``                ``if` `(u.first != 0)` `                    ``// fill final state``                    ``path.push_back({ 0, u.second });``            ``}` `            ``// print the solution path``            ``int` `sz = path.size();``            ``for` `(``int` `i = 0; i < sz; i++)``                ``cout << ``"("` `<< path[i].first``                    ``<< ``", "` `<< path[i].second << ``")\n"``;``            ``break``;``        ``}` `        ``// if we have not reached final state``        ``// then, start developing intermediate``        ``// states to reach solution state``        ``q.push({ u.first, b }); ``// fill Jug2``        ``q.push({ a, u.second }); ``// fill Jug1` `        ``for` `(``int` `ap = 0; ap <= max(a, b); ap++) {` `            ``// pour amount ap from Jug2 to Jug1``            ``int` `c = u.first + ap;``            ``int` `d = u.second - ap;` `            ``// check if this state is possible or not``            ``if` `(c == a || (d == 0 && d >= 0))``                ``q.push({ c, d });` `            ``// Pour amount ap from Jug 1 to Jug2``            ``c = u.first - ap;``            ``d = u.second + ap;` `            ``// check if this state is possible or not``            ``if` `((c == 0 && c >= 0) || d == b)``                ``q.push({ c, d });``        ``}` `        ``q.push({ a, 0 }); ``// Empty Jug2``        ``q.push({ 0, b }); ``// Empty Jug1``    ``}` `    ``// No, solution exists if ans=0``    ``if` `(!isSolvable)``        ``cout << ``"No solution"``;``}` `// Driver code``int` `main()``{``    ``int` `Jug1 = 4, Jug2 = 3, target = 2;``    ``cout << ``"Path from initial state "``            ``"to solution state ::\n"``;``    ``BFS(Jug1, Jug2, target);``    ``return` `0;``}`

## Python3

 `from` `collections ``import` `deque` `def` `BFS(a, b, target):``    ` `    ``# Map is used to store the states, every``    ``# state is hashed to binary value to``    ``# indicate either that state is visited``    ``# before or not``    ``m ``=` `{}``    ``isSolvable ``=` `False``    ``path ``=` `[]``    ` `    ``# Queue to maintain states``    ``q ``=` `deque()``    ` `    ``# Initialing with initial state``    ``q.append((``0``, ``0``))` `    ``while` `(``len``(q) > ``0``):``        ` `        ``# Current state``        ``u ``=` `q.popleft()` `        ``#q.pop() #pop off used state` `        ``# If this state is already visited``        ``if` `((u[``0``], u[``1``]) ``in` `m):``            ``continue` `        ``# Doesn't met jug constraints``        ``if` `((u[``0``] > a ``or` `u[``1``] > b ``or``             ``u[``0``] < ``0` `or` `u[``1``] < ``0``)):``            ``continue` `        ``# Filling the vector for constructing``        ``# the solution path``        ``path.append([u[``0``], u[``1``]])` `        ``# Marking current state as visited``        ``m[(u[``0``], u[``1``])] ``=` `1` `        ``# If we reach solution state, put ans=1``        ``if` `(u[``0``] ``=``=` `target ``or` `u[``1``] ``=``=` `target):``            ``isSolvable ``=` `True``            ` `            ``if` `(u[``0``] ``=``=` `target):``                ``if` `(u[``1``] !``=` `0``):``                    ` `                    ``# Fill final state``                    ``path.append([u[``0``], ``0``])``            ``else``:``                ``if` `(u[``0``] !``=` `0``):` `                    ``# Fill final state``                    ``path.append([``0``, u[``1``]])` `            ``# Print the solution path``            ``sz ``=` `len``(path)``            ``for` `i ``in` `range``(sz):``                ``print``(``"("``, path[i][``0``], ``","``,``                           ``path[i][``1``], ``")"``)``            ``break` `        ``# If we have not reached final state``        ``# then, start developing intermediate``        ``# states to reach solution state``        ``q.append([u[``0``], b]) ``# Fill Jug2``        ``q.append([a, u[``1``]]) ``# Fill Jug1` `        ``for` `ap ``in` `range``(``max``(a, b) ``+` `1``):` `            ``# Pour amount ap from Jug2 to Jug1``            ``c ``=` `u[``0``] ``+` `ap``            ``d ``=` `u[``1``] ``-` `ap` `            ``# Check if this state is possible or not``            ``if` `(c ``=``=` `a ``or` `(d ``=``=` `0` `and` `d >``=` `0``)):``                ``q.append([c, d])` `            ``# Pour amount ap from Jug 1 to Jug2``            ``c ``=` `u[``0``] ``-` `ap``            ``d ``=` `u[``1``] ``+` `ap` `            ``# Check if this state is possible or not``            ``if` `((c ``=``=` `0` `and` `c >``=` `0``) ``or` `d ``=``=` `b):``                ``q.append([c, d])``        ` `        ``# Empty Jug2``        ``q.append([a, ``0``])``        ` `        ``# Empty Jug1``        ``q.append([``0``, b])` `    ``# No, solution exists if ans=0``    ``if` `(``not` `isSolvable):``        ``print` `(``"No solution"``)` `# Driver code``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``Jug1, Jug2, target ``=` `4``, ``3``, ``2``    ``print``(``"Path from initial state "``          ``"to solution state ::"``)``    ` `    ``BFS(Jug1, Jug2, target)` `# This code is contributed by mohit kumar 29`

## C#

 `using` `System;``using` `System.Collections.Generic;` `class` `GFG{``    ` `static` `void` `BFS(``int` `a, ``int` `b, ``int` `target)``{``    ` `    ``// Map is used to store the states, every``    ``// state is hashed to binary value to``    ``// indicate either that state is visited``    ``// before or not``    ``Dictionary, ``int``> m = ``new` `Dictionary ,``int``>(); ``    ``bool` `isSolvable = ``false``;``    ``List> path = ``new` `List>();``    ``// Queue to maintain states``    ``List> q = ``new` `List>();``    ` `    ``// Initializing with initial state``    ``q.Add(``new` `Tuple<``int``,``int``>(0, 0));`` ` `    ``while` `(q.Count > 0)``    ``{``        ` `        ``// Current state``        ``Tuple<``int``, ``int``> u = q;``        ` `        ``// Pop off used state``        ``q.RemoveAt(0);`` ` `        ``// If this state is already visited``        ``if` `(m.ContainsKey(u) && m[u] == 1)``            ``continue``;`` ` `        ``// Doesn't met jug constraints``        ``if` `((u.Item1 > a || u.Item2 > b ||``            ``u.Item1 < 0 || u.Item2 < 0))``            ``continue``;`` ` `        ``// Filling the vector for constructing``        ``// the solution path``        ``path.Add(u);`` ` `        ``// Marking current state as visited``        ``m[u] = 1;`` ` `        ``// If we reach solution state, put ans=1``        ``if` `(u.Item1 == target || u.Item2 == target)``        ``{``            ``isSolvable = ``true``;``            ` `            ``if` `(u.Item1 == target)``            ``{``                ``if` `(u.Item2 != 0)`` ` `                    ``// Fill final state``                    ``path.Add(``new` `Tuple<``int``, ``int``>(u.Item1, 0));``            ``}``            ``else``            ``{``                ``if` `(u.Item1 != 0)`` ` `                    ``// Fill final state``                    ``path.Add(``new` `Tuple<``int``, ``int``>(0, u.Item2));``            ``}`` ` `            ``// Print the solution path``            ``int` `sz = path.Count;``            ``for``(``int` `i = 0; i < sz; i++)``                ``Console.WriteLine(``"("` `+ path[i].Item1 +``                                 ``", "` `+ path[i].Item2 + ``")"``);``            ``break``;``        ``}`` ` `        ``// If we have not reached final state``        ``// then, start developing intermediate``        ``// states to reach solution state``        ``// Fill Jug2``        ``q.Add(``new` `Tuple<``int``, ``int``>(u.Item1, b));``        ` `        ``// Fill Jug1``        ``q.Add(``new` `Tuple<``int``, ``int``>(a, u.Item2));`` ` `        ``for``(``int` `ap = 0; ap <= Math.Max(a, b); ap++)``        ``{``            ` `            ``// Pour amount ap from Jug2 to Jug1``            ``int` `c = u.Item1 + ap;``            ``int` `d = u.Item2 - ap;`` ` `            ``// Check if this state is possible or not``            ``if` `(c == a || (d == 0 && d >= 0))``                ``q.Add(``new` `Tuple<``int``, ``int``>(c, d));`` ` `            ``// Pour amount ap from Jug 1 to Jug2``            ``c = u.Item1 - ap;``            ``d = u.Item2 + ap;`` ` `            ``// Check if this state is possible or not``            ``if` `((c == 0 && c >= 0) || d == b)``                ``q.Add(``new` `Tuple<``int``, ``int``>(c, d));``        ``}``        ` `        ``// Empty Jug2``        ``q.Add(``new` `Tuple<``int``, ``int``>(a, 0));``        ` `        ``// Empty Jug1``        ``q.Add(``new` `Tuple<``int``, ``int``>(0, b));``    ``}`` ` `    ``// No, solution exists if ans=0``    ``if` `(!isSolvable)``        ``Console.WriteLine(``"No solution"``);``}` `// Driver code``static` `void` `Main()``{``    ``int` `Jug1 = 4, Jug2 = 3, target = 2;``    ``Console.WriteLine(``"Path from initial state "` `+``                      ``"to solution state ::"``);``                      ` `    ``BFS(Jug1, Jug2, target);``}``}` `// This code is contributed by divyeshrabadiya07`

Output:

```Path from initial state to solution state ::
(0, 0)
(0, 3)
(4, 0)
(4, 3)
(3, 0)
(1, 3)
(3, 3)
(4, 2)
(0, 2) ```

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up