COOL020
Home ] Up ]

 

// Date:   2005/11/02
// Author: AOU6
// File:   COOL020.cpp

#include<iostream>
#include <fstream>
#include <ctime>
using namespace std;

/*
Description:
Examples:
Algorithms:
Code:
Output:
*/
/*
maintain Ordered Dense List, allow duplicate values
Operations:
  create (COOL myList; )
  populate (myList.populate(1,10);)
  populate (myList.populate(20);)
  populate (myList.populate("myList.dat");)
  shuffle (myList.shuffle();)
  insert  (myList.insert(45);)
  deleteByValue  (myList.delete(45);)
  display  (a.display();)
  deleteAll
  sort
  sum (a = myList.sum();)
  
*/
int const MAX_SIZE  =  10;
int const UNDEFINED = -6;
int const MIN_VALUE =  1;
int const MAX_VALUE =  9;
int const INFINITY  =  9999;
int const TEST_COUNT=  MAX_SIZE+10;


class COOL
  {
  private:
    int n;
    int a[MAX_SIZE+2];
    void swap(int &x, int &y);
  public:
    COOL(void);
    COOL(int n);

    void display(void) const;
    int insert(int x);
    int populate(int m);

    int populate(int n1, int n2); 
    //Project#2 with a test function
    //random values between n1 and n2
    //returns number of values added

    void shuffle(void);
    void sortBubble1(void);
    void sortBubble2(void); //p03
	  void displayDistinct(void) const; //p04
    void displayDistinctWithCounts(void) const; //p05

    friend bool isEqual(const COOL &list1, const COOL &list2);
    bool isEqual(const COOL &list2) const;
    bool operator ==(const COOL &list2) const;

    bool operator !=(const COOL &list2) const;


    int sum(void) const;
  private:
    void init(void);
  public:
    COOL(char ch); //r=>random, d=>distinct
    bool has(int x) const;
    int operator +(void) const;

    COOL(const COOL &aList);
    COOL & operator = (const COOL &aList);
    friend void merge(const COOL &aList, const COOL &bList, COOL &cList);//p06
    //cList should not have duplicate values due 10/21/2005



    bool deleteByPos(int p);

    friend ostream & operator << (ostream & bob, const COOL & aList);
    //project #7 assigned today, due 10/31/2005
    //overload >> operator for input with a test function

    // http://smccd.net/accounts/hasson/C++2Notes/OpOverLoading.html
    /*
    Overloading << and >> for input and output
    cout << x; works just find if x is an int, but the computer doesn't know what to do if x is an intList. 
    To make << and >> work for objects, these symbols must be overloaded with operator functions. 

    Again this must be done using friend functions. Here I overload << and >> for the intList class. 


    Add friend prototypes to the intList class definition: 

    ostream& operator<< (ostream&, intList&);
    istream& operator>> (istream&, intList&);

    cout is an example of an ostream object. cin is an example of an istream object. 

    So the way ostream& operator<< (ostream&, intList&); will work is the following: 


    We give the operator << function an ostream object (like cout) and an intList object as arguments. 
    We accumulate the printing in the ostream object in the body of the function. 
    Then we return the ostream object again so that ``chaining'' will work. cout << x << "George" << endl; is chaining. 
    For the computer to know what ostream and istream mean, #include <iostream> must be included in the intList.h file. 


    Add these functions to the intList.cpp file: 

    ostream& operator<< (ostream& out, intList& aList)
      {
      for (int n = 0; n < aList.size; n++)
	      out << aList.theList [n] << endl;

      return out;
      }

    istream& operator>> (istream& in, intList& aList)
      {
      in >> aList.size;

      delete []aList.theList;

      aList.theList = new int [aList.size];

      for (int n = 0; n < aList.size; n++)
	      in >> aList.theList [n];

      return in;
      }

    */
    int populate(char *fileName);


    int deleteByValue(int x);

    int deleteByValueAll(int x);
    int deleteByValueN(int x, int n);
    int deleteByValueLast(int x);
    void search(int x, int &p, int &n);
  };

//bool isEqual(const COOL &list1, const COOL &list2);

