Finding all Fibonacci numbers less than or equal to a number - javascript

I am trying to implement a function in JavaScript that returns an array of all the Fibonacci numbers up until a certain number (num). During my research I came across this answer: Calculate Fibonacci numbers up to at least n. I implemented their solution in JavaScript and Python, but found that their solution has a bug in it. The problem is that the last element is sometimes wrong. Here is the code I wrote based off of the solution I found in the answer linked above.
function findFibs(num) {
if (num < 2) {
return [1,1];
} else {
var fibs = findFibs(num - 1)
if ((fibs[fibs.length - 1]) < num ) {
fibs.push(fibs[fibs.length - 1] + fibs[fibs.length - 2])
}
return fibs;
}
}
console.log(sumFibs(20));
The expected output of this code is:[ 1, 1, 3, 5, 13 ] , but the actual output is [ 1, 1, 3, 5, 13, 21 ] . What is it that I'm missing?

functional
Recursion is a functional heritage and so using it with functional style yields the best results. This means avoiding things like mutations, variable reassignments, and other side effects. Consider a more functional approach -
Given a limit and two seeds, a and b -
if seed a is greater than the input limit, return the empty result
(inductive) a is less than or equal to the limit. recur on the sub-problem (limit, b, a + b) and append it to the singleton [a]
This encodes as a pure functional expression -
const fibs = (limit, a = 1, b = 1) =>
a > limit
? [] // #1
: [ a, ...fibs(limit, b, a + b) ] // #2
console.log(fibs(20))
// [ 1, 1, 2, 3, 5, 8, 13 ]
imperative
If I were to use imperative style for this program, I think I would reach for a generator -
function* fib (a, b)
{ yield a
yield *fib(b, a + b)
}
function* fibs (limit)
{ for (const n of fib(1, 1))
if (n < limit)
yield n
else
return
}
console.log(Array.from(fibs(20)))
// [ 1, 1, 2, 3, 5, 8, 13 ]
stack-safe
Seen above in fib, we can use recursion with imperative style but because it can overflow the stack, it would make more sense to use a loop in this situation -
function* fib (a, b)
{ let t
while (true) // stack-safe, but not recursive
{ yield a
t = a
a = b
b = t + a
}
}
function* fibs (limit)
{ for (const n of fib(1, 1))
if (n < limit)
yield n
else
return
}
console.log(Array.from(fibs(20)))
// [ 1, 1, 2, 3, 5, 8, 13 ]
BigInt
The Fibonacci sequence quickly produces large numbers that JavaScript will approximate using scientific notation. The 102nd term is 927372692193079200000 and the 103rd term is 1.5005205362068963e+21. This is due to the size constraints of JavaScript's numbers. Using the newer BigInt we can get around this easily -
function* fib (a, b)
{ let t
while (true)
{ yield a
t = a
a = b
b = t + a
}
}
function* fibs (limit)
{ for (const n of fib(1n, 1n)) // <- bigint
if (n < limit)
yield n
else
return
}
for (const n of fibs(1e70))
console.log(String(n)) // <- bigint to string
StackOverflow.com truncates output to show only the last 50 lines. Check your browser's console for the full output -
...
426547842461739379460149980002442288124894678853713953114433
690168906931029935139391829792095612517948949963798093315456
1116716749392769314599541809794537900642843628817512046429889
1806885656323799249738933639586633513160792578781310139745345
2923602405716568564338475449381171413803636207598822186175234
4730488062040367814077409088967804926964428786380132325920579
7654090467756936378415884538348976340768064993978954512095813
12384578529797304192493293627316781267732493780359086838016392
20038668997554240570909178165665757608500558774338041350112205
32423247527351544763402471792982538876233052554697128188128597
52461916524905785334311649958648296484733611329035169538240802
84885164052257330097714121751630835360966663883732297726369399
137347080577163115432025771710279131845700275212767467264610201
222232244629420445529739893461909967206666939096499764990979600
359579325206583560961765665172189099052367214309267232255589801
581811569836004006491505558634099066259034153405766997246569401
941390895042587567453271223806288165311401367715034229502159202
1523202464878591573944776782440387231570435521120801226748728603
2464593359921179141398048006246675396881836888835835456250887805
3987795824799770715342824788687062628452272409956636682999616408
6452389184720949856740872794933738025334109298792472139250504213
10440185009520720572083697583620800653786381708749108822250120621
16892574194241670428824570378554538679120491007541580961500624834
27332759203762391000908267962175339332906872716290689783750745455
44225333398004061429732838340729878012027363723832270745251370289
71558092601766452430641106302905217344934236440122960529002115744
115783425999770513860373944643635095356961600163955231274253486033
187341518601536966291015050946540312701895836604078191803255601777
303124944601307480151388995590175408058857436768033423077509087810
490466463202844446442404046536715720760753273372111614880764689587
793591407804151926593793042126891128819610710140145037958273777397
1284057871006996373036197088663606849580363983512256652839038466984
2077649278811148299629990130790497978399974693652401690797312244381
3361707149818144672666187219454104827980338677164658343636350711365
5439356428629292972296177350244602806380313370817060034433662955746
8801063578447437644962364569698707634360652047981718378070013667111
14240420007076730617258541919943310440740965418798778412503676622857
23041483585524168262220906489642018075101617466780496790573690289968
37281903592600898879479448409585328515842582885579275203077366912825
60323387178125067141700354899227346590944200352359771993651057202793
97605290770725966021179803308812675106786783237939047196728424115618
157928677948851033162880158208040021697730983590298819190379481318411
255533968719576999184059961516852696804517766828237866387107905434029
413462646668428032346940119724892718502248750418536685577487386752440
668996615388005031531000081241745415306766517246774551964595292186469
1082459262056433063877940200966638133809015267665311237542082678938909
1751455877444438095408940282208383549115781784912085789506677971125378
2833915139500871159286880483175021682924797052577397027048760650064287
4585371016945309254695820765383405232040578837489482816555438621189665
7419286156446180413982701248558426914965375890066879843604199271253952

