#include<iostream>
#include<vector>
#include<array>
#include <list>
#include<algorithm>


using namespace std;


class HashedObj{ 
    public: 
    int rep;
    HashedObj(int x){
        rep = x;
    }
};


template <typename HashedObj>
class HashTable{
    public: vector<vector<HashedObj>> theList;
    HashTable(int x){
            for(int i = 0; i < x; i++){
            vector<HashedObj> newlist; 
            theList.push_back(newlist);
        }
    }
    
    void makeEmpty(){
        for( auto & tList : theList )
        tList.clear();
    }
    
    bool contains (HashedObj & x){ 
        auto & whichList = theList[x.rep % 10];
        for(int i = 0; i < whichList.size(); i++){
            if(whichList[i].rep == x.rep)
                return true;
        }
        return false;
        //return find_list(begin(whichList), end(whichList), x) != end( whichList ); 
    }
    
    bool rem (HashedObj & x){
        auto & whichList = theList[x.rep % 10];
        int itr = -1;
        for(int i = 0; i < whichList.size(); i++){
            if(whichList[i].rep == x.rep){
                itr = i;
                break;
            }
        }
        if (itr == -1)
            return false;
        whichList.erase(begin(whichList) + itr);
        /*auto itr = find_list(begin( whichList ), end( whichList ), x );
        
        if( itr == end( whichList ) )
            return false;
        whichList.erase( itr );*/
        return true;
    }
    
    void display(){
        for(int i = 0; i < theList.size(); i++){
            if (theList[i].size() == 0){
                continue;
            }
            cout<<i<<" -> ";
            for(int j = 0; j < theList[i].size(); j++){
                cout<<theList[i][j].rep<<" ";
            }
            cout<<"\n";
        }
    }
    
    bool insertion( HashedObj & x ){
        int i = x.rep % 10;
        auto & whichList = theList[i];
        whichList.push_back(x);
        return true;
    }


};




int main(){
   
    HashedObj h3(30);
    HashedObj h4(40);
    HashTable <HashedObj> hlist(101);


    cout<<"Initial contents:\n";
    hlist.display();
    int choice,element;
do{
    cout<<"1.insertion"<<endl;
    cout<<"2.deletion"<<endl;
    cout<<"3.display"<<endl;
    cout<<"4.Exit"<<endl;
    cin>>choice;
    switch(choice)
{
    case 1:
    {
    cout<<"enter element";
    cin>>element;
    HashedObj h1(element);
    if(!hlist.contains(h1))
        hlist.insertion(h1);
    }
    break;
    
    case 2:
    {
    cout<<"enter element for deletion"<<endl;
    cin>>element;
    HashedObj h2(element);
    if(hlist.rem(h2))
    cout<<"deleted\n";
    }
    break;
    case 3:
    
    cout<<"After inserting h1-4:\n";
    hlist.display();
    break;
}
}while(choice<=3);
    return 0;
}