void test_insert(void);
void test_populate(void);
void test_shuffle(void);
void test_sortBubble1(void);
void test_sortBubble2(void);
void test_constructorN(void);
void test_isEqualFriend(void);
void test_isEqual(void);
void test_operator_isEqual(void);
void test_operator_isNotEqual(void);
void test_sum(void);
void test_constructorChar(void);
void test_has(void);
void test_operatorUniPlus(void);
void test_constructorCopy(void);
void test_operator_assign(void);
void test_mergeFriend(void);
void test_deleteByPos(void);
void test_operator_insertion(void);
void test_populate_file(void);
void test_deleteByVal(void);
void test_pointerGame1(void);
void test_pointerGame2(void);


void main ()
  {
  srand((unsigned int) time(NULL));
  //test_insert();
  //test_populate();
  //test_shuffle();
  //test_sortBubble1();
  //test_sortBubble2();
  //test_constructorN();
  //test_isEqualFriend();
  //test_isEqual();
  //test_operator_isEqual();
  //test_operator_isNotEqual();
  //test_sum();
  //test_constructorChar();
  //test_has();
  //test_operatorUniPlus();
  //test_constructorCopy();
  //test_operator_assign();
  //test_mergeFriend();
  //test_deleteByPos();
  //test_operator_insertion();
  //test_populate_file();
  //test_deleteByVal();
  test_pointerGame1();
  test_pointerGame2();
 }


void test_pointerGame2(void)
  {
  COOL myList('r');
  cout << "myList = " << myList << endl;
  cout << "&myList= " << &myList << endl;

  cout << "-------------------\n";
  COOL *p;
  p = NULL;
  cout << "p = " << p << endl;

  cout << "-------------------\n";
  p = &myList;
  cout << "p = " << p << endl;
  cout << "*p = " << *p << endl;

  }


void test_pointerGame1(void)
  {
  int x=13;
  cout << "x = " << x << endl;
  cout << "&x= " << &x << endl;

  int *p;
  p = NULL;
  cout << "p = " << p << endl;

  p = &x;
  cout << "p = " << p << endl;
  cout << "*p= " << *p << endl;

  int y[4] ={1,2,3,4};
  for (int i=0; i<4; i++)
    cout << "y[" << i << "]= " << y[i] << endl;

  cout << "-------------------\n";
  p = &y[0];
  for (int i=0; i<4; i++)
    {
    cout << "y[" << i << "]= " << *p << " @ " << p << endl;
    p++;
    }

  cout << "-------------------\n";
  p = &y[0];
  for (int i=0; i<4; i++)
    {
    cout << "y[" << i << "]= " << *(p+i) << " @ " << (p+i) << endl;
    }

  cout << "-------------------\n";
  p = y;
  for (int i=0; i<4; i++)
    {
    cout << "y[" << i << "]= " << *(p+i) << " @ " << (p+i) << endl;
    }

  cout << "-------------------\n";
  p = y;
  for (int i=0; i<4; i++)
    {
    *(p+i) = 2*(i+1);
    }

  for (int i=0; i<4; i++)
    {
    cout << "y[" << i << "]= " << *(p+i) << " @ " << (p+i) << endl;
    }
  
  cout << "-------------------\n";
  p = new int(14);
  cout << "p = " << p << endl;
  cout << "*p= " << *p << endl;
  *p = 13;
  cout << "p = " << p << endl;
  cout << "*p= " << *p << endl;
  delete p;

  cout << "===================\n";
  }


void test_deleteByVal(void)
  {
  cout << "--------------------\n";
  cout << "test_deleteByVal\n";
  cout << "--------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList('r');

    myList.display();

    int x = MIN_VALUE + rand()%(MAX_VALUE - MIN_VALUE + 1);

    cout << x << endl;

    myList.deleteByValue(x);

    cout << "After myList.deleteByValue(" << x << ");\n";
    myList.display();


    cout << "........................\n";
    }

  }


/*
int cool::deleteByValue(int x)
Description:
  deletes the first value 9left-most) matching x
Examples:
  {-inf, 12, 14, 14, +inf}, 14
    =>   {-inf, 12, 14, +inf}, 

Algorithms:
  search from left to right
  if found then delete, return 1
           else return 0

  p=-1
  for i=1 to n-2
    if x == a[i] then p=i, exit loop
    next i

  if p===-1 then return 0

  call deleteByPos(p)
  return 1

Code:
Output:
*/
int COOL::deleteByValue(int x)
  {
  int p=-1;

  for (int i=1; i<=this->n-2; i++)
    if (x == a[i]) 
      {
      p=i;
      break;
      }

  if (-1 == p) 
    return 0;

  this->deleteByPos(p);
  return 1;
  }


