Identical function leads to different outcomes in different languages - javascript

I wrote a function in javascript that is supposed to return the lowest prime number larger than x. Instead it get's caught in indefinite recursion.
function next_prime(x) {
if (x <= 1) {
return 2;
}
y = 2;
z = x + 1;
while(true) {
if (z % y == 0) {
z++;
y = 2;
continue;
}
if(y * y > z) {
return z;
}
y = next_prime(y);
}
}
I didn't understand what was wrong, so I implemented the same function in python, where it worked just fine.
def next_prime(x):
if x <= 1:
return 2
y = 2
z = x + 1
while True:
if z % y == 0:
z += 1
y = 2
continue
if y * y > z:
return z
y = next_prime(y)
I looked over both functions and I'm sure that they are identical, yet in python it works and in javascript it doesn't.
Allthough appreciated, I'm not necessarily looking for help with this specific problem, I'm more so interested in what is actually going on here.

I think the problem is that you are not declaring your variables correctly. In JavaScript, you have to use the keywords let and const - which stand for reassignable and not reassignable variables - when declaring a new variable. When using let in lines five and six, the function works just fine.

You should use strict mode to avoid this common mistake of javascript beginners.
your actual js code with 'use strict'; is rejected :
'use strict';
console.log( next_prime(7) ) // never run on strict mode, otherwise make an infinite loop
function next_prime(x) {
if (x <= 1) {
return 2;
}
y = 2;
z = x + 1;
while(true) {
if (z % y == 0) {
z++;
y = 2;
continue;
}
if(y * y > z) {
return z;
}
y = next_prime(y);
}
}
same code in correct javascript syntax :
'use strict';
console.log( next_prime(7) ) // -> 11
function next_prime(x)
{
if (x <= 1) return 2
;
let y = 2, z = x + 1 // declare y and z as locale
;
while(true)
{
if (z % y == 0)
{
z++;
y = 2;
continue;
}
if (y**2 > z) return z
;
y = next_prime(y);
}
}
explanation : your code is recursive, inside call will change y and z value on parent callers and make an infinite loop

Related

Find the Greatest Common Divisor

Here is the question.
Find the greatest common divisor of two positive integers. The integers can be large, so you need to find a clever solution.
The inputs x and y are always greater or equal to 1, so the greatest common divisor will always be an integer that is also greater or equal to 1.
Here is my solution.
function mygcd(x, y) {
//your code here
let gcd = [];
let lowestNum;
let bigestNum;
//detect the lowest and bigest numbers
if (x < y) {
lowestNum = x;
bigestNum = y;
} else if (x > y) {
lowestNum = y
bigestNum = x;
} else {
lowestNum = x
}
//check if the bigest num has a modolo == 0
//else loop the lowest num and push in the array
if (bigestNum % lowestNum === 0) {
return gcd += lowestNum;
} else {
let arrNum = []
for (let i = 1; i < lowestNum; i++) {
// console.log(i)
arrNum.push(i)
}
//loop the array backwards
for (i = arrNum.length - 1; i >= 1; i--) {
if (lowestNum % arrNum[i] === 0 && bigestNum % arrNum[i] === 0) {
console.log(arrNum[i])
if (gcd !== 0) {
return
} else {
// gcd += arrNum[i]
let vals = gcd.push(arrNum[i])
console.log(typeof(vals))
}
}
}
}
console.log(gcd)
return gcd[0];
}
console.log(mygcd(30, 12))
The above solution works for the test cases i tried it for, but the issue is that it returns the correct divisor and undefined.
This is what my logs look like
6
undefined
6
undefined
The test cases
test:
Log
6
expected undefined to equal 6
so it gets undefined instead of 6 or the correct divisor.
I also tired a different recursive approach below.
Note: This works well.
function mygcd(x, y) {
if (!x) return y
if (!y) return x
return mygcd(y, x % y)
}
console.log(mygcd(30, 12))
console.log(mygcd(8, 12))
But i am curious to understand why my original solution breaks. Any help would be really appreciated.
Thanks

switch, else if & or (Beginner Q)

