// L-22 MCS 360 Wed 13 Oct 2010 : fibonacci.cpp

/* The recursive computation of the Fibonacci numbers leads to an
   excessive number of function calls with the same argument.
   With memoization -- storing the values of the calls in a vector --
   we can compute as many Fibonacci numbers as the 64-bit precision 
   of the long long int type allows. */

#include <iostream>
#include <vector>
using namespace std;

long long int f ( int n );
// returns the nth Fibonacci number

long long int mf ( int n );
// returns the nth Fibonacci number 
// with memoization, initialize with f(-1)
// f(-2) writes the vector of function calls

int main()
{
   cout << "give n : ";
   int n; cin >> n;

   cout << "skip recursion ? (y/n) ";
   char answer; cin >> answer;

   if(answer != 'y')
   {
      long long int fn = f(n);
      cout << "f(" << n << ") = " 
           << fn << endl;
   }
   long long int r = mf(-1);
   r = mf(n);
   cout << "f(" << n << ") = " 
        << r << endl;
   cout << "computed values : "; mf(-2);

   return 0;
}

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

long long int mf ( int n )
{
   static vector<long long int> v;

   if(n == -1)
   {
      v.reserve(100);
      for(int i=0; i<100; i++) v[i] = -1;
      return -1;
   }
   else if (n == -2)
   {
      for(int i=0; i<100; i++)
         if(v[i]!=-1) cout << " " << v[i];
      cout << endl;
      return -2;
   }
   else
   {
      if(v[n] != -1)
         return v[n];
      else
         if(n==0)
            v[0] = 0;
         else if(n==1)
            v[1] = 1;
         else
            v[n] = mf(n-1) + mf(n-2);
         return v[n];
   }
}