You can set a condition before push the last item:
toPush < num ? fibs.push(toPush) : 0;
function findFibs(num) {
if (num < 2) {
return [1,1];
} else {
var fibs = findFibs(num - 1)
if ((fibs[fibs.length - 1]) < num) {
let toPush = fibs[fibs.length - 1] + fibs[fibs.length - 2];
toPush < num ? fibs.push(toPush) : 0;
}
return fibs;
}
}
console.log(findFibs(20));

The reason for the output 21 is due to the wrong condition ins if statement.
(fibs[fibs.length - 1]) < num
It means where the last entry was 13 which is less than 20.
so 13 adds up with 8 and stores as 21 in fibs array.
if you change the if statement to
if ((fibs[fibs.length - 1]+ fibs[fibs.length - 2]) < num )
Then you can expect the output you needed.
new code:
function findFibs(num) {
if (num < 2) {
return [1,1];
} else {
var fibs = findFibs(num - 1)
console.log(fibs)
if ((fibs[fibs.length - 1]+ fibs[fibs.length - 2]) < num ) {
fibs.push(fibs[fibs.length - 1] + fibs[fibs.length - 2])
}
return fibs;
}
}
console.log(findFibs(20));

Break down the code first, to understand what it is doing.
function findFibs(num) {
// checking if the given num is less than 2
if (num < 2) {
return [1, 1];
} else {
// decrement the given number by 1, which is 19, 18, 17....
// and reenter the loop with it
var fibs = findFibs(num - 1)
// grab the last and second last numbers
const a = fibs[fibs.length - 1];
const b = fibs[fibs.length - 2];
// check if the last number is less than num
// AND if the sum of a+b is less than num
// see? you should also check for (a + b) < num. this is what you missed.
if (a < num && (a + b) < num) {
// if so, add a new item to the array fibs
fibs.push(a + b)
}
return fibs;
}
}
console.log(findFibs(20));
check out the push method on W3Schools
By the way, your last line of code console.log(sumFibs(20)); should be console.log(findFibs(20));. Otherwise your code does not run properly. Happy coding!

Related

My test task for trainee. Javascript - quadratic equation and game theory

I've been thinking that I found solution, but tests fail (I have no access to tests).
The task:
We want to organize a chess tournament.
One day - one game.
And as entry point we have number of days - that we can afford.
Tournament rules:
We have number of teams: if number is even - we divide number of teams by 2 and that's the number of games - so they fight 1 vs 1 in pairs, who lost is excluded from the competition.
For example : 20 teams => 10 games => 10 teams left.
And if the even number of teams left - we make the same iteration: divide by 2 into pairs.
10 teams - 5 games - 5 teams left.
And now we have Odd number!
If we have odd number from start or get it in process - number of games is counted by another rule:
everyone needs to play with everyone. So the formula is = n * (n-1) / 2.
For example 5 teams = 10 games.
Or any odd number (to sum it all - if we have Odd number we always ignore first rule with pairs).
So:
We have number of days and need to find all possible team numbers for this days, it can be more than one value, for example : 3 days, number of teams that is correct is 3 and 4;
Entry point 3, function logs 3 and 4;
If that's impossible to find teams - return -1;
1 ≤ 𝑁 ≤ 1000000
Here is my solution - It ouputs correct values, but tests fail
Can someone help to find what I did wrong?
(Sorry for code mess, I had different thoughts every time)
function solve(input) {
let quadraticEquation = (number) => {
let a = 1;
let b = -1;
let c = -number*2
if(a == 0)
return 'false';
let res = {};
let D = b * b - 4 * a * c;
let tmp = [];
if(D < 0)
return 'false';
res['discriminant'] = D;
if(D == 0)
res["quadratic roots"] = (-b + Math.sqrt(D)) / (2 * a);
else if(D > 0){
tmp.push((-b + Math.sqrt(D)) / (2 * a));
tmp.push((-b - Math.sqrt(D)) / (2 * a));
res["quadratic roots"] = tmp;
}
return tmp;
}
let start = input;
let xValues = quadraticEquation(start).map(item => Math.abs(item)).filter(item => item % 2 !== 0);
let arrayToUse = []
for(i = 0; i <= xValues[xValues.length-1]; i++) {
if( i === 1) {
continue;
}
if (!(i%2)) {
continue
}
arrayToUse.push(i);
}
const answer = [];
arrayToUse.forEach(item => {
let startValue = item;
let fightsNumber = item * (item - 1) / 2;
let loop = 0;
if (fightsNumber === start) {
answer.push([startValue, loop])
} else {
do {
loop++;
fightsNumber += startValue;
if (fightsNumber === start) {
answer.push([item, loop] )
}
startValue *= 2;
} while (fightsNumber < start)
}
})
function getTeams (answer) {
const finalResult = [];
answer.forEach(item => {
if(item[1] === 0) {
finalResult.push(item[0]);
} else {
let initialValue = item[0];
for(i=0; i < item[1]; i++) {
initialValue += item[0];
item[0] *= 2;
}
finalResult.push(initialValue);
}
})
let initialValue = 2;
let fightCounter = 0;
for (i = 0; i <= start; i++) {
fightCounter += initialValue / 2
if (fightCounter === start) {
finalResult.push(initialValue);
}
initialValue *= 2;
}
return finalResult;
}
let finalString = ''
const arrayToLog = getTeams(answer).sort((a,b) => a - b);
if(arrayToLog.length !== 0) {
arrayToLog.forEach(item => {
finalString += item + '\n';
})
} else {
finalString += -1;
}
return finalString;
}
console.log(solve(325))
console.log(solve(3))
console.log(solve(15))
console.log(solve(21))
console.log(solve(10))
console.log(solve(1))
console.log(solve(5))
console.log(solve(9))
Note: for those who didn't see it, this is a followup to the earlier question Backward recurssion.
That's a lot of code for a fairly simple problem. I don't have the inclination or the time right now to go through it carefully.
So here is how I might solve this problem, using brute force to look for all the resulting number of days for any number of players up to days + 1, and then filtering out what we want from that list:
const range = (lo, hi) =>
[... Array (hi - lo + 1)] .map ((_, i) => i + lo)
const qwe = (n) =>
n % 2 == 1
? n * (n - 1) / 2
: n / 2 + qwe (n / 2)
const solve = (days) => {
const daysByPlayers = range (1, days + 1) .map (qwe)
const res = daysByPlayers .reduce ((a, d, i) => d == days ? [...a, i + 1] : a, [])
return res .length == 0 ? [-1] : res
}
const tests = [325, 3, 15, 21, 10, 1, 5, 9]
tests .forEach (n => console .log (`${n}: ${JSON.stringify(solve(n))}`))
.as-console-wrapper {max-height: 100% !important; top: 0}
This matches your output as far as I can tell. But I don't know what tests you say are failing, so perhaps there's something wrong with this as well.
There is extra complexity in here because of your desire for a -1 output in the missing cases. If an empty array would serve, then this is cleaner:
const solve = (days) =>
rng (1, days + 1) .map (qwe)
.reduce ((a, d, i) => d == days ? [...a, i + 1] : a, [])
And there are many variants. This one returns the maximum number of players that can be accommodated in some number of days up to the given value:
const solve = (days) => {
const daysByPlayers = rng (1, days + 1) .map (qwe)
const max = Math.max (... daysByPlayers .filter (d => d <= days))
return days - daysByPlayers .reverse () .indexOf (max) + 1
}
And this one gives you all the possible number of players available to achieve that maximum:
const solve = (days) => {
const daysByPlayers = rng (1, days + 1) .map (qwe)
const max = Math.max (... daysByPlayers .filter (d => d <= days))
return daysByPlayers .reduce ((a, d, i) => d == max ? [...a, i + 1] : a, [])
}
(For instance, solve (20) would return [10, 16], which are the possible number of players to handle in exactly 15 days, the largest value found no larger than 20.)
And finally, we could list all the numbers of players we could accommodate in up to a certain number of days:
const solve = (days) => {
const daysByPlayers = rng (1, days + 1) .map (qwe)
const max = Math.max (... daysByPlayers .filter (d => d <= days))
return daysByPlayers .reduce ((a, d, i) => d <= max ? [...a, i + 1] : a, [])
}
For instance, solve (20) would return [1, 2, 3, 4, 5, 6, 8, 10, 12, 16], which are the only numbers of players that could be handled in no more than 20 days.
When I brought up the quadratic formula in the earlier question it was just to note that in certain instances, we can find an exact solution, solving for d in n * (n - 1) / 2) = d. That meant that if 8 * d + 1 is a perfect square, then we can choose n to be (1 + sqrt (8 * d + 1)) / 2 to find one solution. But that's not of any real help in the general case.

