I'm trying to use the factorial function with memoization. I have taken the max value from the object to reduce the number of recursive calls made. But the problem is the first call is I don't know whether this is optimized or not since the first call is pretty expensive. Any insights on this will be great.
let cache = {0: 1};
function factMemoize(key) {
if (!cache[key]) {
let maxVal = Object.keys(cache).reduce(function (a, b) {
return Math.max(a, b);
});
console.log(maxVal);
while (key >= maxVal) {
cache[key] = key * factMemoize(key - 1);
maxVal++;
}
}
return cache[key];
}
You don't buy much from memoizing this since you only use each value once. After you've called the function you do have the cache for a second call, but we often think of memoizing as something that happens in a cache that only exists during the function. For something like that, calculating Fibonacci numbers is a classic example where memoizing is a huge improvement over the naive recursive function.
Having said that, in your function it's not clear why you are using an object for your cache and then searching it. You can just use an array where the indexes will be the number you're looking for calculate. You don't need to search it, just start with the number and recursively call the next lower one. If there's a cache it, it will return. For example:
let cache = [1];
function factMemoize(key) {
if (!cache[key]) {
cache[key] = key * factMemoize(key - 1)
} else { // just to demo cache:
console.log("cache hit:", key)
}
return cache[key]
}
// only hits cache at the end
console.log("6! = ", factMemoize(6))
// second call benefits from cache:
console.log("8! = ", factMemoize(8))
Factorial Memoization using Closure
As #mark-meyer mentioned in this thread, there is no advantage coming from memoizing the results since each value will be calculated only one time during computation. The solution Mark offered is great for reusing the function in a later time by re-calling factorials with same or different values. In that case, you can speed up the process and reduce the time complexity by reusing existing results.
Here is how it can look like in a closure:
function factorialFn() {
const cache = [];
return function _factorial() {
if (n < 2) {
return 1;
}
if (cache[n]) {
return cache[n];
}
return cache[n] = n * _factorial(n - 1);
}
}
Then, you can use it like so:
const factorial = factorialFn();
factorial(5); // 120
factorial(7); // 5040
At the first call, it will calculate `factorial(5)` and save it in cache for future reference.
At the second call, `factorial(7)` will execute `7 * factorial(6)`, which `factorial(6)` is basically `6 * the cached value of factorial(5)`
let cache = {};
function factorial(n) {
if (n < 2) return 1;
if (n in cache) return cache[n];
return cache[n] = n * factorial(n - 1);
}
factorial(5); // it will store values in cache from 2-5
factorial(7); // for this it would not compute till 5(from cache)
Related
Example 1.
var fibonacci = function () {
var memo = [0, 1];
var fib = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
return fib;
}();
Example 2.
var memoizer = function (memo, fundamental) {
var shell = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fundamental(shell, n);
memo[n] = result;
}
return result;
};
return shell;
};
var fibonacci = memoizer([0, 1], function (shell, n) {
return shell(n - 1) + shell(n - 2);
});
Above are 2 code snippets from Crockford's book to demonstrate the concept of memoization.
Question 1. How do I invoke function fibonacci from any of 2 examples? By usual way fibonacci (5)?
Question 2. As I can see, argument "n" is not defined anywhere when calling var fib = function (n) { or var shell = function (n) {.
In the first example of fibonacci function I'd expect "n" to be defined right after the 2nd line var memo = [0, 1];, and I'd expect "n" to be defined as follows: n = arguments[0];.
However since this doesn't seem to be the case, so I have to ask: how is "n" determined when fibonacci is invoked?
Thanks.
Page from Crockford's books
Question 1: How do I call each one?
The first example, note the }() at the end. This is invoking the function, which in turn gives the fib function back. So fibonacci() in the first example is really fib() with it's own internal references (e.g. memo and fib), memo only being accessible by fib but lasting as a reference as long as a reference to fib exists (the variable holding fibonacci's return).
The second example is similar, except it's substituting a memoizer that accepts an array of items and returns shell, which has access to the array it was passed.
Question 2: What is n as an argument doing?
Since you're really calling a reference to an internally created but externally available fib() and shell() when you call either fibonacci function, you're passing in a new number, which then has it's fibonacci sequence "memoized" by storing it in the internally available memo given at the beginning.
The point is that memoization is like a hash store where computations already known (since they were previously performed and "memoized") are accessible (preventing re-computation), and using Javascript's closure construct allows you to use internally-scoped variables to manage that access.
I don't have much practice with recursion and I have only some experience with javascript.
How do I refactor the code below to use recursion instead of the for loop?
function add(a, b) {
var sum = 0;
for (var i = a; i <= b; i++) {
sum += i;
}
return sum;
}
console.log(add(3,7)); //25
The for loop makes sense to me; recursion not so much.
EASY WAY:
function recursive(a, b)
{
if(a > b)
{
return 0;
}
return a + recursive(a+1, b);
}
console.log(recursive(3,7));
HARD WAY: (EASY + EXPLANATION)
What is a recursion in a common programming language?
according to Wikipedia: Recursion in computer science is a method where the solution to a problem depends on solutions to smaller instances of the same problem (as opposed to iteration).
translated in everyday language a recursion is when you iterate n-times a function(in this case) and every time that the function call hisself wait for the result of the invoked function's instance.
The invoked functions's intance will invoke himself another time and wait for the result.
When this endless loop will stop?
When an instance will finally return a value, this happens typically with a check before the recursive call(see the easy way).
When a function will return a value all the knots will be loose and the first function that started the cycle will return the final value.
if you want to go deep or just my short explanation was not convincing i reccoment you to read this article: https://www.codecademy.com/en/forum_questions/5060c73fcfadd700020c8e54
You could use another parameter for the sum of the last call, for a later tail call optimisation of the recursive call.
At start, initialize s which keeps the summed result and add a.
The perform an exit check, if the target value is reached, then exith with the sum s.
Otherwise call the function again with reduced start value, given end value and the actual sum of all.
Don't forget to return the value of the call.
function sum(a, b, s) {
s = s || 0;
s += a;
if (a === b) {
return s;
}
return sum(a + 1, b, s);
}
console.log(sum(3, 7));
Without tail optimization, this keeps all intermediate results in stack.
function sum(a, b) {
if (a === b) {
return a;
}
return a + sum(a + 1, b);
}
console.log(sum(3, 7));
I'm trying to solve a puzzle, and am at my wit's end trying to figure it out.
I'm supposed to make a function that works like this:
add(1); //returns 1
add(1)(1); //returns 2
add(1)(1)(1); //returns 3
I know it can be done because other people have successfully completed the puzzle. I have tried several different ways to do it. This is my most recent attempt:
function add(n) {
//Return new add(n) on first call
if (!(this instanceof add)) {
return new add(n);
}
//Define calc function
var obj = this;
obj.calc = function(n) {
if (typeof n != "undefined") {
obj.sum += n;
return obj.calc;
}
return obj.sum;
}
//Constructor initializes sum and returns calc(n)
obj.sum = 0;
return obj.calc(n);
}
The idea is that on the first call, a new add(n) is initialized and calc(n) is run. If calc receives a parameter, it adds n to sum and returns itself. When it eventually doesn't receive a parameter, it returns the value of sum.
It makes sense in theory, but I can't get it to work. Any ideas?
--edit--
My code is just the route I chose to go. I'm not opposed to a different approach if anyone can think of one.
To answer "how dow this work". Given:
function add(n) {
function calc(x) {
return add(n + x);
}
calc.valueOf = function() {
return n;
}
return calc;
}
var sum = add(1)(2)(3); // 6
When add is called the first time, it stores the value passed in in a variable called n. It then returns the function calc, which has a closure to n and a special valueOf method (explained later).
This function is then called with a value of 2, so it calls add with the sum of n + x, wich is 1 + 2 which 3.
So a new version of calc is returned, this time with a closure to n with a value of 3.
This new calc is called with a value of 3, so it calls add with n + x, which this time is 3 + 3 which is 6
Again add returns a new calc with n set to 6. This last time, calc isn't called again. The returned value is assigned to the variable sum. All of the calc functions have a special valueOf method that replaces the standard one provided by Object.prototype. Normally valueOf would just return the function object, but in this case it will return the value of n.
Now sum can be used in expressions, and if its valueOf method is called it will return 6 (i.e. the value of n held in a closure).
This seems pretty cool, and sum will act a lot like a primitve number, but it's actually a function:
typeof sum == 'function';
So be careful with being strict about testing the type of things:
sum * 2 // 12
sum == 6 // true
sum === 6 // false -- oops!!
Here's a somewhat streamlined version of #RobG's great answer:
function add(n) {
function calc(x) { return n+=x, calc; }
calc.valueOf = function() { return n; };
return calc;
}
The minor difference is that here calc just updates n and then returns itself, rather than returning itself via another call to add, which puts another frame on the stack.
Making self-replication explicit
calc is thus a pure self-replicating function, returning itself. We can encapsulate the notion of "self replication" with the function
function self_replicate(fn) {
return function x() {
fn.apply(this, arguments);
return x;
};
}
Then add could be written in a possibly more self-documenting way as
function add(n) {
function update(x) { n += x; }
var calc = self_replicate(update);
calc.valueOf = function() { return n; };
return calc;
}
Parallel to Array#reduce
Note that there is a certain parallelity between this approach to repeatedly calling a function and Array#reduce. Both are reducing a list of things to a single value. In the case of Array#reduce the list is an array; in our case the list is parameters on repeated calls. Array#reduce defines a standard signature for reducer functions, namely
function(prev, cur)
where prev is the "accumulator" (value so far), cur is the new value being fed in, and the return value becomes the new value the accumulator. It seems useful to rewrite our implementation to make use of a function with that kind of signature:
function add(n) {
function reducer(prev, cur) { return prev + cur; }
function update(x) { n = reducer(n, x); }
var calc = self_replicate(update);
calc.valueOf = function() { return n; };
return calc;
}
Now we can create a more general way to create self-replication-based reducers based on a reducer function:
function make_repeatedly_callable_function(reducer) {
return function(n) {
function update(x) { n = reducer(n, x); }
var calc = self_replicate(update);
calc.valueOf = function() { return n; };
return calc;
};
}
Now we can create add as
var add = make_repeatedly_callable_function(function(prev, cur) { return prev + cur; });
add(1)(2);
Actually, Array#reduce calls the reducer function with third and fourth arguments, namely the index into the array and the array itself. The latter has no meaning here, but it's conceivable we might want something like the third argument to know what "iteration" we're on, which is easy enough to do by just keeping track using a variable i:
function reduce_by_calling_repeatedly(reducer) {
var i = 0;
return function(n) {
function update(x) { n = reducer( n, x, i++); }
var calc = self_replicate(update);
calc.valueOf = function() { return n; };
return calc;
};
}
Alternative approach: keeping track of values
There are certain advantages to keeping track of the intermediate parameters the function is being called with (using an array), and then doing the reduce at the end instead of as we go along. For instance, then we could do Array#reduceRight type things:
function reduce_right_by_calling_repeatedly(reducer, initialValue) {
var array_proto = Array.prototype,
push = array_proto.push,
reduceRight = array_proto.reduceRight;
return function(n) {
var stack=[],
calc = self_replicate(push.bind(stack));
calc.valueOf = reduceRight.bind(stack, reducer, initialValue);
return calc(n);
};
}
Non-primitive objects
Let's try using this approach to build ("extend") objects:
function extend_reducer(prev, cur) {
for (i in cur) {
prev[i] = cur[i];
}
return prev;
}
var extend = reduce_by_calling_repeatedly(extend_reducer);
extend({a: 1})({b: 2})
Unfortunately, this won't work because Object#toValue is invoked only when JS needs a primitive object. So in this case we need to call toValue explicitly:
extend({a: 1})({b: 2}).toValue()
Thanks for the tip on valueOf(). This is what works:
function add(n) {
var calc = function(x) {
return add(n + x);
}
calc.valueOf = function() {
return n;
}
return calc;
}
--edit--
Could you please explain how this works? Thanks!
I don't know if I know the correct vocabulary to describe exactly how it works, but I'll attempt to:
Example statement: add(1)(1)
When add(1) is called, a reference to calc is returned.
calc understands what n is because, in the "mind" of the interpreter, calc is a function child of add. When calc looks for n and doesn't find it locally, it searches up the scope chain and finds n.
So when calc(1) is called, it returns add(n + x). Remember, calc knows what n is, and x is simply the current argument (1). The addition is actually done inside of calc, so it returns add(2) at this point, which in turn returns another reference to calc.
Step 2 can repeats every time we have another argument (i.e. (x)).
When there aren't any arguments left, we are left with just a definition of calc. The last calc is never actually called, because you need a () to call a function. At this point, normally the interpreter would return a the function object of calc. But since I overrode calc.valueOf it runs that function instead.
When calc.valueOf runs, it finds the most recent instance of n in the scope chain, which is the cumulative value of all previous n's.
I hope that made some sense. I just saw #RobG 's explanation, which is admittedly much better than mine. Read that one if you're confused.
Here's a variation using bind:
var add = function _add(a, b) {
var boundAdd = _add.bind(null, a + b);
boundAdd.valueOf = function() {
return a + b;
}
return boundAdd;
}.bind(null, 0);
We're taking advantage of a feature of bind that lets us set default arguments on the function we're binding to. From the docs:
bind() also accepts leading default arguments to provide to the target
function when the bound function is called.
So, _add acts as a sort of master function which takes two parameters a and b. It returns a new function boundAdd which is created by binding the original _add function's a parameter to a + b; it also has an overridden valueOf function which returns a + b (the valueOf function was explained quite well in #RobG's answer).
To get the initial add function, we bind _add's a parameter to 0.
Then, when add(1) is called, a = 0 (from our initial bind call) and b = 1 (passed argument). It returns a new function where a = 1 (bound to a + b).
If we then call that function with (2), that will set b = 2 and it'll return a new function where a = 3.
If we then call that function with (3), that will set b = 3 and it'll return a new function where a = 6.
And so on until valueOf is called, at which point it'll return a + b. Which, after add(1)(2)(3), would be 3 + 3.
This is a very simple approach and it meets the criteria the OP was looking for. Namely, the function is passed an integer, keeps track of that integer, and returns itself as a function. If a parameter is not passed - the function returns the sum of the integers passed to it.
let intArray = [];
function add(int){
if(!int){
return intArray.reduce((prev, curr) => prev + curr)
}
intArray.push(int)
return add
}
If you call this like so:
console.log(add(1)(1)());
it outputs 2.
How can I limit the depth of recursion in the function?
Here's a simple function that inserts '...' when an object has been seen before, preventing infinite recursion.
function safeStringify (value) {
const seen = new Set()
return JSON.stringify(value, (k, v) => {
if (seen.has(v)) { return '...' }
if (typeof v === 'object') { seen.add(v) }
return v
})
}
When creating a recursive function, you can always pass a so called accumulative parameter. Simply pass an extra numeric parameter that you increment each time you enter a new level of recursion (i.e. increment your parameter exactly once each recursive iteration) and pass it through.
You can use this technique for a variety of things, as well as keeping track of the depth of recursion. Simply check the value of the parameter at the start of your function, and return when it is equal to the maximum depth that you wish to traverse into.
Example
This example shows a variable called depthLevel that signifies the level of depth in a tree for the current node. The maxDepthLevel constant should be defined somewhere. This Depth First algorithm will not traverse deeper than maxDepthLevel. Notice how the depthLevel is increased by 1 for each level of recursion, making it an accumulative parameter.
function depthFirst(var node, var depthLevel) {
if(depthLevel > maxDepthLevel) {
return;
}
//do logic for this node here
var childrenOfThisNode = node.getChildren();
foreach(var child in childrenOfThisNode) {
depthFirst(child, depthLevel + 1)
}
}
I'm following an online course about Javascript Functional Programming
at the Exercise 16 it show you how reduce is actually implemented, in order to help you understand how to use it, but into this implementation there is something i don't actually get, i'll show the code:
Array.prototype.reduce = function(combiner, initialValue) {
var counter, accumulatedValue;
// If the array is empty, do nothing
if (this.length === 0) {
return this;
}
else {
// If the user didn't pass an initial value, use the first item.
if (arguments.length === 1) {
counter = 1;
accumulatedValue = this[0];
}
else if (arguments.length >= 2) {
counter = 0;
accumulatedValue = initialValue;
}
else {
throw "Invalid arguments.";
}
// Loop through the array, feeding the current value and the result of
// the previous computation back into the combiner function until
// we've exhausted the entire array and are left with only one value.
while(counter < this.length) {
accumulatedValue = combiner(accumulatedValue, this[counter])
counter++;
}
return [accumulatedValue];
}
};
I don't understand the first if statement, when it check for this.length what this actually mean?
Take note this is different from the reduce in ES5, which returns an value instead of an Array, this is used just as a sample for the learning purpose.
Array.prototype.reduce = function(...
is saying, "create a function on the prototype of Array" - this means that the new reduce function will be callable on all arrays, eg:
[1, 2, 3].reduce(...
This means you can also call it on empty arrays, eg:
[].reduce(...
Building on the comment:
If the array is empty, do nothing
You're working on an array, and when the function is called, this is set to the array that reduce was called on. This implementation of reduce assumes that if that array is empty (ie this.length === 0), you can't logically reduce it any further - there's nothing to reduce, so you can return the same empty array.
As pointed out by #Alnitak in the comments, this implementation of reduce is flawed as compared to the specification. A different implementation is available on the MDN for polyfilling older browsers.