The shortest ways I got were:
Recursive function:
function f(n){return n<3?1:f(n-1)+f(n-2)}
In case I am using direct return and applying a conditional operator to test if the value is less than 3 to return 1 and else it applies the recursive calculation.
This way you can eliminate the comma, variable declaration or very expressive syntax. But performance is one of the worst possible.
Function with variable cache:
function f(n,a,b){return n<3?1:!a?f(n-1)+f(n-2):!b?f(n-1)+a:a+b}
In this case I used the same conditional operator feature, but it also includes a test to see if the variables a
exists and then b
changing the calculation formula to use the cache if it is available.
The same function can be written as follows:
function f(n,a,b){
if (n < 3) return 1;
if (typeof a === 'undefined') return f(n - 1) + f(n - 2);
if (typeof b === 'undefined') return f(n-1)+a;
return a+b;
}
Function with Array Cache:
function f(n,c){c=c|[];return !c[n]?c[n]=n<3?1:f(n-1,c)+f(n-2,c):c[n]}
First I test using |
(bitwise operator or) to see if the variable c
that represents the cache exists, if it exists, I use it itself, if it does not exist it will receive a new array as value.
In the calculation, it will be checked if there is a cached value before anything, there is nothing in the cache, it will check if the value is less than 3 to return 1 or recursively try to apply the same function.
To have a better use of the cache it is possible to adapt it this way:
function f(n){return !f.c[n]?f.c[n]=n<3?1:f(n-1)+f(n-2):f.c[n]};f.c=[];
In this case the cache is being stored as property of the function and can be reused the next times the function is executed, not having to recalculate the values already added in the cache.
A way to better read this function would be:
function f(n) {
if (typeof f.cache[n] === 'undefined') {
if (n < 3) {
f.cache[n] = 1;
return f.cache[n];
}
f.cache[n] = f(n - 1) + f(n - 2)
return f.cache[n];
}
return f.cache[n];
}
f.cache=[];
Please avoid long discussions in the comments; your talk was moved to the chat
– Maniero