1. Computing Fibonacci numbers

Fibonacci numbers

We looked at the problem of computing the n-th number in the following sequence:

           1st 2nd 3rd 4th 5th 6th 7th 8th 9th  10th 11th 12th
           -1,  1,  0,  1,  2,  3,  5,  8,  13,  21,  34,  55,  ...

This is the famous Fibonacci sequence in which each number is the sum of the 
previous two. (Mathematicians write this as: fi = fi-1 + fi-2)

The first two numbers (1st and 2nd) cannot be computed by this rule, so they must
be given to us. Here we use -1 as 1st and 1 as 2nd. (Mathematicians write this as f1 = -1, f2 = 1)

Goal: Write a procedure fibonacci(n) that computes the n-th Fibonacci number, i.e.

fibonacci(6)    ===>    3
fibonacci(12)   ===>    55
As usual, we need to decide on:
* what "information" to keep track of, i.e. what variables/PostIts we need
* initial values for these variables/PostIts
* how many times to go through the loop/computation
* how to update the variables/PostIts on each cycle of the loop
It is clear that if we only keep track of one Fibonacci number we cannot produce the next one. The rules tells us that we need to know at least two numbers, so that we can generate the next one and move through the sequence. (In fact, keeping track of only two Fibonacci numbers is sufficient.) Of course, we also want to keep track of the index of the current Fibonacci number we have computed. The two numbers we will keep track of, called curFib and nextFib, start at the beginning of the sequence and move one step at a time to the right as shown here:
          -1  1, 0, 1, 2, 3, 5, 8, 13, 21, 34, ...     
           ^  ^
before:    |  |
           c  n
              ^  ^
after:        :  :
              c  n
From the sketch above we see that:
* we need at least two variables -- curFib (c), nextFib (n)
  (initial values of the variables are the first two Fibonacci numbers)

* the variables are updated as follows:
  - curFib gets the value of nextFib (c takes over n)
  - nextFib is the sum of nextFib and curFib (n moves to the new number)

   (the correct order of these computations is a bit tricky)
We also need some variable to keep track of the index of the last computed Fibonacci number, so that we know when to stop. We will associate an index, curIndex, to correspond with the value of curFib. Since in the beginning we have the value of the first Fib. number, curIndex starts at 1. Here is the final code. It uses two temporary variables to precompute the new values for curFib and nextFib:
int fibonacci(int n)
{
    int curFib = -1;   // value of first fib number
    int nextFib = 1;   // value of second fib number

    int curIndex = 1;  // index of curFib

    while (curIndex < n)
    {
        int newCur = nextFib;            // new value for curFib  (the current value of nextFib)
        int newNext = curFib + nextFib;  // new value for nextFib (the sum of the current values)

        curFib = newCur;      // change/update curFib  to its new value	    
        nextFib = newNext;    // change/update nextFib to its new value

        curIndex = curIndex + 1;
    }
    
    return curFib;
}
Alternate versions Here are two versions that use only one temporary variable:
int fibonacci(int n)
{
    int curFib = -1;
    int nextFib = 1;

    int curIndex = 1;

    while (index < n)
    {
        int oldCur = curFib;            // remember current value for curFib
        curFib = nextFib;               // curFib takes over nextFib (safe to update since we kept its old value)
        nextFib = oldCur + nextFib;     // use *old* value of curFib

        curIndex = curIndex + 1;
    }
    
    return curFib;
}
int fibonacci(int n)
{
    int curFib = -1;
    int nextFib = 1;

    int curIndex = 1;

    while (index < n)
    {
        int oldNext = nextFib;          // remember current value of nextFib
        nextFib = curFib + nextFib;     // update/change nextFib (safe to update since we kept its old value)
        curFib = oldNext;               // change curFib to where nextFib *was* before the update

        curIndex = curIndex + 1;
    }
    
    return curFib;
}
Incorrect Versions Here are two versions that show a typical first attempt at this problem. Both versions suffer from the same problem -- overwriting a variable whose value is needed in the next (later) step. To avoid this problem we need to create temporary variable(s) to store values that are needed in subsequent computations. In the versions below, that use no temporary variables, no matter how we order the operations the solution ends up being wrong.
int wrongFibonacci(int n)
{
    int curFib = -1;
    int nextFib = 1;

    int curIndex = 1;

    while (curIndex < n)
    {
        // WRONG ORDER -- lost the value of curFib
        curFib = nextFib;
        nextFib = curFib + nextFib;

        curIndex = curIndex + 1;
    }

    return curFib;
}
int wrongFibonacci(int n)
{
    int curFib = -1;
    int nextFib = 1;

    int curIndex = 1;

    while (curIndex < n)
    {
        // WRONG ORDER -- lost the value of nextFib
        nextFib = curFib + nextFib;
        curFib = nextFib;

        curIndex = curIndex + 1;
    }

    return curFib
}
Here is the final code for the Fibonacci numbers along with sample test cases:
public class MathApp
{
    int fibonacci(int n)
    {
        int curFib = -1;   // value of first fib number
        int nextFib = 1;   // value of second fib number

        int curIndex = 1;  // index of curFib

        while (curIndex < n)
        {
            int newCur = nextFib;            // new value for curFib  (the current value of nextFib)
            int newNext = curFib + nextFib;  // new value for nextFib (the sum of the current values)

            curFib = newCur;      // change/update curFib  to its new value
            nextFib = newNext;    // change/update nextFib to its new value

            curIndex = curIndex + 1;
        }
    
        return curFib;
    }

    public void run()
    {
                                                           // expecting to see in the console below:
        System.out.println( "fib(1): " + fibonacci(1) );   // fib(1): -1
        System.out.println( "fib(2): " + fibonacci(2) );   // fib(2): 1
        System.out.println( "fib(3): " + fibonacci(3) );   // fib(3): 0
        System.out.println( "fib(9): " + fibonacci(9) );   // fib(9): 13
        System.out.println( "fib(12): " + fibonacci(12) ); // fib(12): 55

       // Note: We definitely need to try to compute the 1st and 2nd Fibonacci numbers,
       //       since these are special, i.e. cannot be computed by the rule, so we need
       //       to see if our code is able to compute them correctly.
       //
       //       This is why we have the first two tests: ...fib(1)... and ...fib(2)...
    }
}