#include <iostream>

using namespace std;

int pow(int base, int exp)
{
    int res=1;
    for(int i=0; i<exp; i++)
        res*=base;
    return res;
}

bool isPowerOfTwo(int nr)
{
    bool est=false;
    for(int i=0; i<=nr/2; i++)
    if(pow(2,i)==nr){
        est=true;
        break;
    }
    return est;
}

class Function
{
    private:
    int terms[1000], mask[1000], tickedOff[1000], res[1000], resMask[1000]; 
    int nVars, nTerms, pi, ps, nRes;
    public:
    Function(int nv);
    void addTerm(int decIndicator, int msk);
    void printPrimeImplicants();
    void computeMap();
    void makeResult();
    void tickOffIdenticalTerms(); 
    void printResult();
    void removeDep();
    bool canRemoved(int i);
};

Function::Function(int nv)
{
    nVars=nv;
    nTerms=0;
    nRes = 0;
}

void Function::addTerm(int decIndicator, int msk)
{
    terms[nTerms]=decIndicator;
    mask[nTerms]=msk;
    nTerms++;
}

void Function::makeResult()
{
    for(int i=0;i<nTerms;i++)
    {
     if (!tickedOff[i])
     {
      res[nRes] = terms[i];
      resMask[nRes] = mask[i];
      nRes++;
     }
    }
}

void Function::computeMap()
{
    pi=0;
    ps=nTerms;
    int diff, addedTerms, i, j;
    for(int k=0; k<nVars*15; k++){
        tickedOff[k]=0;
    }
    while(pi<ps){
        addedTerms=0;
        for(i=pi; i<ps-1; i++)
            for(j=i+1; j<ps; j++)
            if((mask[i] == mask[j]) && isPowerOfTwo(diff=(terms[j]^terms[i]))){
                tickedOff[i]=1;
                tickedOff[j]=1;
                addTerm(terms[i], mask[i]+diff);
                addedTerms++;
            }
        pi=ps;
        ps+=addedTerms;
    }
}

void Function::tickOffIdenticalTerms()
{
    for(int i=0; i<nTerms-1; i++)
        for(int j=i+1; j<nTerms; j++)
            if(mask[i]==mask[j] && terms[i]==terms[j])
                tickedOff[j]=1;
}



void Function::printResult()
{
    for(int i=0; i<nRes; i++){
        for(int j=nVars-1; j>=0; j--){
            if(resMask[i]&pow(2,j)) cout<<"-"; 
            else if(res[i]&pow(2,j)) cout<<"1";
            else cout<<"0";
        }
        cout<<endl;
    }
}

void Function::removeDep()
{
     for(int i=0;i<nRes;i++)
     {
      if (canRemoved(i))
      {
       if(i==nRes-1)
       {
        nRes--;
       }
       else
       {
           res[i] = res[nRes-1];
           resMask[i] = resMask[nRes-1];
           nRes--;
       }
      }
     }     
}

bool Function::canRemoved(int i)
{
     int j,k,l; 
    bool e[nVars];
    for (j=0;j<nVars;j++)
        e[j] = 0;
    for (j=0;j<nRes;j++)
    {
     if (i!=j)
     {
      for(k=0;k<nVars;k++)
      {
        if((resMask[j]|res[j])==(resMask[j]|terms[k]))
          e[k] = 1;
      }
     }    
    }
    
    for (j=0;j<nVars;j++)
    {
     if(!e[j])
       return false;
    }
    return true;
      
}
///////////////////////////////////////////////////////

int main(int argc, char *argz[])
{
    int nMinterms, i, decInd, nVars;
    cout<<"Enter number of variables in function: "; cin>>nVars;
    cout<<"Enter number of minterms: "; cin>>nMinterms;
    cout<<"Please Enter minterms : "<<endl;
    Function func(nVars);
    for(i=0; i<nMinterms; i++){
        cout<<"Please Enter in decimal minterm "<<i<<" :"; cin>>decInd;
        func.addTerm(decInd,0); 
    }
    cout<<"--------------------------------------"<<endl;
    func.computeMap();
    func.tickOffIdenticalTerms();
    func.makeResult();
    func.removeDep();
    cout<<"\n\n Result: \n\n";
    func.printResult();    
    cin.get();
    cin.get();
    return 0;
}
