Javascript anonymous function error - javascript

I have been trying to use recursion to find the sum of a number using an anonymous function in javascript but I am getting the following error:
Uncaught SyntaxError: Unexpected token +
I want to use an anonymous function for this. Can anyone help me in finding what I am doing wrong here?
<script type="text/javascript">
console.log(function (n) {
if (n == 0) {
return 1;
}
else {
return function(n+function(n-1));
}
}(8));
</script>

There are several problems with what you're doing.
For starters, attempting to call the function recursively (function(n+function(n-1))) will result in a call stack size exceeded error because you're adding the sum to each argument passed to the recursive call. You probably want something closer to (n + function(n-1)).
However, this is still problematic, because you can't call an anonymous function recursively (except by using arguments.callee, which is disallowed in strict mode).
To do what it appears you're trying to do without giving a name to your function expression, you could do something like:
console.log(function(n) {
if (n == 0) {
return 1;
}
else {
return n + arguments.callee(n-1);
}
}(8))
However, you could also provide a name for your function expression to refer to in recursive calls, which will work in strict mode as well:
console.log(function foo(n) {
if (n == 0) {
return 1;
}
else {
return n + foo(n-1);
}
}(8))
edited: In the base case (n == 0) you probably want to return 0 instead of 1 if your goal is to get the sum of all whole numbers from 0 to n.

console.log(function fn(n) {
if (n == 0) {
return 1;
} else {
return (n + fn(n - 1));
}
}(8));
Error in this line function(n+function(n-1)), because this is syntax error, you can not call function like you do. In our case you should add for self-Invoking function - name, and use it for recursion call stack

When I revised the anonymous function to use the correct recursion, namely return n + f(n-1), I discovered that oddly enough the following code works without resorting to arguments.callee as long as the script resides on an HTML page. Note: it still does not work with console.log.
One more thing, if the code in this instance is attempting to get the sum of numbers ranging from eight to one, then when n equals zero, the return value should be zero and not one for the sum to be mathematically correct.
var f = function (n) {
if (n == 0) {
return 0;
}
else {
return n + f(n-1);
}
};
var res = f(8); // 36
See live example at http://jsfiddle.net/d5k4ag8w/11/
Also, this article provides an easy way to figure out the math using just pencil and paper :)

Related

Type Error : not iterable Array Function (Beginner)

let grades=[4,73,67,38,33]
function gradingStudents(grades) {
for (const i of grades) {
if (i >= 38 && i % 5 == 3) {
return i + 2;}
else if (i >= 38 && i % 5 == 4) {
return i + 1;}
return i;
}
}
console.log(gradingStudents())
I am trying to log the results but the function is not working I know I missed something, I am a beginner can you tell me what I am doing wrong.
I tried what could but I dont understand
Your functions expects an argument.
While calling function, you are not passing any argument.
Be sure to call your function with argument.
Such as,
console.log(gradingStudents(grades))
im a beginner to
i know this is not the best way to display the result of GrandingStudents Function but it works
i think this is not a good idea to make a return in a loop.
the loop will break at the first iteration
My Solution

Difference between returning calculation with function name and without

The below function calculates the Fibonacci, why the last calculation needs to include the function name and not just (n-1)+(n-2) ?
function fibonacci(n){
if (n===1){ return 1}
else if (n===0){ return 0}
else return fibonacci(n-1)+fibonacci(n-2) // (n-1)+(n-2) does not work. Why?
}
I know this is a beginner question but couldn't find the answer. I'd appreciate any comments.
I understand that I need to use recursion, but that's not the point of my question.
this is recursive solution:
function fibonacci(n){
if (n===1){ return 1}
else if (n===0){ return 0}
else return fibonacci(n-1)+fibonacci(n-2)
}
You are calling this function for nth fibonacci. But you don't know nth fibonacci yet. so you must find (n-1) and (n-2) fibonacci. That is why you must call fibonacci(n-1)+fibonacci(n-2).
And you don't even know n-1th and n-2th fibonacci that is why you must call it until known fibonacci. You know first and second fibonaccis. That is wht when n == 1 or n==0 you return just answer.
for example:
n = 7
fibonacci(7) = fibonacci(6) + fibonacci(5)
fibonacci(6) = fibonacci(5) + fibonacci(4)
fibonacci(5) = fibonacci(4) + fibonacci(3)
fibonacci(4) = fibonacci(3) + fibonacci(2)
fibonacci(3) = fibonacci(2) + fibonacci(1)
fibonacci(2) = fibonacci(1) + fibonacci(0)
fibonacci(1) = 1
fibonacci(0) = 0

