0

So, I have this task:
Where n is a positive integer, the function f(n) satisfies the following

f(0) = 0 
f(1) = 1
f(n) = f(n-1) + f(n-2) when n > 1
  1. Please create a program to find f(n)
  2. Use the program to find f(8181)

    const f = (n) => {
      if(n === 0) {
        return 0
      } else if(n === 1) {
        return 1
      } else if(n > 1) {
        return f(n-1) + f(n-2)
      } else {
        return null
      }
    }
    

above is the code that i have wrote but it only do just fine when i do n < 40, it starts to slow down when n > 41. it takes forever to load f(100) let alone f(8181)
so, is there any way to optimized this code to meet all the requirements?
thank you in advance!

ps: it's not a school task so i dont have anyone to consult

6
  • For n>2, f(n-1) will involve calling f(n-2), so you're doing twice as much work as needed for each iteration step. What should be an O(n) operation is becoming O(2^n)!! Commented Aug 21, 2018 at 10:24
  • i know right, but the requirement said i should do the recursion. so im wondering if i could write a condition or something Commented Aug 21, 2018 at 10:28
  • const f = (src=>(n) => {while(src.length <= n) src[src.length] = src[src.length-1] + src[src.length-2]; return src[n];})([0,1]); uses dynamic programming, not recursion - however, it is important to note that f(79) > Number.MAX_SAFE_INTEGER - for n>=79 you will get approximate values. f(8181) returns Infinity. Commented Aug 21, 2018 at 10:28
  • f(8181) is a 1,710-digit number - who assigned this insane task to you? Commented Aug 21, 2018 at 10:32
  • Possible duplicate of Fast Fibonacci recursion Commented Aug 21, 2018 at 10:38

2 Answers 2

1

You can use memoization to optimize the algorithm.

The idea is to remember the result of f(n - 1) + f(n - 2) in a JS object so that further calculations can use the memoized result instead of re-calculating everything.

Following is a demo, which instantly prints the result for f(100) correctly.

let dict = {};

const f = (n) => {
  if (n === 0) {
    return 0
  } else if (n === 1) {
    return 1
  } else if (n > 1) {
    if (!dict[n]) {
      dict[n] = f(n - 1) + f(n - 2);
    }

    return dict[n];
  } else {
    return null
  }
}

console.log(f(100));

Sign up to request clarification or add additional context in comments.

6 Comments

ah thank you!! it works. i even just heard that there is something like memoization principal lol
f(100) is 354 224 848 179 261 915 075, which is rather different from the 354 224 848 179 262 000 000 your code gives ;)
@NiettheDarkAbsol -- Did you really compare the values? :D I suppose this behaviour is due to limitations of JavaScript numbers. But the crux is memoization here. :)
I used the calculator I found and linked in a comment on the question :D And yeah. Floats are accurate to about 14-15 significant digits, which is only enough up to f(78).
@ergxpr0xy -- please consider accepting this answer if it solved your problem.
|
0

@31piy - Avoid using recursion as it is not memory efficient also because each function is getting pushed in call-stack which slows down program. Here is the program for Fibonacci series till n number without recursion.

Hope this will help you :)

/**
 * Method to return Fibonacci series with linear (without recursion)
 * @param {*} n 
 */
function getFibonacciSeries(n){
    var n1 = 0, n2 = 1, a = [], n3;
    a.push(n1);
    a.push(n2);
    for(i=2; i < n; i++){
        n3 = n1 + n2;
        a.push(n3);
        n1 = n2;
        n2 = n3;
    }
    console.log(a);
    return a[n-1];
}

3 Comments

This is nice, but it re-builds the entire array each time you call the function. Far better to have a single static array that persists across function calls. Just extend the array if the new call is higher than any previous call.
@NiettheDarkAbsol - You are right, that is more optimized one.
FYI -- The solution I proposed doesn't recurse much. If it finds the value in the dict object, then no recursion takes place. So, I think, the entire call-stack limits to 2-3 frames (didn't evaluate yet though).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.