package com.jwetherell.algorithms.sequence; /** * In mathematics, the Fibonacci numbers are the numbers in the following integer sequence, called the Fibonacci sequence, and characterized by the fact that every number after the first two is the * sum of the two preceding ones: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... *

* * https://en.wikipedia.org/wiki/Fibonacci_number *
* @author Justin Wetherell */ public class FibonacciSequence { private static final double INVERSE_SQUARE_ROOT_OF_5 = 1 / Math.sqrt(5); // Inverse of the square root of 5 private static final double PHI = (1 + Math.sqrt(5)) / 2; // Golden ratio private FibonacciSequence() {} public static final long fibonacciSequenceUsingLoop(int n) { final long[] array = new long[n + 1]; int counter = 0; while (counter <= n) { long r = 0; if (counter > 1) { r = array[counter - 1] + array[counter - 2]; } else if (counter == 1) { r = 1; } // If r goes below zero then we have run out of bits in the long if (r < 0) throw new IllegalArgumentException("Run out of bits in long, n="+n); array[counter] = r; counter++; } return array[n]; } /** * Recursion with memoization */ public static final long fibonacciSequenceUsingRecursion(int n) { // Using the array to store values already computed final long[] array = new long[n + 1]; return fibonacciSequenceUsingRecursion(array,n); } private static final long fibonacciSequenceUsingRecursion(long[] array, int n) { if (n == 0 || n == 1) return n; // If array already has a value then it has previously been computed if (array[n] != 0) return array[n]; final String exception = "Run out of bits in long, n="+n; final long r1 = fibonacciSequenceUsingRecursion(array, (n - 1)); array[n-1] = r1; // memoization // If r1 goes below zero then we have run out of bits in the long if (r1 < 0) throw new IllegalArgumentException(exception); final long r2 = fibonacciSequenceUsingRecursion(array, (n - 2)); array[n-2] = r2; // memoization // If r2 goes below zero then we have run out of bits in the long if (r2 < 0) throw new IllegalArgumentException(exception); final long r = r1 + r2; // If r goes below zero then we have run out of bits in the long if (r < 0) throw new IllegalArgumentException("Run out of bits in long, n="+n); array[n] = r; // memoization return r; } public static final long fibonacciSequenceUsingMatrixMultiplication(int n) { // m = [ 1 , 1 ] // [ 1 , 0 ] final long[][] matrix = new long[2][2]; matrix[0][0] = 1; matrix[0][1] = 1; matrix[1][0] = 1; matrix[1][1] = 0; long[][] temp = new long[2][2]; temp[0][0] = 1; temp[0][1] = 1; temp[1][0] = 1; temp[1][1] = 0; int counter = n; while (counter > 0) { temp = multiplyMatrices(matrix, temp); // Subtract an additional 1 the first time in the loop because the // first multiplication is actually n -= 2 since it multiplying two matrices counter -= (counter == n) ? 2 : 1; } final long r = temp[0][1]; // If r goes below zero then we have run out of bits in the long if (r < 0) throw new IllegalArgumentException("Run out of bits in long, n="+n); return r; } private static final long[][] multiplyMatrices(long[][] A, long[][] B) { final long a = A[0][0]; final long b = A[0][1]; final long c = A[1][0]; final long d = A[1][1]; final long e = B[0][0]; final long f = B[0][1]; final long g = B[1][0]; final long h = B[1][1]; B[0][0] = a * e + b * g; B[0][1] = a * f + b * h; B[1][0] = c * e + d * g; B[1][1] = c * f + d * h; return B; } public static final long fibonacciSequenceUsingBinetsFormula(int n) { final long r = (long) Math.floor(Math.pow(PHI, n) * INVERSE_SQUARE_ROOT_OF_5 + 0.5); // If r hits max value then we have run out of bits in the long if (r == Long.MAX_VALUE) throw new IllegalArgumentException("Run out of bits in long, n="+n); return r; } }