Last active
August 1, 2018 00:57
-
-
Save CharmedSatyr/08ef82f50c400d98c6764578435717ba to your computer and use it in GitHub Desktop.
Fibonacci Number Finder algorithms, one recursive and one iterative, implemented in JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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