Getting this error message: Maximum call stack size exceeded - javascript

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

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

Refactoring JavaScript function results

I'm working on a project using Leaflet's Mapping API. Right now, I'm cleaning up my code and there's one section I feel could be made better.
I have it set when the location is found, the location is checked both in accuracy and in bounds:
function checkLocation(position)
{
if(position.accuracy > 100)
{
return 4;
}
else if((position.latlng.lat <= **bound** || position.latlng.lat >= **bound**) || (position.latlng.lng >= **bound** || position.latlng.lng <= **bound**))
{
return 5;
}
return 0;
}
Basically, if the accuracy is too low, I throw an error with error code 4. If the coordinates are outside of where I want them to be, I throw an error with error code 5 (These are to correspond to Leaflet's builtin error codes 1-3 so I can switch on them later). I return 0 just to say there wasn't an error.
This function is called by the locationFound event, which has the following code:
var temp = checkLocation(position);
if(temp != 0)
{
// Handle error code
return;
}
This also works, but I'm not fond of how this looks. What I want is for this bit to only take like two to three lines, preferably without an if statement. I originally had the code for checkLocation in this section, but I thought having it on its own would make for cleaner and more reader-friendly code.
My question is is there any way to improve this bit? I looked into lambda expressions but didn't think it fit and I tried using a Promise, but at that point, I was losing lines trying to cut down on lines. I don't want to code golf the code, but I'm still pretty new to JavaScript and I don't know if there's any way to simplify this while still looking professional. I'm also up for changing the checkLocation function if it means improving the code.
If you refactor to this:
function invalidAccuracy(position) {
return position.accuracy > 100;
}
function outOfBounds(position) {
return (position.latlng.lat <= **bound** || position.latlng.lat >= **bound**) || (position.latlng.lng >= **bound** || position.latlng.lng <= **bound**);
}
You can handle it like this:
function checkLocation(position) {
if(invalidAccuracy(position))
return 4;
if(outOfBounds(position))
return 5;
return 0;
}
You can (if you want) put it in 1 line then:
return invalidAccuracy(position) ? 4:
outOfBounds(position) ? 5 :
0;

How i put together two functions, both with a recursion inside

I am a beginner and this my first post here(plus I'm not a native English speaker), so please forgive me if my code and/or my English are bad.Given two numbers I want to write a JavaScript function to find if the second one is a power of the first one, and then determine that power (ex: 2,8 the output must be 3). I wrote two functions, both working, but I can't put them together.
This is the first one to check if the second number is a power of the first one.
function checkNumbers(x,y){
if (y%x !==0){
return "this numbers are not valid"
}
else if(x===y) {
return "correct!"
}
else {
y=y/x
return checkNumbers(x,y)
}
}
checkNumbers(2,8) // will give the first answer
checkNumbers(2,18) // will give the second answer
The second function will give you the integral logarithm:
count =1;
function findGrade(x,y) {
if(y/x===1)
return "the grade is " + count;
count++;
y = y/x;
return findGrade(x,y)
}
findGrade(2,8) // output 3
findGrade(2,16) // output 4
How can I put them together into one function? I think i need a closure, but I didn't find the way to make that work.
checkNumbers should return a Boolean value, not a message. Then findGrade can check that result to see whether it should compute the logarithm. Something like this:
function checkNumbers(x,y){
if (y%x !==0){
return false
}
else if(x===y) {
return true
}
// the rest of your function remains the same.
function findGrade(x,y) {
// First, check to see whether y is a power of x
if checkNumbers(x,y) {
// your original findGrade function goes here
}
else
return -1; // Use this as a failure code.
Does this work for you?
Another possibility is to combine the functions entirely: try to find the logarithm (what you call "grade"); if it works, you get your answer; if it fails (at y%x !== 0), then you report the failure.
The solution is, in fact, pretty simple.
You could do the following:
function findGrade(x, y, count = 1) {
// If the numbers are not valid, throw an error. The execution is interrupted.
if(y % x != 0) throw "Invalid inputs";
// If the inputs are different, continue the execution and add 1 to count.
if(x != y) return findGrade(x, y/x, ++count);
// If none of the above are true, you have your result!
return count;
}
Tests:
console.log(findGrade(2, 8)); // Outputs 3
console.log(findGrade(2, 16)); // Outputs 4
console.log(findGrade(2, 3)); // Error: Invalid inputs
console.log(findGrade(3, 3486784401)); // Outputs 20
Please let me know if you need any further help.
I'm not sure if my method is different, but I have implemented it below. In real world application I would do some more typechecking on inputs and check if there is a third argument: if not default to 0 (First Iteration default the count to 0), but this is the general idea. You can run the snippet below.
// Arguments
// 1: Base of Exponent
// 2: test Number
// 3: count by reference
function checkPower (base, test, count) {
let division = test/base
// base case
if (division === 1) {
count++
return count
} else if (division < 1) {
console.log("not a power")
return;
}
// iteration step
count++
return checkPower(base, division, count++)
}
// Test Cases
let test = checkPower(2, 32, 0)
if (test) {
console.log(test) // 5
}
test = checkPower(2, 1024, 0)
if (test) {
console.log(test) // 10
}
test = checkPower(2, 9, 0)
if (test) {
console.log(test) // "not a power"
}

No output in quicksort

I'm trying to implement a quicksort function in JavaScript:
function partition(l, low, high) {
l[0] = l[low];
var pivotkey = l[low];
while (low < high) {
while (low < high && pivotkey <= l[high]) {
--high;
}
l[low] = l[high];
while (low < high && l[low] <= pivotkey) {
++low;
}
l[high] = l[low];
}
l[low] = l[0];
return low;
}
function qsort(l, low, high) {
var pivotloc;
if (low < high) {
pivotloc = partition(l, low, high);
qsort(l, low, pivotloc - 1);
qsort(l, pivotloc + 1, high);
}
return;
}
function quickSort(l) {
qsort(l, 1, l.length - 1);
return l;
}
console.log(quickSort([0, 1, 4, 3]));
But this program output nothing in the terminal (with node qsort.js). Perhaps I'm missing something. Can anyone point me in the right direction? How to debug this kind of problems?
So as you stated the first element of the array will be used as a temporary variable which will be only useful for the execution of the algorithm and which wasn't clear at first !
Your algorithm works fine but you have problem in printing the result !
To get what you want you need to get rid of the first element by adding the shift() function in the quickSort() block so it becomes :
function quickSort(l) {
qsort(l, 1, l.length - 1);
l.shift(); // add this function
return l;
}
There is another solution if you want by using the splice() function which removes the first element also and which has this form :
array.splice(indexToRemove, numberToRemove);
so to get the required resutl add the instruction above to your quickSort() function like this:
function quickSort(l) {
qsort(l, 1, l.length - 1);
l.splice(0, 1); //add this line
return l;
}
These are the two solutions I guess for your problem. Hope it helps !!
I believe there are several issues with your algorithm. But the one I can notice immediately is related to you using l.low and l.high in your partition function. I'm assuming that l is an array in which case, both of these are intended to access the indices at low and high. If that's the case, then these should be l[low] and l[high].
Since it seems like you're trying to do an in-place version of quick sort, take a look at what's available here: In Place Quick Sort

Javascript anonymous function error

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 :)

Categories