void test_populate_file(void)
  {
  cout << "--------------------\n";
  cout << "test_populate_file\n";
  cout << "--------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList;

    myList.display();

    myList.populate("sample.in");
    cout << myList << endl ;

    cout << "........................\n";
    }

  }


int COOL::populate(char *fileName)
  {
  ifstream iFile(fileName, ios::in);
  char input[10];

  if (!iFile)
    {
    cout << "File " << fileName << " does NOT exist\n";
    return 0;
    }
  
  cout << "File " << fileName << " does exist\n";

  int count =0;

  while (!iFile.eof())
    {
    iFile >> input;
    this->insert(atoi(input));
    count++;
    }

  iFile.close();

  return count;
  }


void test_operator_insertion(void)
  {
  cout << "--------------------\n";
  cout << "test_operator_insertion\n";
  cout << "--------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList('r');

    myList.display();
    cout << myList << endl ;


    cout << "........................\n";
    }

  }


ostream & operator << (ostream & bob, const COOL & aList)
  {
  bob << "COOL[" << aList.n-2 << "]: ";

  for (int i=1; i<=aList.n-2; i++)
    bob << aList.a[i] << ' ';
  
  return bob;
  }


void test_deleteByPos(void)
  {
  cout << "--------------------\n";
  cout << "test_deleteByPos\n";
  cout << "--------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList('r');

    myList.display();

    int p = -1 + rand()%(MAX_SIZE+1 - -1 + 1);

    cout << p << endl;

    bool result = myList.deleteByPos(p);

    myList.display();

    if (result)
      cout << "delete by position was a success\n";
    else
      cout << "delete by position was NOT a succes\n";

    cout << "........................\n";
    }

  }


/*
bool COOL::deleteByPos(int p)
Description:
  delete a value from a given valid position 
Example:
  {-inf, 5, 6, 9, +inf}, 2 => {-inf, 5, 9, +inf}, true
  {-inf, 5, 6, 9, +inf}, 0 => {-inf, 5, 6, 9, +inf}, false
  {-inf, 5, 6, 9, +inf}, 4 => {-inf, 5, 6, 9, +inf}, false
  {-inf, 5, 6, 9, +inf}, 9 => {-inf, 5, 6, 9, +inf}, false
  {-inf, 5, 6, 9, +inf},-9 => {-inf, 5, 6, 9, +inf}, false
Algorithm0:
  if p <= 0 or >= n-1 then 
    return false
  else
    delete the value at position p by shifting values to the left
    decrease n by 1
    return true
  end if

Algorithm1:
  if p <= 0 or >= n-1 then 
    return false
  else
    //delete the value at position p by shifting values to the left
    for i=p to n-2 step 1
      a[i] = a[i+1]
      end for
    a[n-1] = UNDEFINED
    decrease n by 1
    return true
  end if
*/
bool COOL::deleteByPos(int p)
  {
  if ((p <= 0) || (p >= n-1)) 
    return false;
  else
    //delete the value at position p by shifting values to the left
    {
    for (int i=p; i<=n-2; i++)
      a[i] = a[i+1];

    a[n-1] = UNDEFINED;
    n--;
    return true;
    }
  }


void test_mergeFriend(void)
  {
  cout << "----------------\n";
  cout << "test_mergeFriend\n";
  cout << "----------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL aList('r'), bList('r'), cList('r');
    aList.display();
    bList.display();
    cList.display();

    merge(aList, bList, cList);

    cout << "After merge(aList, bList, cList);\n";

    aList.display();
    bList.display();
    cList.display();

    cout << "........................\n";
    }

  }

/*
  merge(const COOL &aList, const COOL &bList, COOL &cList)
  Algorithm
  clear cList
  for each value x in aList do the following
    if x is not in cList then 
      insert x into cList
      end if
    end for

  for each value x in bList do the following
    if x is not in cList then 
      insert x into cList
      end if
    end for

*/
void merge(const COOL &aList, const COOL &bList, COOL &cList)
  {
  cout << "MISSING CODE\n";
  }