Javascript's equivalent of R's findInterval() or Python's bisect.bisect_left

I can't find how to determine to which interval an element belongs based on an Array for JavaScript. I want the behavior of bisect.bisect_left from Python. Here is some sample code:
import bisect
a = [10,20,30,40]
print(bisect.bisect_left(a,0)) #0 because 0 <= 10
print(bisect.bisect_left(a,10)) #0 because 10 <= 10
print(bisect.bisect_left(a,15)) #1 because 10 < 15 < 20
print(bisect.bisect_left(a,25)) #2 ...
print(bisect.bisect_left(a,35)) #3 ...
print(bisect.bisect_left(a,45)) #4
I know this would be easy to implement, but why re-invent the wheel?
In case anyone else lands here, here's an implementation of bisect_left that actually runs in O(log N), and should work regardless of the interval between list elements. NB that is does not sort the input list, and, as-is, will likely blow the stack if you pass it an unsorted list. It's also only set up to work with numbers, but it should be easy enough to adapt it to accept a comparison function. Take this as a starting point, not necessarily your destination. Improvements are certainly welcome!
Run it in a REPL
function bisect(sortedList, el){
if(!sortedList.length) return 0;
if(sortedList.length == 1) {
return el > sortedList[0] ? 1 : 0;
}
let lbound = 0;
let rbound = sortedList.length - 1;
return bisect(lbound, rbound);
// note that this function depends on closure over lbound and rbound
// to work correctly
function bisect(lb, rb){
if(rb - lb == 1){
if(sortedList[lb] < el && sortedList[rb] >= el){
return lb + 1;
}
if(sortedList[lb] == el){
return lb;
}
}
if(sortedList[lb] > el){
return 0;
}
if(sortedList[rb] < el){
return sortedList.length
}
let midPoint = lb + (Math.floor((rb - lb) / 2));
let midValue = sortedList[midPoint];
if(el <= midValue){
rbound = midPoint
}
else if(el > midValue){
lbound = midPoint
}
return bisect(lbound, rbound);
}
}
console.log(bisect([1,2,4,5,6], 3)) // => 2
console.log(bisect([1,2,4,5,6], 7)) // => 5
console.log(bisect([0,1,1,1,1,2], 1)) // => 1
console.log(bisect([0,1], 0)) // => 0
console.log(bisect([1,1,1,1,1], 1)) // => 0
console.log(bisect([1], 2)); // => 1
console.log(bisect([1], 1)); // => 0
Speaking of re-inventing the wheel, I'd like to join the conversation:
function bisectLeft(arr, value, lo=0, hi=arr.length) {
while (lo < hi) {
const mid = (lo + hi) >> 1;
if (arr[mid] < value) {
lo = mid + 1;
} else {
hi = mid;
}
}
return lo;
}
I believe that is the schoolbook implementation of bisection. Actually, you'll find something pretty much the same inside the d3-array package mentioned before.
using the D3-array npm.
const d3 = require('d3-array');
var a = [10,20,30,40];
console.log(d3.bisectLeft(a,0));
console.log(d3.bisectLeft(a,10));
console.log(d3.bisectLeft(a,15));
console.log(d3.bisectLeft(a,25));
console.log(d3.bisectLeft(a,35));
console.log(d3.bisectLeft(a,45));
output:
0
0
1
2
3
4
A faster way than the previously accepted answer that works for same size intervals is:
var array = [5, 20, 35, 50]
//Intervals:
// <5: 0
// [5-20): 1
// [20-35): 2
// [35-50): 3
// >=50: 4
var getPosition = function(array, x) {
if (array.length == 0) return;
if (array.length == 1) return (x < array[0]) ? 0 : 1;
return Math.floor((x - array[0]) / (array[1] - array[0])) + 1
}
console.log(getPosition(array, 2)); //0
console.log(getPosition(array, 5)); //1
console.log(getPosition(array, 15));//1
console.log(getPosition(array, 20));//2
console.log(getPosition(array, 48));//3
console.log(getPosition(array, 50));//4
console.log(getPosition(array, 53));//4
console.log("WHEN SIZE: 1")
array = [5];
//Intervals:
// <5: 0
// >=5: 1
console.log(getPosition(array, 3));
console.log(getPosition(array, 5));
console.log(getPosition(array, 6));
There are no built-in bisection functions in JavaScript, so you will have to roll your own. Here is my personal reinvention of the wheel:
var array = [10, 20, 30, 40]
function bisectLeft (array, x) {
for (var i = 0; i < array.length; i++) {
if (array[i] >= x) return i
}
return array.length
}
console.log(bisectLeft(array, 5))
console.log(bisectLeft(array, 15))
console.log(bisectLeft(array, 25))
console.log(bisectLeft(array, 35))
console.log(bisectLeft(array, 45))
function bisectRight (array, x) {
for (var i = 0; i < array.length; i++) {
if (array[i] > x) return i
}
return array.length
}

