//package ex2;


public class Ex2Tester
{
	
	public static boolean treeSizeCheck(Heap heap, boolean isAfterDelete) {
		int[] sizes = heap.treesSize();
		int sum=0;
		//System.out.println("++++++++++++++++++++++++++++++++++++++++");
		for (int i=0; i<sizes.length; i++)
		{
			if (i!=sizes.length-1) {
				if (sizes[i] > sizes[i+1])
					return false;
				if (isAfterDelete && sizes[i] == sizes[i+1])
					return false;
			}
			if ((sizes[i] & sizes[i]-1)!=0)
				return false;
			sum+=sizes[i];
			
			//System.out.println("" + sizes[i]+" ");
			
		}
		//System.out.println("++++++++++++++++++++++++++++++++++++++++");
		return heap.size()==sum;
	}
	
	
	public static void main(String[] args)
	{
		// initialize tests success array to false
		boolean[] success = new boolean[8];
		for (int i=0; i<success.length; i++)
		{
			success[i] = false;
		}
		
		Heap heap = null;
		Heap heap2 = null;
		
		// create array of values between 700-1700
		// like this - 700, 702, 702, 704, 704, 706, 706 ...
		int[] values = new int[1000];
		for (int j=0; j<values.length; j++)
		{
			values[j] = 700 + j + j%2;
		}
		
		// hide some minimum value in it
		int hiddenMin = 113;
		values[values.length / 2] = hiddenMin;
		
		// create array of values 20,19,18,....,1
		int[] values2 = new int[20];
		for (int j=0; j<values2.length; j++)
		{
			values2[j] = values2.length - j;
		}
		
		// create custom array of values
		int[] values3 = new int[] {6,1,19,17,9,2,10,12,18,
				5,15,11,4,16,13,20,7,3,8,14};

		
		
		int prevLen = 0;
		for (int i=0; i<success.length; i++)
		{
			try
			{
				if (i==0)
				{
					heap = new Heap();
					success[i] = heap.isHeap() && heap.empty() && treeSizeCheck(heap, true);
				}
				else if (i==1)
				{
					for (int value : values)
					{
						heap.insert(value);
					}
					success[i] = (heap.isHeap()) && 
						(heap.size() == values.length) &&
						(heap.findMin() == hiddenMin) &&
						treeSizeCheck(heap, false);
				}
				else if (i==2)
				{
					heap.deleteMin();
					success[i] = (heap.isHeap()) && 
						(heap.size() == values.length-1) &&
						(heap.findMin() == 700) &&
						treeSizeCheck(heap, true);
				}
				else if (i==3)
				{
					heap.deleteMin();
					success[i] = (heap.isHeap()) && 
						(heap.size() == values.length-2) &&
						(heap.findMin() == 702) &&
						treeSizeCheck(heap, true);
					heap.deleteMin();
					success[i] = success[i] &&
						(heap.isHeap()) && 
						(heap.size() == values.length-3) &&
						(heap.findMin() == 702) &&
						treeSizeCheck(heap, true);
					heap.deleteMin();
					success[i] = success[i] &&
						(heap.isHeap()) && 
						(heap.size() == values.length-4) &&
						(heap.findMin() == 704) &&
						treeSizeCheck(heap, true);
					prevLen = heap.size();
				}
				else if (i==4)
				{
					int n = 0;
					for (int value : values3)
					{
						heap.insert(value);
						if (!heap.isHeap() || heap.empty() || !treeSizeCheck(heap, false))
						{
							n++;
						}
					}
					success[i] = (n == 0) &&
						(heap.isHeap()) && 
						(heap.size() == (prevLen + values2.length));
				}
				else if (i==5 || i==7)
				{
					int n = 0;
					for (int j=(values2.length-1); j>=0; j--)
					{
						prevLen = heap.size();
						if (!heap.isHeap() || heap.findMin()!=values2[j])
						{
							n++;
						}
						heap.deleteMin();
						if (!heap.isHeap() || heap.size()!=(prevLen-1) || !treeSizeCheck(heap, true))
						{
							n++;
						}
					}
					success[i] = (n==0) && (heap.findMin() == 704);
					prevLen = heap.size();
				}
				else if (i==6)
				{
					heap = new Heap();
					heap2 = new Heap();
					for (int j=0; j<values3.length; j++)
					{
						if (j%2 == 0)
						{
							if (j>=3 && values[j] != hiddenMin)
							{
								heap.insert(values[j]);
							}
							heap2.insert(values3[j]);
						}
						else
						{
							if (j>=3 && values[j] != hiddenMin)
							{
								heap2.insert(values[j]);
							}
							heap.insert(values3[j]);
						}
					}
					for (int j=values3.length; j<values.length; j++)
					{
						if (j>=3 && values[j] != hiddenMin)
						{
							heap.insert(values[j]);
						}
					}
					heap2.meld(heap);
					success[i] = (heap2.isHeap() && 
							heap2.size() == values3.length + values.length - 4) &&
							treeSizeCheck(heap2, false);
					heap = heap2;
				}
				else if (i==8)
				{
					for (int j=0; j<heap.size(); j++)
					{
						heap.deleteMin();
					}
					success[i] = (heap.isHeap() && 
							heap.empty() && 
							heap.size() == 0) &&
							treeSizeCheck(heap, true);
				}
			}
			catch (Exception e)
			{
				System.out.println("Exception Caught On Test" + i + " : "+e);
			}
			System.out.println("Success On Test " + i + " = " + success[i]);
		}

		int n = 0;
		for (boolean value : success)
		{
			if (value)
			{
				n++;
			}
		}
		System.out.println("=========================================");
		System.out.println("Total : " + n + "/" + success.length);
		System.out.println("Grade : " + (float) 100 * n / success.length);
	}
	

}

