#include<stdlib.h>
#include<stdio.h>

#define HAILSTONEMAX 100000 /* This many Hailstone series should be tested */
#define NUMBERSOFMAX 20

int hailstone(int value)
{
	int i=0;
	/* Perform a do-while loop, switch-caseing the next value until 'value'==1 */
	do {
		switch(value % 2) {
			case 0:
				value /= 2;
				break;
			default:
				value = 3 * value + 1;
		}
		i++;
 
	} while(value > 1);

	/* We're done */
	return i;
}


int hailstone_cmp(void *pa, void *pb)
{
    int *a = (int*)pa;
    int *b = (int*)pb;
    if (a == NULL || b == NULL)
		return 0; /* we don't like NULL pointers */
	if(*a==*b) return 0;
	if(*a<*b) return 1;
	return -1;
}

int main(void)
{
//	static int NUMBERSOFMAX=20;
	int i;
	int value=0;
	int ar[HAILSTONEMAX];		/* Holds the frequency of a certain "series lenght" */
	int count[NUMBERSOFMAX];	/* Holds the NUMBERSOFMAX max frequencies */
	int hailstonestartvalue[NUMBERSOFMAX]; /* the staring value for series that gave one of the max frequencies */
	int frequency;
	
	printf("Hailstone series\n");
	printf("****************\n\n");

	/* create frequency table */
	for(i=1; i<HAILSTONEMAX; i++) {
		ar[hailstone(i)]++;				/* Count up the frequency */
	}
	
	/* Fill 'count' with 0 */
	for(i=0;i<NUMBERSOFMAX; i++) {
//		printf("Zeroing %i\n");
		count[i]=0;
	}
	
	for(i=1; i<HAILSTONEMAX; i++) {
	/*
	 * Get frequencey value
	 * compare to first element of 'count'
	 * if lower continue
	 * if bigger insert in 'count', first element, then sort 'count'
	 */
		frequency=ar[i];
		if(frequency>=count[0])
		{
			count[0]=frequency;
			qsort(count, HAILSTONEMAX, sizeof(int), hailstone_cmp);
		}
	}
		
		/*
		 * prototype from man page
	   void qsort(void *base, size_t nmemb, size_t size,
                  int(*compar)(const void *, const void *));
				  */
 
	/* Print out the NUMBERSOFMAX longest Hailstone series that was detected */
		for(i = 1 ; i < NUMBERSOFMAX ; i++) {
			printf("%i: %x\n", hailstonestartvalue[i], count[i]);
	}

	return 0;
}