/**
 * HeapTester_rand
 */

public class HeapTester
{

    public static void meldArr(int a[], int b[], int length)
    {
    	int i=length+40;
    	for (int j=0; j<length+4;j++)
    	{
    		//System.out.println(i);
    		a[i]=b[j];
    		i++;
    	}
    	
    	
    }
    public static int getMin(int[] a) {
        int minVal = 999999;
        for (int i=0; i<a.length; i++)
        {
            if (minVal > a[i]) minVal = a[i];
        }

        return minVal;
    }
    public static void delMin(int[] a) {
        int minVal = 999999;
        int minIndex = 0;
        for (int i=0; i<a.length; i++)
        {
            if (minVal > a[i])
            {
                minVal = a[i];
                minIndex = i;
            }
        }
        a[minIndex] = 999999;
    }
    
    public static boolean delMinCheck(Heap h, int[] a)
    { 
    	if (getMin(a)!= h.getMin())
    		return false;
    	return true;
    }
    
    public static void init(int[] a) {
        for (int i=0; i<a.length; i++)
        {
            a[i] = 999999;
        }
    }

    public static void main(String[] args) {

        int isHeapAfterInsertError = 0;
        int isHeapAfterDeleteMinError = 0;  
        int getMinAfterInsertError = 0;
        int getMinAfterDeleteMinError = 0;
        int wrongValDeletedError = 0;
		int DSGrade = 50;
		try{

        for (int l = 1; l < 100; l++) 
        {

            int ranges[] = {1, l / 10 + 1, l, l*1000}; // many repetitions, lots, a few, probably none;
            for (int r = 0; r < 4; r++)
            {
                int range = ranges[r];

                //System.out.println("Test for array length = " + l +  ", with range = " + range);

               // int[] a = new int[l];
                int[] a_for_check = new int[(3*l)+1000];
                int[] b_for_check = new int[l+50];
                int heapsize = 0;
                int heapsizeb=0;
                int value = -1;
                Heap heap = new Heap();
                Heap heapb = new Heap();
                init(a_for_check);
                init(b_for_check);
                
                for (int i=0; i<l; i++)
                {

                    int insOrDel = (int) Math.round(Math.random()*6);

                    if (insOrDel == 4) //delete Min
                    {

                        if (heapsize > 0)
                        {
                            //System.out.println("deleteMin" );
                            delMin(a_for_check);
                            heap.deleteMin();     
                            heapsize--;    
                        }
                    }
                    /*if (insOrDel == 3) //delete Min
                    {
                        if (heapsize > 0)
                        {
                        	System.out.println("deleteMin" );
                            if (!delMinCheck(heap, a_for_check))
                            	wrongValDeletedError++;
                            heap.deleteMin();     
                            heapsize--;    
                            outputHeap(heap);
                        }

                    }*/

                    else // insOrDel == 0,1,2,5 - for more insertions
                    {
                        value = (int) Math.round(Math.random() * range);
                       // System.out.println("Insert " +  value);
                        a_for_check[i] = value;              
                        heap.insert(value);
                        heapsize++;
                        //outputHeap(a);
                    }   

                    if (heapsize > 0)
                    {
                        if (heap.isHeap() != true )
                        {
                        	if (insOrDel == 4)
                            {
                                isHeapAfterDeleteMinError++;
                                System.out.println("isHeapAfterDeleteMinError");
                            }
                        	else
                            {
                                isHeapAfterInsertError++;
                                System.out.println("isHeapAfterInsertError");
                            }
                            //break;
                        }
                        if (getMin(a_for_check) != heap.getMin())
                        {
                            if (insOrDel == 4)
                            {
                                getMinAfterDeleteMinError++;
                                System.out.println("getMinAfterDeleteMinError");
                            }
                           
                            else
                            {
                                getMinAfterInsertError++;
                                System.out.println("getMinAfterInsertError");
                            }
                            //break;
                        }
                    }
                }
                    
                    
                    
                    
                    
                    
                    for (int j=0; j<l; j++)
                    {
                    	//System.out.println("in BBBB");

                        int jnsOrDel = (int) Math.round(Math.random()*6);

                        if (jnsOrDel == 4) //delete Min
                        {

                            if (heapsizeb > 0)
                            {
                                //
                                //System.out.println("b deleteMin" );
                                delMin(b_for_check);
                                heapb.deleteMin();     
                                heapsizeb--;    
                            }
                        }
                        /*if (insOrDel == 3) //delete Min
                        {
                            if (heapsize > 0)
                            {
                            	System.out.println("deleteMin" );
                                if (!delMinCheck(heap, a_for_check))
                                	wrongValDeletedError++;
                                heap.deleteMin();     
                                heapsize--;    
                                outputHeap(heap);
                            }

                        }*/

                        else // insOrDel == 0,1,2,5 - for more insertions
                        {
                            value = (int) Math.round(Math.random() * range);
                           //System.out.println("B Insert " +  value);
                            b_for_check[j] = value;              
                            heapb.insert(value);
                            heapsizeb++;
                            //outputHeap(a);
                            //System.out.println("end B Insert " +  value);
                            
                        }   

                        if (heapsizeb > 0)
                        {
                        	
                        	//System.out.println("Checking " +  value);
                            if (heapb.isHeap() != true )
                            {
                            	if (jnsOrDel == 4)
                                {
                                    isHeapAfterDeleteMinError++;
                                    System.out.println("isHeapAfterDeleteMinError");
                                }
                            	else
                                {
                                    isHeapAfterInsertError++;
                                    System.out.println("isHeapAfterInsertError");
                                }
                                //break;
                            }
                            
                          //System.out.println("first obstacle" +  value);
                            if (getMin(b_for_check) != heapb.getMin())
                            {
                                if (jnsOrDel == 4)
                                {
                                    getMinAfterDeleteMinError++;
                                   // System.out.println("getMinAfterDeleteMinError");
                                }
                                
                                else
                                {
                                    getMinAfterInsertError++;
                                 //   System.out.println("getMinAfterInsertError");
                                }
                                //break;
                            }
                        }
                    }
                       // System.out.println("second obstacle" +  value);
                        
                        heap.meld(heapb);
                        meldArr(a_for_check,b_for_check,l+20);
                        heapsize+=heapsizeb;
                        
                       for (int k=0; k<l-5; k++)
                        {
                        	
                        	//System.out.println("YOYOY");

                            int jnsOrDel = (int) Math.round(Math.random()*6);

                            if (jnsOrDel == 4) //delete Min
                            {

                                if (heapsize > 0)
                                {
                                    //System.out.println("deleteMin" );
                                    delMin(a_for_check);
                                    heap.deleteMin();     
                                    heapsize--;    
                                }
                            }
                           

                            else // insOrDel == 0,1,2,5 - for more insertions
                            {
                                value = (int) Math.round(Math.random() * range);
                               // System.out.println("Insert " +  value);
                                a_for_check[(2*l)+300+k] = value;              
                                heap.insert(value);
                                heapsize++;
                                //outputHeap(a);
                            }   

                            if (heapsize > 0)
                            {
                                if (heap.isHeap() != true )
                                {
                                	if (jnsOrDel == 4)
                                    {
                                        isHeapAfterDeleteMinError++;
                                        System.out.println("isHeapAfterDeleteMinError");
                                    }
                                	else
                                    {
                                        isHeapAfterInsertError++;
                                        System.out.println("isHeapAfterInsertError");
                                    }
                                    //break;
                                }
                                if (getMin(a_for_check) != heap.getMin())
                                {
                                    if (jnsOrDel == 4)
                                    {
                                        getMinAfterDeleteMinError++;
                                        System.out.println("DEL ERROR: " + getMin(a_for_check)+ " "+ heap.getMin());
                                    }
                                    else
                                    {
                                        getMinAfterInsertError++;
                                        System.out.println("ERROR2: " + getMin(a_for_check)+ " "+ heap.getMin());
                                    }
                                    //break;
                                }
                            }
                        }
                       
                
            }
        }
        
		}catch(Exception e){
		
			System.out.println("DSError "+e);
			DSGrade -=20;
		}catch(Error e){
			System.out.println("DSError "+e);
			DSGrade -=25;
		}

        if (isHeapAfterInsertError > 0)
        {
            System.out.println("DSError " + isHeapAfterInsertError+"isHeapAfterInsertErrors");

			DSGrade -=2;
        }
        if (isHeapAfterDeleteMinError > 0)
        {
            System.out.println("DSError " + isHeapAfterDeleteMinError+"isHeapAfterDeleteMinErrors");
			DSGrade -=2;
        }
        if (getMinAfterInsertError > 0)
        {
            System.out.println("DSError " + getMinAfterInsertError+"getMinAfterInsertErrors");
			DSGrade -=2;
        }
        if (getMinAfterDeleteMinError > 0)
        {
            System.out.println("DSError " + getMinAfterDeleteMinError+"getMinAfterDeleteMinErrors");
			DSGrade -=2;
        }
       
        if (wrongValDeletedError > 0)
        {
            System.out.println("DSError "+ wrongValDeletedError+"wrongValDeletedErrors");
			DSGrade -=2;
        }
		int totalErrors = isHeapAfterInsertError+isHeapAfterDeleteMinError+
			getMinAfterInsertError+
			getMinAfterDeleteMinError+
			wrongValDeletedError;
		
		if(totalErrors>10000)
		{DSGrade-=2;}
		if(totalErrors>20000)
		{DSGrade-=2;}
		//if(totalErrors>50)
		//{DSGrade-=2;}
		if(totalErrors>100000)
		{DSGrade-=2;}
		
		System.out.println("DSGrade "+DSGrade);
        System.out.println("End of tests");

    }
}