Getting this error message: Maximum call stack size exceeded

I'm trying to solve this leetcode problem. In this problem, I basically need to return the power of x.
But when I run my solution it returns this error message:
RangeError: Maximum call stack size exceeded
My code:
function myPow(base, exponent){
if(exponent === 0) {
return 1;
} else if(exponent < 0){
return (myPow(base,exponent + 1)/base);
} else {
return base * myPow(base,exponent-1);
}
}
myPow(0.00001, 2147483647) // this test case is failing only I think
Updated code according to Luca Kiebel's suggestion
function myPow(base, exponent){
if(exponent === 0) {
return 1;
} else if(exponent < 0){
return (myPow(base,exponent + 1)/base);
} else {
return base ** myPow(base,exponent-1);
}
}
Anyone please explain me where I'm making a mistake.
You're calling the function inside itself too many times, making the JS Engine think there's a problem, and killing it before it takes too much CPU/RAM.
Using Math.pow or a simple for loop (Instead of recursion) should fix the problem.
See Browser Javascript Stack size limit for how many times you can call a function inside another one
You are basically getting that error because your function is calling itself multiple times, until a stack limit is reached.
You can try using Math.pow() function to achieve what you are trying to do.
Recursion is not a good choice if you did want to roll your own raise-to-the-power function, but you can do it in a very simple loop
function myPow(x,n){
var res = 1;
for(var i=0;i<Math.abs(n);i++)
res = n<0 ? res/x : res * x
return res
}
console.log(myPow(2, 10), Math.pow(2,10), 2 ** 10)
console.log(myPow(2, -2), Math.pow(2,-2), 2 ** -2)
//console.log(myPow(0.00001, 2147483647), Math.pow(0.00001,2147483647), 0.00001 ** 2147483647)
But as you can see from the above examples, you're simply reinventing the wheen of Math.pow or the ** operator

recursion on returning vectors c++

Hey guys I am trying trying to right this javascript code into c++. I am doing quick sort and everything is straight forward minus the last step.
function quickSort(arr)
{
//base case if the arr is 1 or 0 then return the array
if(arr.length === 1 || arr.length === 0)
{
return arr;
}
var pivotIndex = Math.floor(arr.length/2);
var pivotValue = arr[pivotIndex];
var before = [];
var after = [];
for(var counter = 0; counter < arr.length; counter++)
{
if(counter === pivotIndex)
continue;
if(pivotValue <= arr[counter])
{
before.push(arr[counter])
}
else
{
after.push(arr[counter])
}
}
//this step I am having trouble rewriting in c++
return quickSort(after).concat(pivotValue).concat(quickSort(before));
}
I am having a hard time rewriting the recursive step in c++. I am not sure how concat 2 vector. I tried using the insert method but I keep getting an error about invalid use of void expression.
vector<int> quickSort(vector<int> arr)
{
if(arr.size() == 1 || arr.size() == 0)
{
return arr;
}
int pivotIndex = arr.size()/2;
int pivotValue = arr[pivotIndex];
vector<int> before;
vector<int> after;
//put values in before or after the piv
for(size_t counter = 0; counter < arr.size(); counter++)
{
if(counter == pivotIndex)
continue;
if(pivotValue <= arr[counter])
before.push_back( arr[counter]);
else
after.push_back( arr[counter]);
}
return //????? not sure how to do this
}
So, you realized that your core question was "how to concatenate two vectors", and you found a right answer: using insert. Now your question is about why you were getting "an error about invalid use of void expression." (That's the assumption my answer is for, at least.)
That's because you were likely trying to do something like the following:
return quickSort(after).insert( /* stuff */ );
which is wrong. In JavaScript, array.concat returns the concatenated array. It's return type is effectively Array, and so doing return arr.concat(arr2) returns an Array because arr.concat would return an Array. Further, in JavaScript, array.concat doesn't modify the array it was called on, but rather returns a new array.
In C++, however, vector.insert (#4 in the reference) returns void. That means it returns nothing. So when you try to return the result of insert, you get that error about invalid use of a void expression. Further, in C++, vector.insert does modify the vector it was called on.
So how do you use insert in this case?
vector<int> quickSort(vector<int> arr)
{
// ...
// Sort `before` and `after`
before = quickSort(before);
after = quickSort(after);
// Modify `after` and return it.
after.push_back(pivotValue);
after.insert(after.end(), before.begin(), before.end());
return after;
}
Note: My code isn't optimal and the idea of rewriting JS in C++ is also oddly specific. My answer is to simply outline the problem asked in the question, not to give a good C++ implementation of quick sort.
To concat two vector , you can use std::merge
like:std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst));