I have a function which appears to always be returning true on the first condition irrelevant of input. I have been reading about using switch versus else if as I have 16 conditions to check and I want to ensure I have working 'best practice'
Can I achieve the same thing using both options:
function lsaupdateTotals() {
var x = variablename.value;
var y = variablename2.value;
if (x = 1) || (y = y > 1 && y < 280) {
rdlsa = 7.45;
} else if (x = 2 || (y = y > 281 && y < 460)) {
rdlsa = 11.65;
/ or switch: /
switch (x) {
case 1:
case y > 1:
case y < 280:
y = 7.45;
break;
}
There are several problem in your code:
In javascript, to compare 2 numbers (or strings) you have to use the syntax ===, so if (x = 1) should became if (x === '1') (as I'm expecting x is a string).
The if condition should be in a parenthesis: if (x = 1) || (y = y > 1 && y < 280) { => if ((x === 1) || (y === y > 1 && y < 280)) {
It's not clear what you mean with y = y > 1 (or y === y > 1) in first if (second parenthesis)
In switch/case syntax you cannot use y>1, please refer to switch/case syntax (internet is full of documentation)
When you put an assignment into the if (using = instead of ===) the if statement consider true the condition if the value after the = is not null, 0, empty string, false or undefined, for this reason when you write if(x=1){ the condition is always true.
You've got a few issues in your code:
You're using = instead of == or === to check equality in your if statements. A single = sign always means "set equal to", not "is equal to?".
In your if statement your parens make things a bit ambiguous. It's possible that this works just fine, but wrapping the entire question in parens is guaranteed to work as intended while also being completely clear.
Rewriting your if statement according to the above:
if (x == 1 || (y == y > 1 && y < 280)) {
rdlsa = 7.45;
}
else if (x == 2 || (y == y > 281 && y < 460)) {
rdlsa = 11.65;
}
(EDIT: Note that the y == y > 1 part is almost definitely not doing what you want it to. That's asking "is y the same thing as y > 1?")
In your switch, think of the value in each case as being a place holder for what you're putting into it. So in your example, using y>1 doesn't make sense to evaluate against x, because it's asking if x is *equal to y>1, but y>1 is always true or false and is independent of x.
you are getting the conditions wrong.
Please replace your code with the below lines
function lsaupdateTotals() {
var x = variablename.value;
var y = variablename2.value;
if ((x == 1) || (y > 1 && y < 280)) {
rdlsa = 7.45;
} else if ((x == 2) || (y > 281 && y < 460)) {
rdlsa = 11.65;
}
/ or switch: /
switch (x) {
case 1:
case y > 1:
case y < 280:
y = 7.45;
break;
}

Function to create new array producing undefined

I am trying to write a program that creates an array and populates it with a range of numbers. The function range's x, y, z variables correlates to the start number, the end number, and the number value of each step. My goal is produce an array with all the numbers between (and including) x and y that is created with each step. Here is the code:
let newarray = []
function range (x, y, z){
if (x === undefined || y === undefined || z === undefined || (x > y) || (z < 0)) {
return newarray; // returns empty array if x, y, or z is undefined, x is greater than y or z is a negative integer
}
else if (y > x) {
for (x; x < y; x = x += z) {
newarray.push(x); //pushes x into an array then adds z into x and loops until x exceeds y
}
}
else {
return newarray; //prints out new array
}
}
console.log(range(0, 10, 2));
console.log(range(10, 30, 5));
console.log(range(-5, 2, 3));
right now it is producing undefined for all three numbers. My research suggests something about asynchronicity? I'm not sure what that means.
A few things are at play here:
newArray should be defined inside the function scope rather than as a global variable. Otherwise, subsequent calls to the function will keep appending onto the same array, which is likely not your intention (and if it was, there's array.concat() for that).
Your last else is unreachable, so the function will either return an empty array for input failing your validation or return undefined when control reaches the end of the function after populating the array in the else if block.
x = x += z is probably intended as x += z.
You should disallow z === 0 otherwise you'll wind up with an infinite loop.
Normal JS style is to camelCase variable names.
Additionally, I find it's easier to write positive conditionals than negative conditionals. In this case, enumerating what arguments are allowed seems cleanest. This approach enables you to only have one return statement and fewer conditional branches, mitigating potential confusion.
Here's a version that addresses these issues:
function range(x, y, z) {
const newArray = [];
if ([x, y, z].indexOf(undefined) < 0 && x < y && z > 0) {
for (; x < y; x += z) {
newArray.push(x);
}
}
return newArray;
}
console.log(range(0, 10, 2));
console.log(range(10, 30, 5));
console.log(range(-5, 2, 3));
Note that the section where you check else if (y > x) does not have a return. When this condition is true, your function returns undefined. To fix the problem, just add return newarray; as the last line in the function. Then remove all other lines with return new array;.
The else block is not required as it will be unreachable and will
return undefined.
Corrected x = x + z from x = x += z.
The array declaration was outside, so every time the old data will be
appended with newer data from the for loop.
function range (x, y, z){
let newarray = [];
if (x === undefined || y === undefined || z === undefined || (x > y) || (z < 0)){
return newarray;
}
else if (y > x) {
for (x; x < y; x = x + z){
newarray.push(x);
}
}
return newarray;
}
console.log(range(0, 10, 2));
console.log(range(10, 30, 5));
console.log(range(-5, 2, 3));

What does ||| mean in JavaScript?

I've googled this and searched through the JavaScript documentation but I can't find any mention of this operator: a |ǀ| b
When I try the operator on its own I get an error but when I run the following code it runs perfectly fine:
var a, b = 0; tex = '\u0076\u0061r'
var players, score = 0, x, y, z = 1;
function f(s) {
var t = 0, r = 0;
var js = 'window';
while (t == r) {
if (t == 1) {
r = s.length;
return false;
} else {
t += 1;
} for (var i = 0; i < 20; i++) {
r = 20;i+=9000;eval(s); x = 50; y =+ 8;
z = -20; y = s;
}
if (r < 20) {
return t + 2;
}}
return true;
} while (f(tex + ' \u01C0='+'0') && score < 900) {
score = 9000.0001;}eval(y); a = 1; b += a;
x = 50;{y =+ 8;
}
// testing:
document.writeln(false |ǀ| false); // 0
document.writeln(false |ǀ| true); // 1
document.writeln(true |ǀ| false); // 1
document.writeln(true |ǀ| true); // 1
Changing the values of a and b would suggest it works like || but I just can't work out why it works with the previous code, but doesn't work on its own. Does anyone know whats going on here?
It's not an operator. It's the | operator, twice, with a "Latin letter 'Dental Click'" character in between. That character is valid in JavaScript identifiers. Thus the expression:
false |ǀ| false
(probably) means the same thing as
false | undefined | false
because there's no real variable called ǀ. (edit — Actually there probably is, otherwise you'd get a reference error.)
The | (bitwise-OR) operator treats its operands as numbers, and both false and undefined become 0.
That function f() is what's defining a window property called ǀ.

JavaScript: When assigning an anonymous function to a variable, function return value is not passed, rather the function as a string

I am trying to learn JavaScript but I've come across a hurdle. If the answer is obvious and reachable through a simple search I apologize in advance. I am a novice to programming and JavaScript, and unsure what line of inquiry to follow.
In the following code, the function takes values from a HTML form, does some processing and sends them back. I've tested the input and output process and it's working correctly.
function foo() {
var x = parseInt(document.formdata.fieldone.value);
var y = parseFloat(document.formdata.fieldtwo.value);
if (isNaN(y))
{ var z = x; }
else
{ var z = function(x, y) {
if ((y * (x / 100)) < 1) {
return (x + Math.ceil(y * (x / 100))); }
else if ((y * (x / 100)) > 1) {
return (x + Math.round(y * (x / 100))); }
else {
return 0; } } }
var bar = document.getElementById("output");
bar.innerHTML = z; }
The problem is, when the else branch of the conditional statement tries to process the anonymous function, the return value isn't assigned; rather the entirety of the function as a string. That is, the following appears in the HTML page:
function (x, y) { if ((y * (x / 100)) < 1) { return (x + Math.ceil(y * (x / 100))); } else if ((y * (x / 100)) > 1) { return (x + Math.round(y * (x / 100))); } else { return 0; } }
I've tested the code in Chrome and Firefox and the result is the same.
Any help is appreciated and thank you in advance.
You need to call the function by passing it two arguments, because otherwise the z variable will just store a reference to this function but it will not evaluate it:
var z = (function(x, y) {
if ((y * (x / 100)) < 1) {
return (x + Math.ceil(y * (x / 100))); }
else if ((y * (x / 100)) > 1) {
return (x + Math.round(y * (x / 100))); }
else {
return 0;
}
})(x, y);
Note that (x, y) used inside the anonymous function are not the same as the one passed as arguments at the end which correspond to the two variables declared in the beginning of the foo function.

Categories