Recursive Factorial inside Object Javascript - javascript

const Calculate = {
factorial(n) {
return n * factorial(n - 1)
}
}
let newNumber = Calculate.factorial(8);
So every time I call the function I get a factorial not defined error. I'm guessing it has something to do with the function being inside an object. Need some help in understanding whats going on. Thank you in advance

Objects don't create a variable scope, so you need to refer to the object when calling the method.
You can also use this to refer to the object that the method was called on, so you don't have to hard-code the variable name.
const Calculate = {
factorial(n) {
if (n <= 1) {
return 1;
}
return n * this.factorial(n - 1)
}
}
let newNumber = Calculate.factorial(8);
console.log(newNumber);

Related

Can I make an outer argument the same as an inner argument?

I am trying to create a function that returns the sum of all the multiples of 3 or 5 below the number passed in. I immediately recognized the similarity to "FizzBuzz". This is the first codewars challenge. I have created two functions that I have tested and they work independently, but I can't figure out how to reference the argument of the outer function solution() in my inner function returnNumber. Every time I try to run the function, I get an answer of 0.
function solution(number){
function returnNumbers(number){
let numbers=[];
for (let i=1; i<number; i++){
if (i % 3 == 0 && i % 5 == 0) numbers.push(i);
else if (i % 3 == 0) numbers.push(i);
else if (i % 5 == 0) numbers.push(i);
} //end of for loop
return numbers
} //end of returnNumbers
let sum = returnNumbers().reduce(function(a, b){
return a + b;
}, 0);
return sum
} //end of solution
I already tried assigning a new variable for the original argument but maybe I didn't do it correctly. Like this:
function solution(number){
let x = number
function returnNumbers(x){
let numbers=[];
for (let i=1; i<x; i++){
if (i % 3 == 0 && i % 5 == 0) numbers.push(i);
else if (i % 3 == 0) numbers.push(i);
else if (i % 5 == 0) numbers.push(i);
} //end of for loop
return numbers
} //end of returnNumbers
let sum = returnNumbers().reduce(function(a, b){
return a + b;
}, 0);
return sum
}
I imagine the solution is simple, but I am an absolute beginner (< 3weeks) so I would appreciate some help.
The main issue you are facing is scope - how long a variable still "exists". The main thing to realize is that anything in the outer function is still in scope in the inner function, as long as you don't declare a variable with the same name (when you do, the outer variable is shadowed - it still exists, you just can't access it, because when you use that name you'll get the inner one).
So, your first solution is correct, except that you need to not have an argument to the function:
function returnNumbers(number){
should just be
function returnNumbers(){
because number is already in scope, but if you declare it as an argument, you will need to pass it (but that's pointless in this case).
when calling returnNumbers function, argument is not getting passed. Try passing the outer function value to it.
let sum = returnNumbers(number).reduce(function(a, b){
return a + b;
}, 0);
Your inner function already has access to the outer function's parameter (because it's sitting inside of the outer function's brackets). So in your case, returnNumbers can already use number without having it passed as a parameter.
By declaring it as a parameter for returnNumbers, you're shadowing the number variable. You have two possible solutions.
Either pass number to returnNumbers
let sum = returnNumbers(number).reduce(function(a, b){
return a + b;
}, 0);
Or remove returnNumbers parameter
function returnNumbers(){
...
}

Javascript factorial function memoization

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)

Idiomatic population of an array as long as a property's value

I have a dice-rolling bot that spits out results via var roll = new Roll('4#2d20+3'). That constructor makes objects with properties parsed out of the string argument, which resembles this:
aRoll = {
text: '4#2d20+3',
times: 4,
dice: 2,
sides: 20,
modifier: 3,
roll: function() {...}
}
The roll() method should use the object's properties to generate an array of results. This is an exercise to learn what's new in JavaScript, so I'm curious how best to accomplish this.
Old, procedural way:
this.roll = function() {
var total = 0;
for (var i=0; i < this.dice; i++) {
total += Math.floor(Math.random() * this.sides) + 1;
}
return total;
}
My attempt at new Array functional iteration:
this.roll = () => Array(this.dice).fill(0).reduce(state => {
result + Math.floor(Math.random() * state.sides) + 1;
}, this);
This sorta works, but Array(x).fill(0).reduce(... is an ugly hack, and passing this in as state seems like a sign I'm doing the wrong thing.
Is there an Array method I should use instead? Or is the for loop still the cleanest way to accomplish this?
One way to repeat a function n times is
Array.from(Array(n), fn)
To make all of this more readable, you could define, for example
let times = (n, fn) => Array.from(Array(n), fn);
let rand = n => Math.floor(Math.random() * n) + 1;
let sum = a => a.reduce((x, y) => x + y);
and then
roll = function() {
return sum(
times(this.dice,
rand.bind(0, this.sides)));
}
I think I figured out how this “should” be done.
The first issue is straightforward: do not use arrow functions as methods:
An arrow function does not create its own this context, so this has its original meaning from the enclosing context.
this is the whole point of object-orientation, so breaking it is a bad idea. Passing this as map()’s second argument was indeed a code smell.
The second issue: instead of abusing reduce()’s initial value parameter with this to fake a context object, use a closure:
function roll(sides) {
return (total) => {
total + Math.floor(Math.random() * sides) + 1;
};
}
someArray.map(roll(this.sides));
When you pass callbacks as arguments, but need to dynamically give them data that callers don’t provide, closures are the classic solution.
As for the third issue, populating an array the size of an object property, in order to call a function that many times…
There is no built-in boilerplate way. :•) #georg kindly provided a clean implementation of a times() function that reminds me of Ruby’s Number.times(), if you’re interested.

Is it possible to add a value when returning a function from a recursive function being chained? [duplicate]

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.

circular references among javascript functions

How can one define a pair of functions that call each other in Javascript so that JS-lint does not complain that 'factorial' is being used before it is defined?
function factorial1(n) { return factorial(n); }
function factorial(n) { return n === 0 ? 1 : n * factorial1(n - 1); }
It seems there is no valid ordering that will satisfy JSlint.
(One can be embedded in the other, but this would be a nightmare for a collection of functions that all call each other).
Surely this is handled by the language right?
Is this just a bug in JSlint?
(This question must have been answered somewhere, but I cannot find it!)
The references inside the functions is not resolved until they are executed. As long as both functions has been defined by the time one of them executes, they will find each other.
If you want to get rid of the JSLint warning, you could define the name of the function, just before:
var factorial;
function factorial1(n) { return factorial(n); }
function factorial(n) { return n === 0 ? 1 : n * factorial1(n - 1); }
I prefer this syntax to functions:
var factorial1 = function(n) { return factorial(n); }
var factorial = function(n) { return n === 0 ? 1 : n * factorial1(n - 1); }
Will not be able to forget to "declare" function with this syntax.
Another approach to this problem, is to pass it as a callback function, like this:
const factorial1 = (n, callback) => { return callback(n); }
const factorial = (n) => { return n === 0 ? 1 : n * factorial1(n - 1, factorial ); }

Categories