/* Demonstration of recursion, dynamic programming and memoization on
   Fibonacci numbers
   
   Cliff Stein 10/16/05
*/

/* Simple recursive program */

long  fib_recursive(long  n)
{
  if ((n==1) || (n== 2))
    return 1;
  else if (n==0)
    return 0;
  else
    return (fib_recursive(n-1) + fib_recursive(n-2));
}

/* Dynamic programming solution.  Fill in the table in order */

long fib_dp(long n)
{
  long F[n+1];
  int i;
  
  
  F[0] = 0;
  F[1] = F[2] = 1;
  
  for (i=2;i<=n;i++)
    F[i] = F[i-1] + F[i-2];

  return F[n];
}

/* Memoized code.  Start with recursive solution and store computed values.  
   Initialize array with -1's to denote that the value has not yet been 
   computed.  We use a non-recursive function for initialization, and pass 
   a pointer to the array F.
*/

long fib_memoize(long n)
{
  long F[n+1];
  long fib_lookup(long, long *);
  
  int i;
  
  F[0] = 0;
  F[1] = F[2] = 1;
  
  for (i=2;i<=n;i++)  /* -1 means not yet computed */
    F[i] = -1;
  
  return  fib_lookup(n,F);
  
    
}

long fib_lookup(long n,long F[])
{
  long x,y;
  
  if ((n==1) || (n== 2)) 
    return 1;
  else if (n==0)
    return 0;
  else{
    if (F[n-1] == -1) {
      x = fib_lookup(n-1,F);  /* compute F[n-1] for the first time */
      F[n-1] = x;             /* save the value */
      }
    else
      x = F[n-1];             /* do a lookup for the already computed value */

    if (F[n-2] == -1) {
      y = fib_lookup(n-2,F);  /* compute F[n-2] for the first time */
      F[n-2] = y;             /* save the value */
    }
    else
      y = F[n-2];             /* do a lookup for the already computed value */
    
    return x+y;
  }
}
  
/* Main demonstration program */

main()
{   

long   n;
  
  printf("enter n - We will compute the nth fibonacci number. \n");
  scanf("%d", &n);

  
  printf("\n \nHit a key to begin the dynamic programming computation");
  getchar();getchar();
  printf("\n\n %d th fibonacci number is %ld\n",n,fib_dp(n));

  printf("\n \nHit a key to begin the memoized computation");
  getchar();
  printf("\n\n %d th fibonacci number is %ld\n",n,fib_memoize(n));

  printf("\n \nHit a key to begin the recursive computation");
  getchar();
    printf("\n\n %d th fibonacci number is %ld\n",n,fib_recursive(n));
  

  
}
 
  
  



    