Why is the first argument of reduce() returning undefined?

I'm trying to write a function that takes in an array as an input. If the integer is positive, it counts it. If the integer is negative, it sums it.
I figured that that the reduce() helper in js would be the best way to go about this, but I keep returning undefined for my first argument when it runs.
Here's my code:
function countPositivesSumNegatives(input) {
let countPositive = 0;
let sumNegative = 0
if (input === null || input === []){
return [];
} else {
return input.reduce(function(prev,num){
if (num > 0) {
countPositive++;
}else{
sumNegative = prev + num};
}, 0);
}
return [countPositive, sumNegative];
}
It throws me a TypeError that says:
TypeError: Cannot read property '0' of undefined
When I log 'prev' to the console inside of the reduce function, it logs undefined for all inputs except the first one. The first one, as expected, is 0. But for each following input it logs undefined. Why is this happening?
Thanks in advance.
The callback you pass to .reduce() needs to return the cumulative value (the value that will be passed as prev to the next iteration of the loop. Since you are returning nothing, you get undefined for the next iteration of your loop.
This complicates what you're trying to do because you are trying to keep track of two values in your loop. As such, you would either have to avoid using prev at all or you'd have to make it be a data structure that had both your values in it. Your use is not a textbook example for .reduce(). Your code is probably simpler with an iteration using .forEach() or for/of.
function countPositivesSumNegatives(input) {
let countPositive = 0;
let sumNegative = 0
if (!input || input.length === 0){
return [];
} else {
input.forEach(function(num){
if (num > 0) {
++countPositive;
} else {
sumNegative += num;
});
}
return [countPositive, sumNegative];
}
Well sorry but this is not a good implementation of this function. But we can correct your function as follows;
function countPositivesSumNegatives(input) {
let countPositive = 0;
let sumNegative = 0;
if (input === null || input === []){
return [];
} else {
sumNegative = input.reduce(function(prev,num){
if (num > 0) {
countPositive++;
} else {
prev += num;
}
return prev; // <---- THE MISSING PART
}, 0);
}
return [countPositive, sumNegative];
}
var data = [1,2,3,4,5,-4,7,-3];
console.log(countPositivesSumNegatives(data));
However while the code works just fine it still involves many issues. When getting into functors like .reduce() you should be able to keep everthing contained within itself and should not refer to variables at the outer scope. Accordingly one can simply rephrase this code as follows;
var data = [1,2,3,4,5,-4,7,-3],
cpsn = a => a.reduce((p,c) => c > 0 ? (p[0]++,p) : (p[1]+=c,p) ,[0,0]);
console.log(cpsn(data))

Categories