
// CS410, Summer 1998
// Homework 6 Provided Code
// Tester.java

// Assuming a properly-implemented Sorter.java, this file creates and tests
// 160 kinds of Sorter objects.

import java.util.*;
import java.io.*;

class Tester {

	static final int        NUMBER_PER_RUN    = 4; 
	static final int[]      sortSizes         = {10000, 20000, 30000, 40000};
	static final int[]      switchMethodSizes = {0, 10, 25, 40}; 
	static final boolean[]  doShorterFirst    = {true, false};
	static final int[]      medianOf          = {1, 3, 5, 7, 9};

	// generate a random array of OrderedInteger objects.
	static Sortable[] makeRandomArray(int size) {
		Random r = new Random();
		Sortable[] array = new OrderedInteger[size];
		for (int i=0; i < size; i++)
			array[i] = new OrderedInteger(r.nextInt());
		return array;
	}

	// sorts the array with the given Sorter.  Output average time-elapsed.
	static void doTimedSort(PrintWriter outfile, Sortable[] toSort, Sorter q) {
		int total = 0;
		for (int j=0; j<NUMBER_PER_RUN; j++) {
			
			// have to make a copy each time so it isn't already sorted.
			Sortable [] copy = new Sortable[toSort.length];
			System.arraycopy(toSort, 0, copy, 0, toSort.length);
			
			// run garbage collector so sorting isn't penalized.
			System.gc();
			
			// start the clock, do the sort, stop the clock
			long before = System.currentTimeMillis();
			q.sort(copy);
			long after = System.currentTimeMillis();
			total += after - before;

			// this doesn't check permutation, but it is still a debugging help.
			for (int i=1; i < toSort.length; i++) {
				if (copy[i].lessThan(copy[i-1]))
					throw new Error("sort has a bug");
			}

		}
		outfile.println(total / NUMBER_PER_RUN);
	}

	// iterate through all 160 combinations, creating output file as you go.
	static void doAllTests(PrintWriter outfile) {
		for (int i=0; i < sortSizes.length; i++) {
			Sortable [] randomOnes = makeRandomArray(sortSizes[i]);
			for (int j=0; j < switchMethodSizes.length; j++)
			for (int k=0; k < doShorterFirst.length; k++) 
			for (int l=0; l < medianOf.length; l++) {
				// let the user know we're on the next iteration
				System.out.println(i + "" + j); 
				System.out.flush();
				
				// output the parameters
				outfile.print(switchMethodSizes[j] +"\t"
							  + doShorterFirst[k]  + "\t" 
							  + medianOf[l]        + "\t"
							  + sortSizes[i]       + "\t");
				
				// make the right Sorter and do the sort
				Sorter q = new Sorter(switchMethodSizes[j],
									  doShorterFirst[k],
									  medianOf[l]);
				doTimedSort(outfile, randomOnes, q);
			}
		}
	}

	// Basically just calls doAllTests
	public static void main (String[] args) throws IOException {
		PrintWriter outfile = new PrintWriter(new FileWriter("hw6results.txt"));
		long start = System.currentTimeMillis();
		doAllTests(outfile);
		long end = System.currentTimeMillis();
		outfile.close();
		System.out.println("Total time: " + (end-start) + "milliseconds");
		System.in.read();
	}
}