COOL & COOL::operator = (const COOL &aList)
  {
  cout << "Did you just call me?\n";

  for (int i=0; i<=MAX_SIZE+1; i++)
    this->a[i] = aList.a[i];

  this->n = aList.n;

  return *this;
  }


void test_operator_assign(void)
  {
  cout << "--------------------\n";
  cout << "test_operator_assign\n";
  cout << "--------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList('r');
    myList.display();

    COOL yourList('r');
    yourList.display();

    COOL hisList('r');
    hisList.display();

    myList = yourList = hisList;

    cout << "After myList = yourList = hisList;\n";

    myList.display();
    yourList.display();
    hisList.display();

    if (myList == yourList)
      cout << "myList == yourList\n";
    else
      cout << "myList != yourList\n";


    cout << "........................\n";
    }

  }



void test_constructorCopy(void)
  {
  cout << "--------------------\n";
  cout << "test_constructorCopy\n";
  cout << "--------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList('r');

    myList.display();

    COOL yourList(myList);
    yourList.display();

    if (myList == yourList)
      cout << "myList == yourList\n";
    else
      cout << "myList != yourList\n";


    cout << "........................\n";
    }

  }



COOL::COOL(const COOL &aList)
  {
  cout << "You just called copy constructor\n";
  for (int i=0; i<=MAX_SIZE+1; i++)
    this->a[i] = aList.a[i];

  this->n = aList.n;
  }


void test_has(void)
  {
  cout << "--------------------\n";
  cout << "test_has\n";
  cout << "--------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList('r');

    myList.display();

    int x = MIN_VALUE + rand()%(MAX_VALUE - MIN_VALUE + 1);

    cout << x << endl;

    if (myList.has(x))
      cout << "has it\n";
    else
      cout << "DOES NOT have it\n";

    cout << "........................\n";
    }

  }



bool COOL::has(int x) const
  {
  if (2 == this->n)
    return false;

  for (int i=1; i<=this->n-2; i++)
    if (this->a[i] == x)
      return true;

  return false;
  }


void test_constructorChar(void)
  {
  cout << "--------------------\n";
  cout << "test_constructorChar\n";
  cout << "--------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList('d');

    myList.display();

    COOL yourList('x');

    yourList.display();

    cout << "........................\n";
    }

  }


COOL::COOL(char ch)
  {
  init();

  if ('r' == ch)
    {
    int n = rand()%(MAX_SIZE+1);
    this->populate(n);
    }
  else if ('d' == ch)
    {
    //supply the missing code
    }
  }


void test_operatorUniPlus(void)
  {
  cout << "------------------------\n";
  cout << "test_operatorUniPlus\n";
  cout << "------------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    int n = rand()%MAX_SIZE;
    COOL myList(n);

    myList.display();

    cout << "myList.sum() = " <<  +myList << endl;

    cout << "........................\n";
    }
  }


int COOL::operator +(void) const
  {
  int result = 0;
  for (int i=1; i<=n-2; i++)
    result = result + a[i];

  return result;
  }



void test_sum(void)
  {
  cout << "------------------------\n";
  cout << "test_sum\n";
  cout << "------------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    int n = rand()%MAX_SIZE;
    COOL myList(n);

    myList.display();

    cout << "myList.sum() = " << myList.sum() << endl;

    cout << "........................\n";
    }
  }


int COOL::sum(void) const
  {
  int result = 0;
  for (int i=1; i<=n-2; i++)
    result = result + a[i];

  return result;
  }


void test_operator_isNotEqual(void)
  {
  cout << "------------------------\n";
  cout << "test_operator_isNotEqual\n";
  cout << "------------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    int n = rand()%MAX_SIZE;
    COOL myList(n);

    int m = rand()%MAX_SIZE;
    COOL yourList(m);

    myList.display();
    yourList.display();

    if (myList.operator !=(yourList))
      cout << "myList is NOT equal to yourList\n";
    else
      cout << "myList is equal to yourList\n";

    cout << "myList = yourList;\n";
    myList = yourList;
    myList.display();
    yourList.display();

    if (myList != yourList)
      cout << "myList is NOT equal to yourList\n";
    else
      cout << "myList is equal to yourList\n";


    cout << "........................\n";
    }
  }


