Addition assignment did not run as expected in Javascript's recursive functions - javascript

For the following functions that use addition assignment, the value of ans is always changed to 1 when an integer greater than 1 is passed
let ans = 0;
function reduce(num){
if(num == 0){
return 0;
}
ans += reduce(num-1);
return 1;
}
reduce(5);
console.log(ans); // 1
But when I save the recursive result to another variable first, the function works fine (ans will be changed to num-1)
let ans = 0;
function reduce(num){
if(num == 0){
return 0;
}
let tmp=reduce(num-1);
ans += tmp;
return 1;
}
reduce(5);
console.log(ans); // 4
How does this happen? Is this a feature of Javascript or a bug in the environment?
I have tried similar C codes and they all behave the same
#include<stdio.h>
int reduce(int num);
int ans;
int main(){
ans = 0;
reduce(5);
printf("%d",ans); // 4
}
int reduce(int num){
if(num == 0){
return 0;
}
int tmp=reduce(num-1);
ans += tmp;
// ans += reduce(num-1);
return 1;
}
Environment:
Microsoft Edge 97.0.1072.55
JavaScript V8 9.7.106.18

This happens because in JavaScript ans += reduce(num-1) is evaluated as:
ans = ans + reduce(num-1)
and not as:
ans = reduce(num-1) + ans;
(See (13.15.2) Runtime semantics: evaluation in the ECMAScript specs).
So ans is evaluated before the recursive call is made, and it is that evaluated value that is used as the operand of the addition.
You can avoid such unexpected behaviour by avoiding functions with side-effects. A pure recursive solution would be:
function reduce(num) {
if (num < 2) {
return 0;
}
return reduce(num-1) + 1;
}
let ans = reduce(5);
console.log(ans); // 4

Related

What is while(n- - >1)meaning?