Write a JS function to find the first prime pair with a given step value

** Here is the question from Codewars.
The prime numbers are not regularly spaced. For example from 2 to 3 the step is 1. From 3 to 5 the step is 2. From 7 to 11 it is 4. Between 2 and 50 we have the following pairs of 2-steps primes:
3, 5 - 5, 7, - 11, 13, - 17, 19, - 29, 31, - 41, 43
We will write a function step with parameters:
g (integer >= 2) which indicates the step we are looking for,
m (integer >= 2) which gives the start of the search (m inclusive),
n (integer >= m) which gives the end of the search (n inclusive)
In the example above step(2, 2, 50) will return [3, 5] which is the first pair between 2 and 50 with a 2-steps.
So this function should return the first pair of the two prime numbers spaced with a step of g between the limits m, n if these g-steps prime numbers exist otherwise nil or null or None or Nothing (depending on the language).
Examples:
step(2, 5, 7) --> [5, 7] or (5, 7) or {5, 7}
step(2, 5, 5) --> nil or null
step(4, 130, 200) --> [163, 167] or (163, 167) or {163, 167}
Here is my solution- it is taking too long to pass the tests- how can I make it more efficient?
function step(g, m, n) {
var arr = [];
function isPrime(num){
for (var k=2; k<num; k++){
if(num%k ===0){
return false;
}
}return true;
}
for (var i= m; i < n; i++){
if(isPrime(i)=== true){
arr.push(i);
}
}
var endArr=[];
for(var l=0;l<arr.length;l++)
for(var p=1;p<arr.length;p++){
if(arr[l]-arr[l-p]=== g){
endArr.push(arr[l])
endArr.push(arr[l]-g)
}
}
return endArr.slice(0,2).sort(function(a,b){
return a-b;
})
}
Thanks!
There are several points of interest here.
First, your implementation of isPrime is inefficient. The fastest way would be using the precached set (it's easy to prepare one), but even without it you should only check a candidate by dividing it by primes, dropping out when the next prime divisor becomes greater than sqrt(cand).
For example, if you already know that 2, 3, 5, and 7 are primes, you can detect that 11 is a prime by dividing it only by 3 (as 5 > Math.sqrt(11)) Oh, and did I mention that you'd never check even numbers greater than 2?
Second, your implementation attempts to find all the primes in the given range, and after that tries to find all the primes that satisfy the "difference condition". But remember, your task actually is finding the first pair of the two prime numbers with the given step.
With that in mind, why don't you just check a number (n), and if it's a prime, attempt to check n + g's primeness? You can cache the result of that check, so that you skip it afterwards.
Here's one possible approach:
function findPrimesByStep(g, m, n) {
let primes = new Set([2]);
function isPrimeNumber(candidate) {
if (primes.has(candidate)) {
return true;
}
let lim = Math.sqrt(candidate);
for (let prime of primes) {
if (prime > lim) {
break;
}
if (candidate % prime === 0) {
return false;
}
}
primes.add(candidate);
return true;
}
n = n - g;
for (let i = 3; i <= n; i += 2) {
let isPrime = isPrimeNumber(i);
if (isPrime && i >= m && isPrimeNumber(i + g)) {
return [i, i + g];
}
}
return null;
}
This is both incomplete and unoptimized (it doesn't check against trivial cases, it skips 2, one doesn't need primes greater than sqrt(n)), but shows how it can be done.

How can I recursively generate an Array of the Fibonacci sequence?

I've seen several posts on generating a given fibonacci sequence, such as this one. However, I can't figure out how to generate the sequence (return an array) of fibonnaci numbers for a given n using recursion. What I have clearly doesn't work, but I really can't figure out how to do it otherwise.
var fibArray = function(n) {
var f = [];
n < 2 ? f.push(n) : f.push(fibArray(n-1) + fibArray(n-2));
return f;
};
A slightly modified version from the previous answer:
function fib(n) {
if (n == 0) return [0]
if (n == 1) return [0, 1]
const arr = fib(n - 1)
return [...arr, arr[n-1] + arr[n-2]]
}
console.log(fib(15))
Notice that you start each function call with an empty array and then only add 1 member to it. That won't work.
You have to add the new element to the array that was returned from the previous fib(n - 1) step. Like so:
function fib (n) {
if (n < 2) {
return [1];
}
if (n < 3) {
return [1, 1];
}
var a = fib(n - 1);
a.push(a[n - 2] + a[n - 3]);
return a;
};
The nth number appears on the position n - 1 on the array. That justifies the n - 2 = n - 1 - 1 and n - 3 = n - 2 - 1.
This is an option without spread operator and with an option to start the sequence when you want:
function fibonacciRecursion(amountNumbers = 4, sequence = [0, 1]) {
if (amountNumbers > 0) {
sequence.push(sequence[sequence.length - 1] + sequence[sequence.length - 2]);
return fibonacciRecursion(amountNumbers - 1, sequence);
}
return sequence
}
console.log(fibonacciRecursion(10, [3,5]))

Generating Fibonacci Sequence

var x = 0;
var y = 1;
var z;
fib[0] = 0;
fib[1] = 1;
for (i = 2; i <= 10; i++) {
alert(x + y);
fib[i] = x + y;
x = y;
z = y;
}
I'm trying to get to generate a simple Fibonacci Sequence but there no output.
Can anybody let me know what's wrong?
You have never declared fib to be an array. Use var fib = []; to solve this.
Also, you're never modifying the y variable, neither using it.
The code below makes more sense, plus, it doesn't create unused variables:
var i;
var fib = [0, 1]; // Initialize array!
for (i = 2; i <= 10; i++) {
// Next fibonacci number = previous + one before previous
// Translated to JavaScript:
fib[i] = fib[i - 2] + fib[i - 1];
console.log(fib[i]);
}
According to the Interview Cake question, the sequence goes 0,1,1,2,3,5,8,13,21. If this is the case, this solution works and is recursive without the use of arrays.
function fibonacci(n) {
return n < 1 ? 0
: n <= 2 ? 1
: fibonacci(n - 1) + fibonacci(n - 2)
}
console.log(fibonacci(4))
Think of it like this.
fibonacci(4) .--------> 2 + 1 = 3
| / |
'--> fibonacci(3) + fibonacci(2)
| ^
| '----------- 2 = 1 + 1 <----------.
1st step -> | ^ |
| | |
'----> fibonacci(2) -' + fibonacci(1)-'
Take note, this solution is not very efficient though.
Yet another answer would be to use es6 generator functions.
function* fib() {
var current = a = b = 1;
yield 1;
while (true) {
current = b;
yield current;
b = a + b;
a = current;
}
}
sequence = fib();
sequence.next(); // 1
sequence.next(); // 1
sequence.next(); // 2
// ...
Here's a simple function to iterate the Fibonacci sequence into an array using arguments in the for function more than the body of the loop:
fib = function(numMax){
for(var fibArray = [0,1], i=0,j=1,k=0; k<numMax;i=j,j=x,k++ ){
x=i+j;
fibArray.push(x);
}
console.log(fibArray);
}
fib(10)
[ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 ]
You should've declared the fib variable to be an array in the first place (such as var fib = [] or var fib = new Array()) and I think you're a bit confused about the algorithm.
If you use an array to store the fibonacci sequence, you do not need the other auxiliar variables (x,y,z) :
var fib = [0, 1];
for(var i=fib.length; i<10; i++) {
fib[i] = fib[i-2] + fib[i-1];
}
console.log(fib);
Click for the demo
You should consider the recursive method too (note that this is an optimised version) :
function fib(n, undefined){
if(fib.cache[n] === undefined){
fib.cache[n] = fib(n-1) + fib(n-2);
}
return fib.cache[n];
}
fib.cache = [0, 1, 1];
and then, after you call the fibonacci function, you have all the sequence in the fib.cache field :
fib(1000);
console.log(fib.cache);
The golden ration "phi" ^ n / sqrt(5) is asymptotic to the fibonacci of n, if we round that value up, we indeed get the fibonacci value.
function fib(n) {
let phi = (1 + Math.sqrt(5))/2;
let asymp = Math.pow(phi, n) / Math.sqrt(5);
return Math.round(asymp);
}
fib(1000); // 4.346655768693734e+208 in just a few milliseconds
This runs faster on large numbers compared to the recursion based solutions.
You're not assigning a value to z, so what do you expect y=z; to do? Likewise you're never actually reading from the array. It looks like you're trying a combination of two different approaches here... try getting rid of the array entirely, and just use:
// Initialization of x and y as before
for (i = 2; i <= 10; i++)
{
alert(x + y);
z = x + y;
x = y;
y = z;
}
EDIT: The OP changed the code after I'd added this answer. Originally the last line of the loop was y = z; - and that makes sense if you've initialized z as per my code.
If the array is required later, then obviously that needs to be populated still - but otherwise, the code I've given should be fine.
Another easy way to achieve this:
function fibonacciGenerator(n) {
// declare the array starting with the first 2 values of the fibonacci sequence
// starting at array index 1, and push current index + previous index to the array
for (var fibonacci = [0, 1], i = 2; i < n; i++)
fibonacci.push(fibonacci[i-1] + fibonacci[i - 2])
return fibonacci
}
console.log( fibonacciGenerator(10) )
function fib(n) {
if (n <= 1) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
fib(10); // returns 55
fibonacci 1,000 ... 10,000 ... 100,000
Some answers run into issues when trying to calculate large fibonacci numbers. Others are approximating numbers using phi. This answer will show you how to calculate a precise series of large fibonacci numbers without running into limitations set by JavaScript's floating point implementation.
Below, we generate the first 1,000 fibonacci numbers in a few milliseconds. Later, we'll do 100,000!
const { fromInt, toString, add } =
Bignum
const bigfib = function* (n = 0)
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n >= 0) {
yield toString (a)
_ = a
a = b
b = add (b, _)
n = n - 1
}
}
console.time ('bigfib')
const seq = Array.from (bigfib (1000))
console.timeEnd ('bigfib')
// 25 ms
console.log (seq.length)
// 1001
console.log (seq)
// [ 0, 1, 1, 2, 3, ... 995 more elements ]
Let's see the 1,000th fibonacci number
console.log (seq [1000])
// 43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
10,000
This solution scales quite nicely. We can calculate the first 10,000 fibonacci numbers in under 2 seconds. At this point in the sequence, the numbers are over 2,000 digits long – way beyond the capacity of JavaScript's floating point numbers. Still, our result includes precise values without making approximations.
console.time ('bigfib')
const seq = Array.from (bigfib (10000))
console.timeEnd ('bigfib')
// 1877 ms
console.log (seq.length)
// 10001
console.log (seq [10000] .length)
// 2090
console.log (seq [10000])
// 3364476487 ... 2070 more digits ... 9947366875
Of course all of that magic takes place in Bignum, which we will share now. To get an intuition for how we will design Bignum, recall how you added big numbers using pen and paper as a child...
1259601512351095520986368
+ 50695640938240596831104
---------------------------
?
You add each column, right to left, and when a column overflows into the double digits, remembering to carry the 1 over to the next column...
... <-001
1259601512351095520986368
+ 50695640938240596831104
---------------------------
... <-472
Above, we can see that if we had two 10-digit numbers, it would take approximately 30 simple additions (3 per column) to compute the answer. This is how we will design Bignum to work
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s, Number) .reverse ()
, toString: (b) =>
Array.from (b) .reverse () .join ('')
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
We'll run a quick test to verify our example above
const x =
fromString ('1259601512351095520986368')
const y =
fromString ('50695640938240596831104')
console.log (toString (add (x,y)))
// 1310297153289336117817472
And now a complete program demonstration. Expand it to calculate the precise 10,000th fibonacci number in your own browser! Note, the result is the same as the answer provided by wolfram alpha
const Bignum =
{ fromInt: (n = 0) =>
n < 10
? [ n ]
: [ n % 10, ...Bignum.fromInt (n / 10 >> 0) ]
, fromString: (s = "0") =>
Array.from (s, Number) .reverse ()
, toString: (b) =>
Array.from (b) .reverse () .join ('')
, add: (b1, b2) =>
{
const len = Math.max (b1.length, b2.length)
let answer = []
let carry = 0
for (let i = 0; i < len; i = i + 1) {
const x = b1[i] || 0
const y = b2[i] || 0
const sum = x + y + carry
answer.push (sum % 10)
carry = sum / 10 >> 0
}
if (carry > 0) answer.push (carry)
return answer
}
}
const { fromInt, toString, add } =
Bignum
const bigfib = function* (n = 0)
{
let a = fromInt (0)
let b = fromInt (1)
let _
while (n >= 0) {
yield toString (a)
_ = a
a = b
b = add (b, _)
n = n - 1
}
}
console.time ('bigfib')
const seq = Array.from (bigfib (10000))
console.timeEnd ('bigfib')
// 1877 ms
console.log (seq.length)
// 10001
console.log (seq [10000] .length)
// 2090
console.log (seq [10000])
// 3364476487 ... 2070 more digits ... 9947366875
100,000
I was just curious how far this little script could go. It seems like the only limitation is just time and memory. Below, we calculate the first 100,000 fibonacci numbers without approximation. Numbers at this point in the sequence are over 20,000 digits long, wow! It takes 3.18 minutes to complete but the result still matches the answer from wolfram alpha
console.time ('bigfib')
const seq = Array.from (bigfib (100000))
console.timeEnd ('bigfib')
// 191078 ms
console.log (seq .length)
// 100001
console.log (seq [100000] .length)
// 20899
console.log (seq [100000])
// 2597406934 ... 20879 more digits ... 3428746875
BigInt
JavaScript now has native support for BigInt. This allows for calculating huge integers very quickly -
function* fib (n)
{ let a = 0n
let b = 1n
let _
while (n >= 0) {
yield a.toString()
_ = a
a = b
b = b + _
n = n - 1
}
}
console.time("fib(1000)")
const result = Array.from(fib(1000))
console.timeEnd("fib(1000)")
document.body.textContent = JSON.stringify(result, null, 2)
body {
font-family: monospace;
white-space: pre;
}
I like the fact that there are so many ways to create a fibonacci sequence in JS. I will try to reproduce a few of them. The goal is to output a sequence to console (like {n: 6, fiboNum: 8})
Good ol' closure
// The IIFE form is purposefully omitted. See below.
const fiboGenClosure = () => {
let [a, b] = [0, 1];
let n = 0;
return (fiboNum = a) => {
[a, b] = [b, a + b];
return {
n: n++,
fiboNum: fiboNum
};
};
}
// Gets the sequence until given nth number. Always returns a new copy of the main function, so it is possible to generate multiple independent sequences.
const generateFiboClosure = n => {
const newSequence = fiboGenClosure();
for (let i = 0; i <= n; i++) {
console.log(newSequence());
}
}
generateFiboClosure(21);
Fancy ES6 generator
Similar to the closure pattern above, using the advantages of generator function and for..of loop.
// The 'n' argument is a substitute for index.
function* fiboGen(n = 0) {
let [a, b] = [0, 1];
while (true) {
yield [a, n++];
[a, b] = [b, a + b];
}
}
// Also gives a new sequence every time is invoked.
const generateFibonacci = n => {
const iterator = fiboGen();
for (let [value, index] of iterator) {
console.log({
n: index,
fiboNum: value
});
if (index >= n) break;
}
}
generateFibonacci(21);
Tail call recursion
This one is a little tricky, because, now in late 2018, TC optimization is still an issue. But honestly – if you don't use any smart tricks to allow the default JS engine to use a really big numbers, it will get dizzy and claims that the next fibonacci number is "Infinity" by iteration 1477. The stack would probably overflow somewhere around iteration 10 000 (vastly depends on browser, memory etc…). Could be probably padded by try… catch block or check if "Infinity" was reached.
const fibonacciRTC = (n, i = 0, a = 0, b = 1) => {
console.log({
n: i,
fibonacci: a
});
if (n === 0) return;
return fibonacciRTC(--n, ++i, b, a + b);
}
fibonacciRTC(21)
It can be written as a one-liner, if we throe away the console.log thing and simply return a number:
const fibonacciRTC2 = (n, a = 0, b = 1) => n === 0 ? a : fibonacciRTC2(n - 1, b, a + b);
console.log(fibonacciRTC2(21))
Important note!
As I found out reading this mathIsFun article, the fibonacci sequence is valid for negative numbers as well! I tried to implement that in the recursive tail call form above like that:
const fibonacciRTC3 = (n, a = 0, b = 1, sign = n >= 0 ? 1 : -1) => {
if (n === 0) return a * sign;
return fibonacciRTC3(n - sign, b, a + b, sign);
}
console.log(fibonacciRTC3(8)); // 21
console.log(fibonacciRTC3(-8)); // -21
There is also a generalization of Binet's formula for negative integers:
static float phi = (1.0f + sqrt(5.0f)) / 2.0f;
int generalized_binet_fib(int n) {
return round( (pow(phi, n) - cos(n * M_PI) * pow(phi, -n)) / sqrt(5.0f) );
}
...
for(int i = -10; i < 10; ++i)
printf("%i ", generalized_binet_fib(i));
A quick way to get ~75
ty #geeves for the catch, I replaced Math.floor for Math.round which seems to get it up to 76 where floating point issues come into play :/ ...
either way, I wouldn't want to be using recursion up and until that point.
/**
* Binet Fibonacci number formula for determining
* sequence values
* #param {int} pos - the position in sequence to lookup
* #returns {int} the Fibonacci value of sequence #pos
*/
var test = [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986,102334155,165580141,267914296,433494437,701408733,1134903170,1836311903,2971215073,4807526976,7778742049,12586269025,20365011074,32951280099,53316291173,86267571272,139583862445,225851433717,365435296162,591286729879,956722026041,1548008755920,2504730781961,4052739537881,6557470319842,10610209857723,17167680177565,27777890035288,44945570212853,72723460248141,117669030460994,190392490709135,308061521170129,498454011879264,806515533049393,1304969544928657,2111485077978050,3416454622906707,5527939700884757,8944394323791464,14472334024676221,23416728348467685,37889062373143906,61305790721611591,99194853094755497,160500643816367088,259695496911122585,420196140727489673,679891637638612258,1100087778366101931,1779979416004714189,2880067194370816120,4660046610375530309,7540113804746346429,12200160415121876738,19740274219868223167,31940434634990099905,51680708854858323072,83621143489848422977,135301852344706746049,218922995834555169026];
var fib = function (pos) {
return Math.round((Math.pow( 1 + Math.sqrt(5), pos)
- Math.pow( 1 - Math.sqrt(5), pos))
/ (Math.pow(2, pos) * Math.sqrt(5)));
};
/* This is only for the test */
var max = test.length,
i = 0,
frag = document.createDocumentFragment(),
_div = document.createElement('div'),
_text = document.createTextNode(''),
div,
text,
err,
num;
for ( ; i < max; i++) {
div = _div.cloneNode();
text = _text.cloneNode();
num = fib(i);
if (num !== test[i]) {
err = i + ' == ' + test[i] + '; got ' + num;
div.style.color = 'red';
}
text.nodeValue = i + ': ' + num;
div.appendChild(text);
frag.appendChild(div);
}
document.body.appendChild(frag);
You can get some cache to speedup the algorithm...
var tools = {
fibonacci : function(n) {
var cache = {};
// optional seed cache
cache[2] = 1;
cache[3] = 2;
cache[4] = 3;
cache[5] = 5;
cache[6] = 8;
return execute(n);
function execute(n) {
// special cases 0 or 1
if (n < 2) return n;
var a = n - 1;
var b = n - 2;
if(!cache[a]) cache[a] = execute(a);
if(!cache[b]) cache[b] = execute(b);
return cache[a] + cache[b];
}
}
};
If using ES2015
const fib = (n, prev = 0, current = 1) => n
? fib(--n, current, prev + current)
: prev + current
console.log( fib(10) )
If you need to build a list of fibonacci numbers easily you can use array destructuring assignment to ease your pain:
function fibonacci(n) {
let fibList = [];
let [a, b] = [0, 1]; // array destructuring to ease your pain
while (a < n) {
fibList.push(a);
[a, b] = [b, a + b]; // less pain, more gain
}
return fibList;
}
console.log(fibonacci(10)); // prints [0, 1, 1, 2, 3, 5, 8]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>fibonacci series</title>
<script type="text/javascript">
function generateseries(){
var fno = document.getElementById("firstno").value;
var sno = document.getElementById("secondno").value;
var a = parseInt(fno);
var result = new Array();
result[0] = a;
var b = ++fno;
var c = b;
while (b <= sno) {
result.push(c);
document.getElementById("maindiv").innerHTML = "Fibonacci Series between "+fno+ " and " +sno+ " is " +result;
c = a + b;
a = b;
b = c;
}
}
function numeric(evt){
var theEvent = evt || window.event;
var key = theEvent.keyCode || theEvent.which;
key = String.fromCharCode(key);
var regex = /[0-9]|\./;
if (!regex.test(key)) {
theEvent.returnValue = false;
if (theEvent.preventDefault)
theEvent.preventDefault();
}
}
</script>
<h1 align="center">Fibonacci Series</h1>
</head>
<body>
<div id="resultdiv" align="center">
<input type="text" name="firstno" id="firstno" onkeypress="numeric(event)"><br>
<input type="text" name="secondno" id="secondno" onkeypress="numeric(event)"><br>
<input type="button" id="result" value="Result" onclick="generateseries();">
<div id="maindiv"></div>
</div>
</body>
</html>
I know this is a bit of an old question, but I realized that many of the answers here are utilizing for loops rather than while loops.
Sometimes, while loops are faster than for loops, so I figured I'd contribute some code that runs the Fibonacci sequence in a while loop as well! Use whatever you find suitable to your needs.
function fib(length) {
var fibArr = [],
i = 0,
j = 1;
fibArr.push(i);
fibArr.push(j);
while (fibArr.length <= length) {
fibArr.push(fibArr[j] + fibArr[i]);
j++;
i++;
}
return fibArr;
};
fib(15);
sparkida, found an issue with your method. If you check position 10, it returns 54 and causes all subsequent values to be incorrect. You can see this appearing here: http://jsfiddle.net/createanaccount/cdrgyzdz/5/
(function() {
function fib(n) {
var root5 = Math.sqrt(5);
var val1 = (1 + root5) / 2;
var val2 = 1 - val1;
var value = (Math.pow(val1, n) - Math.pow(val2, n)) / root5;
return Math.floor(value + 0.5);
}
for (var i = 0; i < 100; i++) {
document.getElementById("sequence").innerHTML += (0 < i ? ", " : "") + fib(i);
}
}());
<div id="sequence">
</div>
Here are examples how to write fibonacci using recursion, generator and reduce.
'use strict'
//------------- using recursion ------------
function fibonacciRecursion(n) {
return (n < 2) ? n : fibonacciRecursion(n - 2) + fibonacciRecursion(n - 1)
}
// usage
for (let i = 0; i < 10; i++) {
console.log(fibonacciRecursion(i))
}
//-------------- using generator -----------------
function* fibonacciGenerator() {
let a = 1,
b = 0
while (true) {
yield b;
[a, b] = [b, a + b]
}
}
// usage
const gen = fibonacciGenerator()
for (let i = 0; i < 10; i++) {
console.log(gen.next().value)
}
//------------- using reduce ---------------------
function fibonacciReduce(n) {
return new Array(n).fill(0)
.reduce((prev, curr) => ([prev[0], prev[1]] = [prev[1], prev[0] + prev[1]], prev), [0, 1])[0]
}
// usage
for (let i = 0; i < 10; i++) {
console.log(fibonacciReduce(i))
}
I just would like to contribute with a tail call optimized version by ES6. It's quite simple;
var fibonacci = (n, f = 0, s = 1) => n === 0 ? f : fibonacci(--n, s, f + s);
console.log(fibonacci(12));
There is no need for slow loops, generators or recursive functions (with or without caching). Here is a fast one-liner using Array and reduce.
ECMAScript 6:
var fibonacci=(n)=>Array(n).fill().reduce((a,b,c)=>a.concat(c<2?c:a[c-1]+a[c-2]),[])
ECMAScript 5:
function fibonacci(n){
return Array.apply(null,{length:n}).reduce(function(a,b,c){return a.concat((c<2)?c:a[c-1]+a[c-2]);},[]);
}
Tested in Chrome 59 (Windows 10):
fibonacci(10); // 0 ms -> (10) [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
JavaScript can handle numbers up to 1476 before reaching Infinity.
fibonacci(1476); // 11ms -> (1476) [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...]
Another implementation, while recursive is very fast and uses single inline function. It hits the javascript 64-bit number precision limit, starting 80th sequence (as do all other algorithms):
For example if you want the 78th term (78 goes in the last parenthesis):
(function (n,i,p,r){p=(p||0)+r||1;i=i?i+1:1;return i<=n?arguments.callee(n,i,r,p):r}(78));
will return: 8944394323791464
This is backwards compatible all the way to ECMASCRIPT4 - I tested it with IE7 and it works!
This script will take a number as parameter, that you want your Fibonacci sequence to go.
function calculateFib(num) {
var fibArray = [];
var counter = 0;
if (fibArray.length == 0) {
fibArray.push(
counter
);
counter++
};
fibArray.push(fibArray[fibArray.length - 1] + counter);
do {
var lastIndex = fibArray[fibArray.length - 1];
var snLastIndex = fibArray[fibArray.length - 2];
if (lastIndex + snLastIndex < num) {
fibArray.push(lastIndex + snLastIndex);
}
} while (lastIndex + snLastIndex < num);
return fibArray;
};
This is what I came up with
//fibonacci numbers
//0,1,1,2,3,5,8,13,21,34,55,89
//print out the first ten fibonacci numbers
'use strict';
function printFobonacciNumbers(n) {
var firstNumber = 0,
secondNumber = 1,
fibNumbers = [];
if (n <= 0) {
return fibNumbers;
}
if (n === 1) {
return fibNumbers.push(firstNumber);
}
//if we are here,we should have at least two numbers in the array
fibNumbers[0] = firstNumber;
fibNumbers[1] = secondNumber;
for (var i = 2; i <= n; i++) {
fibNumbers[i] = fibNumbers[(i - 1)] + fibNumbers[(i - 2)];
}
return fibNumbers;
}
var result = printFobonacciNumbers(10);
if (result) {
for (var i = 0; i < result.length; i++) {
console.log(result[i]);
}
}
Beginner, not too elegant, but shows the basic steps and deductions in JavaScript
/* Array Four Million Numbers */
var j = [];
var x = [1,2];
var even = [];
for (var i = 1;i<4000001;i++){
j.push(i);
}
// Array Even Million
i = 1;
while (i<4000001){
var k = j[i] + j[i-1];
j[i + 1] = k;
if (k < 4000001){
x.push(k);
}
i++;
}
var total = 0;
for (w in x){
if (x[w] %2 === 0){
even.push(x[w]);
}
}
for (num in even){
total += even[num];
}
console.log(x);
console.log(even);
console.log(total);
My 2 cents:
function fibonacci(num) {
return Array.apply(null, Array(num)).reduce(function(acc, curr, idx) {
return idx > 2 ? acc.concat(acc[idx-1] + acc[idx-2]) : acc;
}, [0, 1, 1]);
}
console.log(fibonacci(10));
I would like to add some more code as an answer :), Its never too late to code :P
function fibonacciRecursive(a, b, counter, len) {
if (counter <= len) {
console.log(a);
fibonacciRecursive(b, a + b, counter + 1, len);
}
}
fibonacciRecursive(0, 1, 1, 20);
Result
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
function fibo(count) {
//when count is 0, just return
if (!count) return;
//Push 0 as the first element into an array
var fibArr = [0];
//when count is 1, just print and return
if (count === 1) {
console.log(fibArr);
return;
}
//Now push 1 as the next element to the same array
fibArr.push(1);
//Start the iteration from 2 to the count
for(var i = 2, len = count; i < len; i++) {
//Addition of previous and one before previous
fibArr.push(fibArr[i-1] + fibArr[i-2]);
}
//outputs the final fibonacci series
console.log(fibArr);
}
Whatever count we need, we can give it to above fibo method and get the fibonacci series upto the count.
fibo(20); //output: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
Fibonacci (one-liner)
function fibonacci(n) {
return (n <= 1) ? n : fibonacci(n - 1) + fibonacci(n - 2);
}
Fibonacci (recursive)
function fibonacci(number) {
// n <= 1
if (number <= 0) {
return n;
} else {
// f(n) = f(n-1) + f(n-2)
return fibonacci(number - 1) + fibonacci(number - 2);
}
};
console.log('f(14) = ' + fibonacci(14)); // 377
Fibonacci (iterative)
function fibonacci(number) {
// n < 2
if (number <= 0) {
return number ;
} else {
var n = 2; // n = 2
var fn_1 = 0; // f(n-2), if n=2
var fn_2 = 1; // f(n-1), if n=2
// n >= 2
while (n <= number) {
var aa = fn_2; // f(n-1)
var fn = fn_1 + fn_2; // f(n)
// Preparation for next loop
fn_1 = aa;
fn_2 = fn;
n++;
}
return fn_2;
}
};
console.log('f(14) = ' + fibonacci(14)); // 377
Fibonacci (with Tail Call Optimization)
function fibonacci(number) {
if (number <= 1) {
return number;
}
function recursion(length, originalLength, previous, next) {
if (length === originalLength)
return previous + next;
return recursion(length + 1, originalLength, next, previous + next);
}
return recursion(1, number - 1, 0, 1);
}
console.log(`f(14) = ${fibonacci(14)}`); // 377

Categories

Resources