bool COOL::operator !=(const COOL &list2) const
  {
  return !(*this == list2);
  /*
  if (*this == list2)
    return false;
  else
    return true;
  */
  /*
  if (n != list2.n)
    return true;

  if (n <= 2)
    return false;

  for (int i=0; i<=n-1; i++)
    if (a[i] != list2.a[i])
      return true;

  return false;
  */
  }


void test_operator_isEqual(void)
  {
  cout << "------------\n";
  cout << "test_operator_isEqual\n";
  cout << "------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    int n = rand()%MAX_SIZE;
    COOL myList(n);

    int m = rand()%MAX_SIZE;
    COOL yourList(m);

    myList.display();
    yourList.display();

    if (myList.operator ==(yourList))
      cout << "myList is equal to yourList\n";
    else
      cout << "myList is NOT equal to yourList\n";

    cout << "myList = yourList;\n";
    myList = yourList;
    myList.display();
    yourList.display();

    if (myList == yourList)
      cout << "myList is equal to yourList\n";
    else
      cout << "myList is NOT equal to yourList\n";


    cout << "........................\n";
    }
  }


bool COOL::operator ==(const COOL &list2) const
  {
  if (n != list2.n)
    return false;

  if (n <= 2)
    return true;

  for (int i=0; i<=n-1; i++)
    if (a[i] != list2.a[i])
      return false;

  return true;
  }


void test_isEqual(void)
  {
  cout << "------------\n";
  cout << "test_isEqual\n";
  cout << "------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    int n = rand()%MAX_SIZE;
    COOL myList(n);

    int m = rand()%MAX_SIZE;
    COOL yourList(m);

    myList.display();
    yourList.display();

    if (myList.isEqual(yourList))
      cout << "myList is equal to yourList\n";
    else
      cout << "myList is NOT equal to yourList\n";

    cout << "myList = yourList;\n";
    myList = yourList;
    myList.display();
    yourList.display();

    if (myList.isEqual(yourList))
      cout << "myList is equal to yourList\n";
    else
      cout << "myList is NOT equal to yourList\n";


    cout << "........................\n";
    }
  }


bool COOL::isEqual(const COOL &list2) const
  {
  if (n != list2.n)
    return false;

  if (n <= 2)
    return true;

  for (int i=0; i<=n-1; i++)
    if (a[i] != list2.a[i])
      return false;

  return true;
  }


void test_isEqualFriend(void)
  {
  cout << "------------------\n";
  cout << "test_isEqualFriend\n";
  cout << "------------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    int n = rand()%MAX_SIZE;
    COOL myList(n);

    int m = rand()%MAX_SIZE;
    COOL yourList(m);

    myList.display();
    yourList.display();

    if (isEqual(myList, yourList))
      cout << "myList is equal to yourList\n";
    else
      cout << "myList is NOT equal to yourList\n";

    cout << "myList = yourList;\n";
    myList = yourList;
    myList.display();
    yourList.display();

    if (isEqual(myList, yourList))
      cout << "myList is equal to yourList\n";
    else
      cout << "myList is NOT equal to yourList\n";


    cout << "........................\n";
    }
  }


bool isEqual(const COOL &list1, const COOL &list2)
  {
  if (list1.n != list2.n)
    return false;

  if (list1.n <= 2)
    return true;

  for (int i=0; i<=list1.n-1; i++)
    if (list1.a[i] != list2.a[i])
      return false;

  return true;
  }


void test_constructorN(void)
  {
  cout << "-----------------\n";
  cout << "test_constructorN\n";
  cout << "-----------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    int n = rand()%MAX_SIZE;
    COOL myList(n);

    myList.display();

    cout << "........................\n";
    }
  }


COOL::COOL(int n)
  {
  //a[0] = -INFINITY;
  //a[1] = +INFINITY;

  //for (int i=2; i<=MAX_SIZE+1; i++)
  //  a[i] = UNDEFINED;

  //this->n = 2;

  this->init();

  this->populate(n);
  }


/*
Description: 
  displays distinct values from the list
Examples:
  [-inf, 1, 1, 1, 2, 5, 5, +inf] => 
   -inf  1
   1     3
   2     1
   5     2
   +inf  1

Algorithms0:
  print the first value
  do the following for the rest of the values
    if the next value != value printed 
      print next value, prinedValue=nextValue

    
Algorithms0:
  i=0
  x=a[i]
  print x
  do the following for i=1 to n-1
    if a[i] != x then
       x = a[i]
       print x
       end if
    end do



Code:
Output:
*/
void COOL::displayDistinctWithCounts(void) const //p04
  {
  /*
  */
  }