I saw a question in leetcode.
Also,I found solution in it.
And one thing i don't understand is this line of code
while(n-- >1)
Could someone explain --> meaning?
Here is the JS:
var countAndSay = function(n) {
var result = "1";
var prev;
var count;
var tmp;
while (n-- > 1) {
prev = result[0];
count = 1;
tmp = [];
for (var i = 1; i < result.length; i++) {
if (prev === result[i]) {
count++;
} else {
tmp.push(count, prev);
prev = result[i];
count = 1;
}
}
tmp.push(count, prev);
result = tmp.join("");
}
return result;
};
console.log(countAndSay(4))
One last thing,Could someone explain what is this question's meaning.
I still don't understand why 2 is 11,3 is 21,4 is 1211 and 5 is 111221.
The expression
n-- > 1
means: subtract one from n, and check whether its value before the subtraction was greater than 1.
while (n-- > 1) {
// rest of the code
is equivalent to
while (true) {
if (n > 1) {
n--;
// rest of the code
} else {
// n is decremented regardless:
n--;
// initial condition was not fulfilled:
break;
}
Or, with the negation of the condition:
while (true) {
const origN = n;
n--;
if (!(origN > 1)) {
break;
}
// rest of the code
That means you check whether the n is greater than 1 and after that decrement n by 1.
That means, subtract 1 from n and check if the result is greater than 1.
n-- in any part of the code is equivalent to n = n - 1, or ``n -= 1`, in that loop is a consised way to subtract and evaluate.
The expression (n-- > 1) is similar to comparing the value of n greater than 1. But the thing which you must notice is the value of n will not be decremented(at the beginning) while comparing here. This is because the value of n is first compared with 1 after that only, the value of n is decremented. To understand this clearly, you can take a look over this.
function test(name) {
var n = 5;
while (n-- == 5) { //Here the decrement doesn't takes places so it gets inside the block
console.log(n); //This statement returns the value of n as 4.
}
}
const testing = new test();

Prime Check JavaScript

What have I done wrong with this code? It can't print anything on the console.
Here it is the description of the problem:
Implement a javascript function that accepts an array containing an integer N and uses an expression to check if given N is prime (i.e. it is divisible without remainder only to itself and 1).
var n = ['2'];
function isPrime(n) {
if (n < 2) {
return false;
}
var isPrime = true;
for(var i = 2; i < Math.sqrt(n); i += 1) {
if (n % i === 0) {
isPrime = false;
}
}
return isPrime;
}
return isPrime(n);
There are couple errors in your code.
First, you need to check for every integer between 2 and Math.sqrt(n) inclusively. Your current code returns true for 4.
I don't think this is in a function, so you need to omit return from return isPrime(n) and replace it with a function wich prints out the return value of the funnction, like alert or console.log.
n is not a number, it's an array. You need to either make n a number, or call the function with isPrime(n[0]).
The correct code is
var n = 2;
function isPrime(n) {
if (n < 2) {
return false;
}
var isPrime = true;
for(var i = 2; i <= Math.sqrt(n); i += 1) {
if (n % i === 0) {
isPrime = false;
}
}
return isPrime;
}
alert(isPrime(n));
Note: You can change n += 1 to n++, and it works the same way.
n is an array, you want to access first element in the array and convert it to number first.
try replacing
return isPrime(n);
with
return isPrime(parseInt(n[0],10));
Your for-loop condition also needs a little modification
for(var i = 2; i <= Math.sqrt(n); i += 1) { //observe that i is not <= Math.sqrt(n)
A couple of little errors:
var n = 2;//<--no need to put n in an array
function isPrime(n) {
if (n < 2) {
return false;
}
var isPrime = true;
for(var i = 2; i < Math.sqrt(n); i += 1) {
if (n % i === 0) {
isPrime = false;
}
}
return isPrime;
}
isPrime(n);//<--no need for "return"
As to no output being printed, it is because you need to use console.log.
Replace return isPrime(n); with console.log(isPrime(n));.
Full working code:
var n = ['2', '3', '4', '5', '6', '7']; // you can use as many values as you want
function isPrime(n) {
if (n < 2) {
return false;
}
var isPrime = true;
for (var i = 2; i <= Math.sqrt(n); i += 1) { // Thanks to gurvinder372's comment
if (n % i === 0) {
isPrime = false;
}
}
return isPrime;
}
n.forEach(function(value) { // this is so you can iterate your array with js
console.log('is ' + value + ' prime or not? ' + isPrime(value)); // this so you can print a message in the console
});
/*
// Another approach of parsing the data, uncomment this piece of code and comment the one above to see it in action (both will give the same result)
for (index = 0; index < n.length; ++index) {
console.log('is ' + n[index] + ' prime or not? ' + isPrime(n[index])); // this so you can print a message in the console
}
*/

Returning factorials in JavaScript

I'm trying to create a script that returns the factorial of the input number as part of a challenge. When I try to run it, it returns the proper factorial, but apparently I did it wrong somehow.
It looks like this:
function FirstFactorial(num) {
if (num > 1) {
var x = num;
for (var i = 1; i < x; i++) {
num = num * i;
}
} else if (num === 1) {
return 1;
} else {
console.log("That's not a number!");
}
return num;
}
Then I tried doing it like this, but it still doesn't work!
function FirstFactorial(num) {
if (num < 0) {
num = 0;
console.log("You have to input a number!");
}
if (num === 0) {
return 1;
}
return num * FirstFactorial(num - 1);
}
The most likely reason is that they expected and intended you to use recursion (a function that calls itself).
If you think about factorials, each builds on the result of the previous one, which is the classic case for using recursion.
(Note that I'm specifically not posting code doing this with recursion, because presumably the point here is for you to work out how to do it.)

Calculates and outputs the factorial of variable n (n already initialized).

Here inbelow is the code. Could anybody tell that what's wrong with the code? The purpose is to the factorial result of var n. (suppose it's already declared)
for(var i = 0; i < 5; i++)
{
var n1 = Math.floor(rc4Rand.getRandomNumber() * 7) + 3;
document.write("The factorial of " + n1 + " is ");
outputFactorial(n1);
}
function outputFactorial(n)
{
//I have to add some context here to post this question.
if (n1 == 0) {
return 1;
}
else {
return (n1 * factorial(n1 - 1));
}
}
document.write(n);
Simple mistake: the name of the argument in your outputFactorial() function is n, but you're using n1 throughout the function, and thus entering an infinite recursion loop (if n1 != 0).
The factorial function must be change to outputFactorial
The n1 variables needs to be changed to n in the outputFactorial function
You have to do is Document.write(outputFactorial(n1));
Remove the outside of function Document.write

sorting an alphanum array using jQuery

i am trying to compare two arrays containing alphabets and numbers using jquery but a call to the function does nothing.
jQuery.compare = function (string2,string1) {
alert("comparing")
var i, j;
for ( i = 0, j=0; i < string2.length|| j<string1.length; ++i,++j) {
var n1 = 0,n2=0;
if ($.isNumeric(string2[i+1])) {
num=string2[i]
while ($.isNumeric(string2[i+1])) {
i++;
num += string2[i]
}
n1 = 1;
}
if ($.isNumeric(strin1[j])) {
num1 = string1[j]
while ($.isNumeric(string1[j+1])) {
j++;
num1 += string1[j]
}
n2 = 1;
}
if (n1 == 1) {
if (n2 = 1) {
if( parseInt(num1) - parseInt(num) !=0)
return parseInt(num1) - parseInt(num);
}
else
return 1;
}
else if (n2 = 1)
return -1;
else {
if(string2[i]-string1[j]!=0)
return string2[i]-string1[j]!=0;
}
}
if (j < string1.length)
return -1;
else
return 1;
}
Also i would like to know the best way to call this function. I would like to use something like string1.compare(string2) and replace string1 with 'this' in the above code fragment.
EDIT:
This is how i call the compare function.Here, colValues is an array of string.
$.fn.sort = function (colValues) {
alert("sorting")
var i;
for (i = 0; i < colValues.length; ++i) {
for (var j = 0; j < i - 1; ++j) {
alert("before compare")
if(colValues.compare(colValues[j],colValues[j + 1])) {
var temp = colValues[j];
colValues[j] = colValues[j + 1];
colValues[j + 1] = temp;
}
}
}
return colValues
}
if i replace
if(colValues.compare(colValues[j],colValues[j + 1]))
with
if(colValues[j]>colValues[j+1])
my sort function works.
i am a complete newbie at coding in jquery. There is probably some syntactical error. I dont really want any help with the algorithm just the syntax.
jsfiddle-checkout my code here
EDIT2:
i fixed everything thx to metadings.
heres what i had to change
1)
jQuery.compare
to
$.fn.compare
2)
if($.isNumeric(string2[i+1]))
to
if(jQuery.isNumeric(string2[i + 1]))
somehow the
while ($.isNumeric(string1[j+1]))
syntax worked without any changes
3)
parseInt(num1) - parseInt(num)
didnt work either as it returned NaN. To solve this problem i defined two var variables 'number1' and 'number2' and initialized them with 0's and assigned parseInt(num1) individually to the variables and then subtracted the new variables.

Categories

Resources