Skip to content

Instantly share code, notes, and snippets.

@CharmedSatyr
Last active August 1, 2018 00:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CharmedSatyr/08ef82f50c400d98c6764578435717ba to your computer and use it in GitHub Desktop.
Save CharmedSatyr/08ef82f50c400d98c6764578435717ba to your computer and use it in GitHub Desktop.
Fibonacci Number Finder algorithms, one recursive and one iterative, implemented in JavaScript
// Fibonacci Number
// Objective: Find the n-Fibonacci number,
// the nth term of the Fibonacci Sequence,
// often denoted by F(n)
// For example, given the Fibonacci Sequence:
// 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377...
// F(8) = 21
// F(20) = 6765
// METHOD 1: Recursive Loop
const fR = n => {
// Error conditions
if (typeof n !== 'number') {
return 'Input must be a number';
} else if (n < 0) {
return 'Input must be greater than or equal to zero';
} else if (n % 1 !== 0) {
return 'Input must be an integer';
}
// Base cases (stop recursion)
if (n === 0) {
// F(0) = 0
return 0;
} else if (n === 1) {
// F(1) = 1
return 1;
}
// Recursive case
if (n > 1) {
// The nth term is the sum of the two previous numbers in the sequence
return fR(n - 1) + fR(n - 2);
}
};
console.log('Recursive:', fR('abc')); // Message
console.log('Recursive:', fR(-100)); // Message
console.log('Recursive:', fR(1.1)); // Message
console.log('Recursive:', fR(0)); // 0
console.log('Recursive:', fR(8)); // 21
console.log('Recursive:', fR(20)); // 6765
// The below takes a long time to return a value
console.log('Recursive:', fR(50)); // ???
// This is inefficient because it breaks down each problem
// into the sum of 1s and 0s.
// E.g.,
// fR(0) = 0
// fR(1) = 1
// fR(2) = fR(2-1) + fR(2-2)
// = fR(1) + fR(0)
// = 1 + 0
// = 1
// fR(3) = fR(3-1) + fR(3-2)
// = fR(2) + fR(1)
// = fR(2-1) + fR(2-2) + 1
// = fR(1) + fR(0) + 1
// = 1 + 0 + 1
// = 2
// fR(4) = fR(4-1) + fR(4-2)
// = fR(3) + fR(2)
// = fR(3-1) + fR(3-2) + fR(2-1) + fR(2-2)
// = fR(2) + fR(1) + fR(1) + fR(0)
// = fR(2-1) + 1 + 1 + 0
// = fR(1) + 1 + 1 + 0
// = 1 + 1 + 1 + 0
// = 3
// When dealing with high values, this will eventually
// become cumbersome because the number of functions to complete
// keeps multiplying.
// METHOD 2: Iterative Loop
const fI = n => {
// Error conditions
if (typeof n !== 'number') {
return 'Input must be a number';
} else if (n < 0) {
return 'Input must be greater than or equal to zero';
} else if (n % 1 !== 0) {
return 'Input must be an integer';
}
// Initialize a and b to 1 and 0
let [a, b] = [0, 1];
// Counting back from n to 1
while (n-- > 0) {
// Basically create our own Fibonacci sequence,
// storing each successive set of values in the [a, b] array
// so that they don't have to be recalculated each time.
// (This is called memoization and looks pretty here in ES6.)
// In the meantime n is counting down from our target value,
// and the while loop will stop once b becomes F(n).
[a, b] = [b, a + b];
}
return a;
};
console.log('Iterative:', fI('abc')); // Message
console.log('Iterative:', fI(-100)); // Message
console.log('Iterative:', fI(1.1)); // Message
console.log('Iterative:', fI(0)); // 0
console.log('Iterative:', fI(8)); // 21
console.log('Iterative:', fI(20)); // 6765
// The below returns in less than a second!
console.log('Iterative:', fI(50)); // 12586269025
// This iterative solution involves a series of addition problems
// in the destructured array, and a countdown from n
// in the while condition. The total number of calculations
// will be fewer than in fR because there is no recursion,
// and each number does not have to be broken down into
// the sum of 1s and 0s. As a result, it is much faster!
// In ES5, a temp variable can be used instead of
// a destructured array.
// fI(0) = a = 0 // No loops
// fI(1)
// n = 1: [0,1] => [1, 1 + 0] = [1,1] // Loop 1
// n = 0: a = 1 // No loop
// = 1
// fI(2)
// n = 2: [0,1] => [1, 1 + 0] = [1,1] // Loop 1
// n = 1: [1,1] => [1, 1 + 1] = [1,2] // Loop 2
// n = 0: a = 1 // No loop
// = 1
// fI(3)
// n = 3: [0,1] => [0, 1 + 0] = [1,1] // Loop 1
// n = 2: [1,1] => [1, 1 + 1] = [1,2] // Loop 2
// n = 1: [1,2] => [2, 2 + 1] = [2,3] // Loop 3
// n = 0: a = 2 // No loop
// = 2
// fI(4)
// n = 4: [1,0] => [0, 1 + 0] = [1,1] // Loop 1
// n = 3: [1,1] => [1, 1 + 1] = [1,2] // Loop 2
// n = 2: [1,2] => [2, 2 + 1] = [2,3] // Loop 3
// n = 1: [2,3] => [3, 3 + 2] = [3,5] // Loop 4
// n = 0: a = 3 // No loop
// = 3
// We can get up to high values fairly quickly using this method
// because it uses the natural power of the Fibonacci Sequence.
// References:
// https://www.gregjs.com/javascript/2016/writing-a-fibonacci-implementation-in-javascript/
// https://stackoverflow.com/questions/1451170/in-the-fibonacci-sequence-is-fib0-0-or-1
// https://guide.freecodecamp.org/mathematics/fibonacci-number
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment