There are two vessels of capacities ‘a’ and ‘b’ respectively. We have infinite water supply. Give an efficient algorithm to make exactly 1 litre of water in one of the vessels. You can throw all the water from any vessel any point of time. Assume that ‘a’ and ‘b’ are Coprimes.
Following are the steps:
Let V1 be the vessel of capacity ‘a’ and V2 be the vessel of capacity ‘b’ and ‘a’ is smaller than ‘b’.
1) Do following while the amount of water in V1 is not 1.
….a) If V1 is empty, then completely fill V1
….b) Transfer water from V1 to V2. If V2 becomes full, then keep the remaining water in V1 and empty V2
2) V1 will have 1 litre after termination of loop in step 1. Return.
Following is C++ implementation of the above algorithm.
C++
#include <iostream>
using namespace std;
int gcd( int a, int b) { return b? gcd(b, a % b) : a; }
class Vessel
{
int capacity, current;
public :
Vessel( int capacity) { this ->capacity = capacity; current = 0; }
void makeOneLitre(Vessel &V2);
int transfer( int amount);
};
void Vessel:: makeOneLitre(Vessel &V2)
{
if (gcd(capacity, V2.capacity) != 1)
return ;
while (current != 1)
{
if (current == 0)
current = capacity;
cout << "Vessel 1: " << current << " Vessel 2: "
<< V2.current << endl;
current = current - V2.transfer(current);
}
cout << "Vessel 1: " << current << " Vessel 2: "
<< V2.current << endl;
}
int Vessel::transfer( int amount)
{
if (current + amount < capacity)
{
current += amount;
return amount;
}
int transferred = capacity - current;
current = 0;
return transferred;
}
int main()
{
int a = 3, b = 7;
Vessel V1(a), V2(b);
V1.makeOneLitre(V2);
return 0;
}
|
C#
using System;
class GFG
{
static int gcd( int a, int b)
{
return b > 0 ? gcd(b, a % b) : a;
}
class Vessel
{
int capacity, current;
public Vessel( int capacity)
{
this .capacity = capacity;
current = 0;
}
public void makeOneLitre(Vessel V2)
{
if (gcd(capacity, V2.capacity) != 1)
return ;
while (current != 1)
{
if (current == 0)
current = capacity;
Console.Write( "Vessel 1: " + current +
" Vessel 2: " + V2.current + "\n" );
current = current - V2.transfer(current);
}
Console.Write( "Vessel 1: " + current +
" Vessel 2: " + V2.current + "\n" );
}
int transfer( int amount)
{
if (current + amount < capacity)
{
current += amount;
return amount;
}
int transferred = capacity - current;
current = 0;
return transferred;
}
}
public static void Main(String[] args)
{
int a = 3, b = 7;
Vessel V1 = new Vessel(a);
Vessel V2 = new Vessel(b);
V1.makeOneLitre(V2);
}
}
|
Java
class GFG
{
static int gcd( int a, int b)
{
return b > 0 ? gcd(b, a % b) : a;
}
static class Vessel
{
int capacity, current;
public Vessel( int capacity)
{
this .capacity = capacity;
current = 0 ;
}
void makeOneLitre(Vessel V2)
{
if (gcd(capacity, V2.capacity) != 1 )
return ;
while (current != 1 )
{
if (current == 0 )
current = capacity;
System.out.print( "Vessel 1: " + current +
" Vessel 2: " + V2.current + "\n" );
current = current - V2.transfer(current);
}
System.out.print( "Vessel 1: " + current +
" Vessel 2: " + V2.current + "\n" );
}
int transfer( int amount)
{
if (current + amount < capacity)
{
current += amount;
return amount;
}
int transferred = capacity - current;
current = 0 ;
return transferred;
}
}
public static void main(String[] args)
{
int a = 3 , b = 7 ;
Vessel V1 = new Vessel(a);
Vessel V2 = new Vessel(b);
V1.makeOneLitre(V2);
}
}
|
Python3
def gcd(a,b):
return gcd(b, a % b) if (b > 0 ) else a
class Vessel:
def __init__( self ,capacity):
self .capacity = capacity
self .current = 0
def makeOneLitre( self ,V2):
if (gcd( self .capacity, V2.capacity) ! = 1 ):
return
while ( self .current ! = 1 ):
if ( self .current = = 0 ):
self .current = self .capacity
print (f "Vessel 1: {self.current} Vessel 2: {V2.current}" )
self .current = self .current - V2.transfer( self .current)
print (f "Vessel 1: {self.current} Vessel 2: {V2.current}" )
def transfer( self ,amount):
if ( self .current + amount < self .capacity):
self .current + = amount
return amount
transferred = self .capacity - self .current
self .current = 0
return transferred
a,b = 3 , 7
V1 = Vessel(a)
V2 = Vessel(b)
V1.makeOneLitre(V2)
|
Javascript
<script>
function gcd(a,b)
{
return b > 0 ? gcd(b, a % b) : a;
}
class Vessel
{
constructor(capacity)
{
this .capacity = capacity;
this .current = 0;
}
makeOneLitre(V2)
{
if (gcd( this .capacity, V2.capacity) != 1)
return ;
while ( this .current != 1)
{
if ( this .current == 0)
this .current = this .capacity;
document.write( "Vessel 1: " + this .current +
" Vessel 2: " + V2.current + "<br>" );
this .current = this .current - V2.transfer( this .current);
}
document.write( "Vessel 1: " + this .current +
" Vessel 2: " + V2.current + "<br>" );
}
transfer(amount)
{
if ( this .current + amount < this .capacity)
{
this .current += amount;
return amount;
}
let transferred = this .capacity - this .current;
this .current = 0;
return transferred;
}
}
let a = 3, b = 7;
let V1 = new Vessel(a);
let V2 = new Vessel(b);
V1.makeOneLitre(V2);
</script>
|
Output:
Vessel 1: 3 Vessel 2: 0
Vessel 1: 3 Vessel 2: 3
Vessel 1: 3 Vessel 2: 6
Vessel 1: 2 Vessel 2: 0
Vessel 1: 3 Vessel 2: 2
Vessel 1: 3 Vessel 2: 5
Vessel 1: 1 Vessel 2: 0
How does this work?
To prove that the algorithm works, we need to proof that after certain number of iterations in the while loop, we will get 1 litre in V1.
Let ‘a’ be the capacity of vessel V1 and ‘b’ be the capacity of V2. Since we repeatedly transfer water from V1 to V2 until V2 becomes full, we will have ‘a – b (mod a)’ water in V1 when V2 becomes full first time . Once V2 becomes full, it is emptied. We will have ‘a – 2b (mod a)’ water in V1 when V2 is full second time. We repeat the above steps, and get ‘a – nb (mod a)’ water in V1 after the vessel V2 is filled and emptied ‘n’ times. We need to prove that the value of ‘a – nb (mod a)’ will be 1 for a finite integer ‘n’. To prove this, let us consider the following property of coprime numbers.
For any two coprime integers ‘a’ and ‘b’, the integer ‘b’ has a multiplicative inverse modulo ‘a’. In other words, there exists an integer ‘y’ such that ‘b*y ≡ 1(mod)a’ (See 3rd point here). After ‘(a – 1)*y’ iterations, we will have ‘a – [(a-1)*y*b (mod a)]’ water in V1, the value of this expression is ‘a – [(a – 1) * 1] mod a’ which is 1. So the algorithm converges and we get 1 litre in V1.
This article is compiled by Aashish Barnwal. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.