Thursday, 11 August 2016

Water Jug Problem (Oracle Interview)

This problem was asked to me during my Oracle interview. The interviewer asked me to write down the code for the same.
 
Problem :

You are given three water jugs.
Let the capacity of jugs be X, Y and Z. (X >= Y >= Z).
As described in all common water jug problems, neither of the jugs has any measuring markers on it.

Initially we have only the first jug (with capacity X) fully filled up to brim (the other two jugs are initially empty).
Now you need to tell whether it is possible or not to transfer the water, in such a way that you reach to a state in which any two jugs have equal amount of water in them, and the third jug is empty.
In short, you have to divide X litre of water into two equal halves. These two equal halves can be in any of the two jugs.

Example
Suppose, X=10, Y=7, Z=3
Solution steps:
10 0 0 -> Initial State
3 7 0
0 7 3
7 0 3
7 3 0
4 3 3
4 6 0
1 6 3
1 7 2
8 0 2
8 2 0
5 2 3
5 5 0 -> Final State


C++ Program to solve this problem :

#include<bits/stdc++.h>
using namespace std;
class triplet
{
    public:
    int x,y,z;
    triplet(int x,int y,int z)
    {
        this->x=x;
        this->y=y;
        this->z=z;
    }
    
};
bool findTriplet(vector<triplet>&v,int x,int y,int z)
{
    for(int i=0;i<v.size();i++)
        if(v[i].x==x && v[i].z==z && v[i].y==y)
            return true;
    return false;
}
bool getSteps(int x,int y,int z,int X,int Y,int Z) // x y and z denotes the current capacity.
{
    static vector<triplet>v;
    if(findTriplet(v,x,y,z))
        return false;
    else 
        v.push_back(triplet(x,y,z));
    cout<<x<<" "<<y<<" "<<z<<endl;
    if(x==y && z==0)
        return true;
    if(z==y && x==0)
        return true;
    if(x==z && y==0)
        return true;
    
    /*********************************--> transferring from X <--*****************************************************/        
    if(x>0)
    {
        // transferring from x to y
        {
        int emptyy=Y-y;
        int newx,newy;
        if(emptyy>=x)
        {
            newy=y+x;
            newx=0;
        }
        else
        {
            newy=Y;
            newx=x-emptyy;
        }
        if(emptyy>0 && getSteps(newx,newy,z,X,Y,Z))
            return true;
        }
    
        // transferring from x to z
        {
        int emptyz=Z-z;
        int newx,newz;
        if(emptyz>=x)
        {
            newz=z+x;
            newx=0;
        }
        else
        {
            newz=Z;
            newx=x-emptyz;
        }
        if(emptyz>0 && getSteps(newx,y,newz,X,Y,Z))
            return true;
        }
    }
            
    /*********************************--> transferring from Y <--*****************************************************/        
    if(y>0)
    {
        // transferring from y to x
        {
        int emptyx=X-x;
        int newx,newy;
        if(emptyx>=y)
        {
            newx=x+y;
            newy=0;
        }
        else
        {
            newx=X;
            newy=y-emptyx;
        }
        if(emptyx>0 && getSteps(newx,newy,z,X,Y,Z))
            return true;
        }
    
        // transferring from y to z
        {
        int emptyz=Z-z;
        int newy,newz;
        if(emptyz>=y)
        {
            newz=z+y;
            newy=0;
        }
        else
        {
            newz=Z;
            newy=y-emptyz;
        }
        if(emptyz>0 && getSteps(x,newy,newz,X,Y,Z))
            return true;
        }
    }
            
    /*********************************--> transferring from Z <--*****************************************************/        
    if(z>0)
    {
        // transferring from z to y
        {
        int emptyy=Y-y;
        int newz,newy;
        if(emptyy>=z)
        {
            newy=y+z;
            newz=0;
        }
        else
        {
            newy=Y;
            newz=z-emptyy;
        }
        if(emptyy>0 && getSteps(x,newy,newz,X,Y,Z))
            return true;
        }
    
        // transferring from z to x
        {
        int emptyx=X-x;
        int newz,newx;
        if(emptyx>=z)
        {
            newx=z+x;
            newz=0;
        }
        else
        {
            newx=X;
            newz=z-emptyx;
        }
        if(emptyx>0 && getSteps(newx,y,newz,X,Y,Z))
            return true;
        }
    }
    return false;
}
int main()
{
    int x,y,z;
    cin>>x>>y>>z;
    if(getSteps(x,0,0,x,y,z))
        cout<<"Yes!! you got a solution!!"<<endl;
    else cout<<"No solution found!!"<<endl;
    return 0;
}

Please write comments if you find anything incorrect, or you want to share more information about the problem discussed above.

No comments:

Post a Comment