function even(num) {//console.log(num) => shows 1 & then 0 before terminating.
if (num === 0) {
return true;
} else {
return !even(num - 1);
}
}
console.log(even(1));
//Why Chrome Console shows num = 1 when .log is being executed.
The Else part of the recursive function even would run till num becomes 0 this is quite clear but the chrome developer console shows num = 1 print when console.log is logging
Is the final value going to be 0 or 1?
Screenshot after the calls are completed:
The function you provided will recursively call itself until num is 0, and then the results will bubble back up.
So:
even( 1 ) is called - current function: even( 1 )
even( 0 ) is called by even( 1 ) - current function: even( 0 )
even( 0 ) returns true back to even( 1 ) - current function: even( 1 )
even( 1 ) returns !true: false - current function: main, but even( 1 ) was the last function called.
At the end, the last version of even() the code was running in was even( 1 ). The debugger will show num = 1 because that was the last value num had before returning.
To see this in action:
function even(num) {
console.log( "num is: " + num + " before function" );
if (num === 0) {
return true;
} else {
var returnValue = !even(num - 1);
console.log( "num is: " + num + " after recursion" );
return returnValue;
}
}
console.log(even(5));
The response will be false for odd numbers, and true for even. That looks pretty exactly what you need. But this looks overcomplex, why don't do just
function even(num) {
return n % 2 == 0;
}
Yes chrome showing right when we use that kind of data structure like recursion then here what happen all call going to stack and all operation happening according to stack push and pop operation. So
when you pass 1 to function then basically what is happening the value of num is -
1 -> 0 in stack but when your condition is true now stack is releasing so it will back on original state and the last value is 1 so that why you are getting 1.
Related
I'm trying to solve leetcode 112.Path Sum. I pass in currSum as 0 initially and want to increment currSum value by adding previous currSum value to current root.val - but currSum is not increasing, see code below:
var hasPathSum = function(root, targetSum) {
var result = helper(root, targetSum, 0);
return result;
};
function helper(root, targetSum, currSum){
if(root === null) return false;
currSum = currSum + root.val;
console.log(currSum);
if(root.left === null && root.right === null && currSum === targetSum){
return true;
}
return hasPathSum(root.left, targetSum, currSum) || hasPathSum(root.right, targetSum, currSum);
}
can someone please point me to what i am doing wrongly. Thanks in advance.
See link to the problem statement here https://leetcode.com/problems/path-sum/
What i expect currSum to be is:
5
9
20
27
22
...
but what i get is:
5
4
11
7
2
8
13
4
1
Observe that it is just printing back the current root.val at each recursive call.
Whenever you call this function
var hasPathSum = function(root, targetSum) {
var result = helper(root, targetSum, 0);
It will call helper with last parameter as zero and it only accepts two parameters - root and targetSum
Therefore when you call at the end of function
hasPathSum(root.left, targetSum, currSum)
The currSum is not used in any way, it is just lost
I have not checked the logic itself, but to keep the currSum value you need to use it in this way:
return helper(root.left, targetSum, currSum) || helper(root.right, targetSum, currSum);
So I'm making this program that loops through an array and returns each character in each element of the array. The elements in the array are lines of regular english. Here's my current code:
(I'm using javascript btw)
let array = ["this", "does", "not", "work"]
var current_pos_in_line = -1
var current_line = 0
var current_char
function advance() {
current_pos_in_line += 1
if (current_pos_in_line < array[current_line].length) {
current_char = array[current_line][current_pos_in_line]
return current_char
} else {
current_char = null
newline()
}
}
function newline() {
current_line += 1
current_pos_in_line = -1
advance()
}
for (some_condition) {
advance()
}
So you get the basic idea. The advance function loops through the current_line, and when it gets to the end, it increments current_line by 1. However, the problem is at the first if...else statement. There is an error returned when I try to do array[current_line]. It's undefined!
I have no clue why this is the case, as array[1] is most definitely defined, and current_line is within the bounds of the length of array
Please help
Change newline function as follows:
function newline() {
if (current_line < array.length - 1) {
current_line += 1
current_pos_in_line = -1
advance()
}
}
That will prevent the error, though you should really check the some_condition that drives the advance function forward.
So I was doing this popular challenge "palindrome" and I was copying this solution from the "Frontend Masters" Javascript Series and I'm getting a different output. I want to know if there is something that changes or am I missing something. This is my first question on StackOverflow because this is just MindF***k.
What is going on?
'use strict'
function isPalindrome(str) {
if (str.length <= 1) return true;
var first = str[0];
var last = str[str.length - 1];
if (first === last) {
console.log(str.substring(1, str.length - 1))
isPalindrome(str.substring(1, str.length - 1));
}
return false;
}
console.log(isPalindrome("abcdcba")) // Return false on my machine
I try this on the RunJS app as well as the VScode terminal and also I run Node on the file.
KEEP RETURNING FALSE !!
The function will return true if and only if the length of the input is <= 1:
if (str.length <= 1) return true;
Which it isn't:
isPalindrome("abcdcba")
The only other return statement in the function is:
return false;
It looks like you meant to return the recursive result:
return isPalindrome(str.substring(1, str.length - 1));
Otherwise the function never does anything with the result from calling itself recursively, and just defaults to returning false on the last line.
I fixed your code...
'use strict'
function isPalindrome(str) {
if (str.length <= 1) return true;
var first = str[0];
var last = str[str.length - 1];
if (first === last) {
console.log(str.substring(1, str.length - 1))
return isPalindrome(str.substring(1, str.length - 1));
}else return false;
}
console.log(isPalindrome("abcdcba")) //
I see recursive functions having two different parts:
Going forward when the function starts calling itself and stacking function calls.
in a reverse way going backward when all the stack functions start returning values. In your example this phase is kickoff just after if (str.length <= 1) return true or if first !== last.
I think you you did it totally right going forward, but there was a minor details in the come back. You need to remember that ones you have your solution you need to return values through all the calls back to the initial one.
A recursive function is kind of split in two:
function recursive{
//forward processing
..
resultValue = recursive()
..
// backward processing if needed
return kindOfResultValue //resultValue or a transformation if needed
}
Note: Remember to check all conditional branches of your recursive function to return always a value after calling itself
I am building a decorator for arrays of items, the array of objects is meant to be slotted into a defined range of values if it fits there.
Currently, I am doing this using some conditionals to check for the range but the code does not feel clean enough to me.
Does anyone have any suggestions about how write this code in a more concise and expandable way?
Example of current setup...
thingsToSort.forEach(function(thing) {
if (thing > 1 || thing < 3) {
// set the item to 1
}
if (thing > 3 || thing < 5) {
// set to 3
}
})
Note: I am really looking for a better way to loop through this logic and determine if object falls in the range.
One another implementation.
Created a function to represent the Range, Range
A function to identify the range and take appropriate action. setcompareRange
Notice the usage of the some method in the function compareRange. Since a number can be found in one range only, All the ranges are not evaluated and till the matched range traversal is done.
function Range(min, max){
this.min = min;
this.max = max;
}
var rangeArray = [ new Range(1,3), new Range(3,5)];
function compareRange(c,i,arr){
var result = rangeArray.some(x=> {
return setcompareRange(c, x.min, x.max)
});
}
function setcompareRange(thing, min, max){
if (thing > min && thing < max) {
// set the item to 1
console.log("set thing = " + thing + " in range = " + min);
return true;
}
}
var thingsToSort = [2,4];
thingsToSort.forEach(compareRange);
I would first double-check your logic...
thingsToSort.forEach(function(thing) {
This conditional will set ANYTHING greater than 1 to 1, and ignore the second condition (thing < 3):
if (thing > 1 || thing < 3) {
// set the item to 1
}
You should be using an && operator to AND these two conditions:
if (thing > 1 && thing < 3) {
// set the item to 1
}
The same thing goes for this conditional which will set ANYTHING greater than 3 to 3.
if (thing > 3 || thing < 5) { //should be &&
// set to 3
}
})
You are also not breaking the loop after meeting a conditional. This means that even though you have already determined that a thing meets the first condition, you are still checking to see if it meets the other conditions. This wastes resources. Use else if to prevent this:
if (thing > 1 && thing < 3) {
// set the item to 1
}
else if (thing > 3 && thing < 5) {
// set to 3
}
Other than that, it's already pretty clean. This is very similar to the classic fizzbuzz problem, of which, there are many possible refactorings
I'm new to JS, so most of my code hasn't worked. I've made a program to find out every prime number, but every time I use it, it crashes. Is there any way to make this code not crash upon running?
var i = 0;
for (;;) {
if (i % 2 === 0 || i % 3 === 0 || i % 5 === 0 || i % 7 === 0) {
i++;
}
else {
return i;
i++;
}
}
The correct approach is to use a single timer. Using setInterval, you can achieve what you want as follows:
window.onload = function start() {
primes();
}
function primes() {
var i = 0;
window.setInterval(function () {
if (i % 2 === 0 || i % 3 === 0 || i % 5 === 0 || i % 7 === 0) {
i++;
} else {
console.log(i);
i++;
}
}, 1000); // repeat forever, new value every 1 second
}
This will print the values to the console once a match is found (It does a check every second). But you can adjust this on the second parameter of the setInterval function.
If you want the results on the actual page, you can replace the console.log() with document.createTextNode().
Also, i have not checked this or know if the algorithm is right. Just adapted from your code.
List of fixes:
You manually update i and use a blank for loop instead of using the for loop normally, but having the middle condition always return true (a while loop could be used here also, but would still require manually updating i) as you don't plan on stopping. However, you can actually just put the whole thing in a timer instead of a loop, like #Leonel Atencio did.
You use return outside of a function, and if you did put this code inside of a function, it would just return the first prime number every time, so it would always return 1.
The formula is incorrect, only checking for some examples of primes; As #Alexandru-Ionut Mihai said, 121 would be considered prime, even though it is 11x11.
Fixed:
var primes = [];
var i = 1; //Start at 2; since "i" is incremented at the start of the function, this won't start it at 1, which would cause problems (the array would only have 1 in it, since all other whole numebrs are divisible by one)
setInterval(primeFunc,100);
function primeFunc(){
i++; //Increment current number
isPrime=true; //Assume prime
for(var j=0;j<primes.length;j++){ //Rule out non-primes with the power of modulo
if(i%primes[j]==0) { //If the current number can be divided (is divisible) by any previous prime...
//...then it's not a prime, so cancel any further chacks and move on
isPrime=false;
break;
}
}
if(isPrime){
//The current number is not divisible by any other primes, so it is itself a prime; if it was divisible, isPrime would be set to false by our loop above
primes.push(i);
output.innerHTML=primes;
}
}
<span id="output"></span>