int main(int argc, char *argv[])
{
    int sequence[] = {3, 3242, 21, 55, 653, 19, 139, 459, 138, 45349, 19, 2, 1}; 
    int sequence_length = sizeof(sequence)/sizeof(sequence[0]);

    printf("Sorting %d values in sequence ", sequence_length);
    print_sequence(sequence, sequence_length);

    insertion_sort(sequence, sequence_length);

    printf("Done sorting. Result ");
    print_sequence(sequence, sequence_length);

    printf("Testing if result sort is valid....");
    int pass = test_insertion_sort(sequence, sequence_length);
    if (pass)
        printf("Yes!\n");
    else
        printf("No!\n");

    return 0;
}
int main(int argc, char** argv) {

	double dZero = 0.0;

	// output command for documentation:
	int i;
	for (i = 0; i < argc; ++i)
		printf("%s ", argv[i] );
	printf("\n");

	if (argc > 1) iterations = atoi(argv[1]);
	if (argc > 2) init_value = (double) atof(argv[2]);
	
	// seed the random number generator so we get repeatable results
	srand( (int)init_value + 123 );
	

	::fill(dpb, dpe, double(init_value));
	
	std::vector<double>   vec_data;
	vec_data.resize(SIZE);

	::fill(vec_data.begin(), vec_data.end(), double(init_value));
	
	rtvdp rtvdpb(vec_data.end());
	rtvdp rtvdpe(vec_data.begin());
	
	rtrvdp rtrvdpb(vec_data.rend());
	rtrvdp rtrvdpe(vec_data.rbegin());
	
	rtrtvdp rtrtvdpb(rtvdpe);
	rtrtvdp rtrtvdpe(rtvdpb);

	test_accumulate(dpb, dpe, dZero, "double pointer verify2");
	test_accumulate(vec_data.begin(), vec_data.end(), dZero, "double vector iterator");
	test_accumulate(rdpb, rdpe, dZero, "double pointer reverse");
	test_accumulate(vec_data.rbegin(), vec_data.rend(), dZero, "double vector reverse_iterator");
	test_accumulate(rtvdpb, rtvdpe, dZero, "double vector iterator reverse");
	test_accumulate(rrdpb, rrdpe, dZero, "double pointer reverse reverse");
	test_accumulate(rtrvdpb, rtrvdpe, dZero, "double vector reverse_iterator reverse");
	test_accumulate(rtrtvdpb, rtrtvdpe, dZero, "double vector iterator reverse reverse");

	summarize("Vector accumulate", SIZE, iterations, kShowGMeans, kShowPenalty );



	// the sorting tests are much slower than the accumulation tests - O(N^2)
	iterations = iterations / 1000;
	
	std::vector<double>   vec_dataMaster;
	vec_dataMaster.resize(SIZE);
	
	// fill one set of random numbers
	fill_random<double *, double>( dMpb, dMpe );
	
	// copy to the other sets, so we have the same numbers
	::copy( dMpb, dMpe, vec_dataMaster.begin() );
	
	rtvdp rtvdMpb(vec_dataMaster.end());
	rtvdp rtvdMpe(vec_dataMaster.begin());
	
	rtrvdp rtrvdMpb(vec_dataMaster.rend());
	rtrvdp rtrvdMpe(vec_dataMaster.rbegin());
	
	rtrtvdp rtrtvdMpb(rtvdMpe);
	rtrtvdp rtrtvdMpe(rtvdMpb);

	test_insertion_sort(dMpb, dMpe, dpb, dpe, dZero, "insertion_sort double pointer verify2");
	test_insertion_sort(vec_dataMaster.begin(), vec_dataMaster.end(), vec_data.begin(), vec_data.end(), dZero, "insertion_sort double vector iterator");
	test_insertion_sort(rdMpb, rdMpe, rdpb, rdpe, dZero, "insertion_sort double pointer reverse");
	test_insertion_sort(vec_dataMaster.rbegin(), vec_dataMaster.rend(), vec_data.rbegin(), vec_data.rend(), dZero, "insertion_sort double vector reverse_iterator");
	test_insertion_sort(rtvdMpb, rtvdMpe, rtvdpb, rtvdpe, dZero, "insertion_sort double vector iterator reverse");
	test_insertion_sort(rrdMpb, rrdMpe, rrdpb, rrdpe, dZero, "insertion_sort double pointer reverse reverse");
	test_insertion_sort(rtrvdMpb, rtrvdMpe, rtrvdpb, rtrvdpe, dZero, "insertion_sort double vector reverse_iterator reverse");
	test_insertion_sort(rtrtvdMpb, rtrtvdMpe, rtrtvdpb, rtrtvdpe, dZero, "insertion_sort double vector iterator reverse reverse");

	summarize("Vector Insertion Sort", SIZE, iterations, kShowGMeans, kShowPenalty );

	
	// these are slightly faster - O(NLog2(N))
	iterations = iterations * 8;
	
	test_quicksort(dMpb, dMpe, dpb, dpe, dZero, "quicksort double pointer verify2");
	test_quicksort(vec_dataMaster.begin(), vec_dataMaster.end(), vec_data.begin(), vec_data.end(), dZero, "quicksort double vector iterator");
	test_quicksort(rdMpb, rdMpe, rdpb, rdpe, dZero, "quicksort double pointer reverse");
	test_quicksort(vec_dataMaster.rbegin(), vec_dataMaster.rend(), vec_data.rbegin(), vec_data.rend(), dZero, "quicksort double vector reverse_iterator");
	test_quicksort(rtvdMpb, rtvdMpe, rtvdpb, rtvdpe, dZero, "quicksort double vector iterator reverse");
	test_quicksort(rrdMpb, rrdMpe, rrdpb, rrdpe, dZero, "quicksort double pointer reverse reverse");
	test_quicksort(rtrvdMpb, rtrvdMpe, rtrvdpb, rtrvdpe, dZero, "quicksort double vector reverse_iterator reverse");
	test_quicksort(rtrtvdMpb, rtrtvdMpe, rtrtvdpb, rtrtvdpe, dZero, "quicksort double vector iterator reverse reverse");

	summarize("Vector Quicksort", SIZE, iterations, kShowGMeans, kShowPenalty );

	
	test_heap_sort(dMpb, dMpe, dpb, dpe, dZero, "heap_sort double pointer verify2");
	test_heap_sort(vec_dataMaster.begin(), vec_dataMaster.end(), vec_data.begin(), vec_data.end(), dZero, "heap_sort double vector iterator");
	test_heap_sort(rdMpb, rdMpe, rdpb, rdpe, dZero, "heap_sort double pointer reverse");
	test_heap_sort(vec_dataMaster.rbegin(), vec_dataMaster.rend(), vec_data.rbegin(), vec_data.rend(), dZero, "heap_sort double vector reverse_iterator");
	test_heap_sort(rtvdMpb, rtvdMpe, rtvdpb, rtvdpe, dZero, "heap_sort double vector iterator reverse");
	test_heap_sort(rrdMpb, rrdMpe, rrdpb, rrdpe, dZero, "heap_sort double pointer reverse reverse");
	test_heap_sort(rtrvdMpb, rtrvdMpe, rtrvdpb, rtrvdpe, dZero, "heap_sort double vector reverse_iterator reverse");
	test_heap_sort(rtrtvdMpb, rtrtvdMpe, rtrtvdpb, rtrtvdpe, dZero, "heap_sort double vector iterator reverse reverse");

	summarize("Vector Heap Sort", SIZE, iterations, kShowGMeans, kShowPenalty );



	return 0;
}