/*
Description: 
  displays distinct values from the list
Examples:
  [-inf, 1, 1, 1, 2,+inf] => -inf, 1, 2, +inf
Algorithms0:
  print the first value
  do the following for the rest of the values
    if the next value != value printed 
      print next value, prinedValue=nextValue

    
Algorithms0:
  i=0
  x=a[i]
  print x
  do the following for i=1 to n-1
    if a[i] != x then
       x = a[i]
       print x
       end if
    end do



Code:
Output:
*/
void COOL::displayDistinct(void) const //p04
  {
  }


void test_sortBubble2(void)
  {
  cout << "------------\n";
  cout << "test_sortBubble2\n";
  cout << "------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList;

    int m = rand()%MAX_SIZE;
    int p = myList.populate(m);

    myList.display();

    myList.shuffle();

    cout << "After shuffle\n";

    myList.display();

    myList.sortBubble2();

    cout << "After sortBubble2\n";

    myList.display();
    cout << "........................\n";
    }
  }

/*
sortBubble2

Description:
  sort in increasing order
Examples:
  [-inf,6,2,3,+inf] => [-inf,2,3,6,+inf]
Algorithm0:
  Possibilities: n<=3,n>3

  if n<=3 then exit
  do
    {
    sorted=true
    scan values from left to right
      if a pair is out of order then
        swap the values and set sorted=false
    }
    while (!sorted)


Algorithm1:
  if n<=3 then exit
  do
    {
    sorted=true
    for i=1 to n-3 do the following
      if a[i]>a[i+1] then
        swap a[i], a[i+1]
        sorted=false
        end if
      next i
    }
    while (!sorted)
    
Code:
Output:
*/

void COOL::sortBubble2(void)
  {
  //supply the code Project #03
  //due 9/26/2005
  }


void test_sortBubble1(void)
  {
  cout << "------------\n";
  cout << "test_sortBubble1\n";
  cout << "------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList;

    int m = rand()%MAX_SIZE;
    int p = myList.populate(m);

    myList.display();

    myList.shuffle();

    cout << "After shuffle\n";

    myList.display();

    myList.sortBubble1();

    cout << "After sortBubble1\n";

    myList.display();
    cout << "........................\n";
    }
  }

/*
Description:
  sort in increasing order
Examples:
  [-inf,6,2,3,+inf] => [-inf,2,3,6,+inf]
Algorithms:
  Possibilities: n<=3,n>3

  if n<=3 then exit
  for i=1 to m-1
    try to put values in order
    next i


  if n<=3 then exit
  for i=1 to n-3
    for j=1 to n-3
      if a[j] > a[j+1] then 
         swap a[j],a[j+1]
      next j
    next i

    
Code:
Output:
*/
void COOL::sortBubble1(void)
  {
  if (n<=3)
    return;
  for (int i=1; i<=n-3; i++)
    for (int j=1; j<=n-3; j++)
      if (a[j] > a[j+1]) swap(a[j],a[j+1]);
  }


void COOL::swap(int &x, int &y)
  {
  int t=x;
  x = y;
  y = t;
  }


void test_shuffle(void)
  {
  cout << "------------\n";
  cout << "test_shuffle\n";
  cout << "------------\n";

  for (int i=1; i<=TEST_COUNT; i++)
    {
    COOL myList;

    int m = rand()%MAX_SIZE;
    int p = myList.populate(m);

    myList.display();

    myList.shuffle();

    cout << "After shuffle\n";

    myList.display();
    cout << "........................\n";
    }
  }

/*
Description:
  Shuffles the values in the list
  do not touch -INFINITY and +INFINITY
Example:
Algorithm:
  Scheme1: Shift to left or right
  Scheme2: swap two randomly chosen values
  Scheme3: move a randomly chosen value to the top/bottom
  Scheme4: move a randomly chosen value to another random position
  Scheme5: move lower approx half to the top
  Scheme6: Split and bridge
  Scheme7: Pick random value and move to a new list

  Scheme2:
    do the following n times
      pick p1, p2 randomly between 1 and n-2
      swap values at p1 and p2
*/
void COOL::shuffle(void)
  {
  if (n <= 3)
    return;

  for (int i=1; i<=n; i++)
    {
    int p1 = 1 + rand()%(n-2 - 1 + 1);
    int p2 = 1 + rand()%(n-2 - 1 + 1);
    //cout << "n=" << n << " p1=" << p1 << " p2=" << p2 << endl;
    //cout << "before swap " << a[p1] << " " << a[p2] << endl;
    swap(a[p1], a[p2]);
    //cout << "after  swap " << a[p1] << " " << a[p2] << endl;
    }
  }


