/*
 * Program to compare performance of various ways of computing
 * an element of the Fibonacci sequence:  iterative, recursive,
 * and recursive with memoization.
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h> /* for get_time */

double get_time();

long long fibonacci_iterate(int n);
long long fibonacci_recurse(int n, long long *count);
long long fibonacci_recurse_m(int n, long long *count);

int main(void) {

	int n;
	printf("which index?\n");
	if ((scanf("%d", &n) != 1) || (n < 0)) {
		printf("input must be a non-negative integer\n");
		return 1;
	}

	double start_time, end_time;
	long long result;
	long long count;

	printf("computing fibonacci(%d)\n", n);

	start_time = get_time();
	result = fibonacci_iterate(n); 
	end_time = get_time();
	puts("\niterative version:");
	printf("result %lld (time %.8f seconds)\n", 
			result, end_time - start_time);

	start_time = get_time();
	count = 0;
	result = fibonacci_recurse(n, &count); 
	end_time = get_time();
	puts("\nrecursive version:");
	printf("result %lld (time %.8f seconds, count %lld)\n", 
			result, end_time - start_time, count);

	start_time = get_time();
	count = 0;
	result = fibonacci_recurse_m(n, &count);
	end_time = get_time();
	puts("\nmemoized recursive version:");
	printf("result %lld (time %.8f seconds, count %lld)\n",
			result, end_time - start_time, count);

	return 0;
}

/* 
 * compute the n-th fibonacci number using iteration 
 */
long long fibonacci_iterate(int n) {
	/* 
	 * FIXME add code here 
	 *
	 * okay to use code from sample program -- that is what I recommend --
	 * but remember you are computing a "long long" not a "long".
	 */
	return 0; /* to make the compiler happy for now */
}

/* 
 * compute the n-th fibonacci number using recursion (naive version)
 */
long long fibonacci_recurse(int n, long long *count) {
	(*count)+=1;
	/* 
	 * FIXME add code here 
	 *
	 * okay to use code from sample program -- that is what I recommend --
	 * but remember you are computing a "long long" not a "long".
	 */
	return 0; /* to make the compiler happy for now */
}

/* 
 * compute the n-th fibonacci number using recursion (version using 
 * memoization)
 */
long long fibonacci_recurse_m(int n, long long *count) {
	(*count)+=1;
	/* 
	 * FIXME add code here 
	 *
	 * this is the only function you can't just copy-and-paste.
	 * again remember that you are computing a "long long" so saved
	 * values should be of that type.
	 */
	return 0; /* to make the compiler happy for now */
}

/*
 * get time in seconds since "epoch" 
 * uses Linux library function gettimeofday, so probably not portable
 */
double get_time() {
	struct timeval tv;
	if (gettimeofday(&tv, NULL) == 0) 
		return (double) tv.tv_sec + ((double) tv.tv_usec / (double) 1000000);
	else
		return 0.0;
}