void test_populate(void)
  {
  COOL myList;
  myList.display();
  for (int i=1; i<=TEST_COUNT; i++)
    {
    int m = rand()%MAX_SIZE;
    int p = myList.populate(m);
    cout << "asked for m = " << m << " inserted " << p << " values\n";
    myList.display();
    }
  }

/*
Description:
  insert m random values into an existing no-empty list
  returns the actual number of items added
Example:
Algorithm:
  count = 0
  for i=1 to m
    x = random value bet min and max
    insert x into the list
    if overflow then break else count++
    next i

  return count
*/
int COOL::populate(int m)
  {
  int count = 0;
  for (int i=1; i<=m; i++)
    {
    int x = MIN_VALUE + rand()%(MAX_VALUE - MIN_VALUE + 1);
    //int p = myList.insert(x);
    //int p = (*this).insert(x);
    //int p = this->insert(x);
    int p = insert(x);
    //this->display();
    if (p != -1)
      count++;
    else
      break;
    }

  return count;
  }


void test_insert(void)
  {
  COOL myList;
  myList.display();
  for (int i=1; i<=TEST_COUNT; i++)
    {
    //int x = rand()%MAX_VALUE; //p1: change to get values fro -10 to 10
    // -11, -10, -9, -8, ..., 0, 1, 2, ..., 9, 10
    // -11 + (0, 1, ..., 21)
    // MIN_VALUE + (0... (MAX_VALUE-MIN_VALUE))
    // MIN_VALUE + rand()%(MAX_VALUE - MIN_VALUE + 1)
    int x = MIN_VALUE + rand()%(MAX_VALUE - MIN_VALUE + 1);
    int p = myList.insert(x);
    myList.display();
    if (p != -1)
      cout << "Value " << x << " was inserted at " << p << " location\n";
    else
      cout << "Overflow\n";
    }
  }

/*
int COOL::insert(int x)
inserts x into the list keeping it in order
possibilities:
  (a) x is out of range
  (b) x is in range
      (c) list is empty
      (d) x >= the last value in the list
      (e) x < the first value in the list
      (f) x is between two values in the list

Solutions:
  (a) add to the end and sort
  (b) four cases
  (c) start with dummy values and just one case

Chosen
  start with dummy values and have just one case
  insert x in the list
  a[n] = x
  check if a[n-1] <= a[n] return n
           else swap a[n-1], a[n]
  check if a[n-2] <= a[n-1] return n-1
           else swap a[n-2], a[n-1]
           ....
  check if a[0] <= a[1] return 1
           else swap a[0], a[1] will never happen


  m=n
  a[m] = x
  while (a[m-1] > a[m])
    swap a[m-1], a[m]
    m--
    end while
  
  n++
  return m
*/
int COOL::insert(int x)
  {
  if (n>=(MAX_SIZE+2))//??
    return -1;

  int m=n;
  a[m] = x;

  while (a[m-1] > a[m])
    {
    int temp = a[m-1];
    a[m-1] = a[m];
    a[m] = temp;
    m--;
    }
  
  n++;
  return m;
  }


void COOL::display(void) const
  {
  //cout << "COOL[" << n << "]: ";

  //for (int i=0; i<=MAX_SIZE+1; i++)
  //  cout << a[i] << ' ';
  //
  //cout << endl;

  cout << "COOL[" << n-2 << "]: ";

  for (int i=1; i<=n-2; i++)
    cout << a[i] << ' ';
  
  cout << endl;
  }

  
COOL::COOL(void)
  {
  cout << "Default constructor is called\n";
  this->init();
  }


void COOL::init(void)
  {
  a[0] = -INFINITY;
  a[1] = +INFINITY;

  for (int i=2; i<=MAX_SIZE+1; i++)
    a[i] = UNDEFINED;

  n = 2;
  }