Why is this code looping infinitely? - javascript

I'm trying to write a program in JavaScript that generates 100 random numbers and checks the primality of each. The program does just that, except for some reason it doesn't stop at 100 and just loops infinitely. I'm sure I made some simple novice mistake, but for some reason I can't see it. Any advice?
My code:
function isPrime(n) {
if (n < 2 || n % 1)
return false;
var r = Math.sqrt(n);
for (i = 2; i <= r; i++)
if (n % i === 0)
return false;
return true;
}
for (i = 0; i < 100; i++) {
var temp = Math.floor((Math.random() * 100) + 1);
if (isPrime(temp))
console.log(temp + " is a prime number!");
else
console.log(temp + " is not a prime number.");
}
Thanks!

You need to declare i variable in for-loops:
(var i = 0; i < 100; i++) ...
otherwise it is defined in global scope and it is shared between for-loop and isPrime function.

madox2 is correct that you should declare i in the for loop, however I think the reason the loop itself is infinite is because by only doing i=0 in the loop, and then for (i = 2; i <= r; i++) in the function the loop calls, you are resetting i every iteration
You should change your code to declare i within the scope of both loops separately, like so:
function isPrime(n) {
if (n < 2 || n % 1)
return false;
var r = Math.sqrt(n);
for (var i = 2; i <= r; i++)
if (n % i === 0)
return false;
return true;
}
for (var i = 0; i < 100; i++) {
var temp = Math.floor((Math.random() * 100) + 1);
if (isPrime(temp))
console.log(temp + " is a prime number!");
else
console.log(temp + " is not a prime number.");
}

Related

for loops with and without block statements

I looked for a function to determine if a number is prime and found this
for (var i = 2; i <= Math.sqrt(num); i++)
if (num % i === 0) {
return false;
}
return true;
and I don't understand why that works, yet this doesn't
for (var i = 2; i <= Math.sqrt(num); i++) {
if (num % i === 0) {
return false;
}
return true;
}
What is it about the (lack of the) block statement that is functioning differently
Your first code looks like this:
for (var i = 2; i <= Math.sqrt(num); i++){
if (num % i === 0) {
return false;
}
}
return true;
Notice how return true is on the outside. Your second code doesn't work because it prematurely returns true when there are more numbers to check. Your entire for loop is equivalent to
return num % 2 !== 0;
which is clearly incorrect.
Let me tell you something about blocks that you might not have known (It took me a while to discover this at least).
When you use a loop or if-else statement, you can ignore the using braces { and }.
Example 1
if (a === b){
c = 0;
}
is actually the same as
if (a === b)
c = 0;
Example 2
for (i = 0; i < 10; i++){
a += 1;
}
is actually the same as
for (i = 0; i < 10; i++)
a += 1;
However 1
if (a === b){
c = 0;
d = 1;
}
is not the same with
if (a === b)
c = 0;
d = 1;
However 2
for (i = 0; i < 10; i++){
a += 1;
b += 1;
}
is not the same with
for (i = 0; i < 10; i++)
a += 1;
b += 1;
Explanation
In loops and if-else statement, the block statement (codes surrounded by { and } groups the codes within it and execute it.
However, in the absence of { and }, the loops or if-else statement will only execute the single line of code after it.
Meaning,
var a = 0,
b = 0;
for (i = 0; i < 10; i++)
a += 1;
b += 1;
In this case, a === 10 but b === 1.
Also, in the following case,
var a = 0,
b = 0;
if (false)
a = 10;
b = 10;
a === 0 but b === 10.

Finding sequence of prime numbers with JS

I have to get a sequence of prime numbers. But my code does not work. How is it possible to fix it?
var num1 = parseInt(prompt('Enter a number'));
var num2 = parseInt(prompt('Enter a number'));
var num3 = 0;
function primeSeq(num1, num2) {
var b = 1;
var c = '';
if (num1 > num2) {
num3 = num2;
num2 = num1;
num1 = num3;
}
for (var i = num1; i < num2; i++) {
for (var j = 2; j < i; j++) {
if (i % j == 0) {
b++;
}
if (b <= 1) {
c += i + ' ';
}
}
}
return c;
}
alert(primeSeq(num1, num2));
I guess you wanted something like this
var num1 = parseInt(prompt('Enter a number'));
var num2 = parseInt(prompt('Enter a number'));
var num3 = 0;
if (num1 > num2) {
num3 = num2;
num2 = num1;
num1 = num3;
}
function primeSeq(num1, num2) {
var b;
var c = '';
for (var i = num1; i < num2; i++) {
b = 1;
for (var j = 2; j < i; j++) {
if (i % j === 0) {
b++;
}
}
if (b === 1) {
c += i + ' ';
}
}
return c;
}
alert(primeSeq(num1, num2));
So in short, b should reset to 1 on every new prime candidate (i loop) and check of b should be outside of inner (j) loop.
Please note that there are more optimal algorithms.
The lot easier way is to use a sieve system, if a number is divisible by another prime number it is not a prime. You can write a function like this:
function primes(max) {
let primes = [2];
for (let i = 3; i <= max; i++) {
let found = true;
for (let j = 0; j < primes.length; j++) {
if (i % primes[j] == 0) found = false;
}
if (found) primes.push(i);
}
return primes;
}
Explanation
What you know by default is that 2 is a prime, so you start at 3. You don't want to exeed the max, that is the i <= max statement. Assume it is a prime, then search in the array if it is divisible by primes you found before, if that is the case, set found to false.
Now check if is was found, push is to the array and return the primes.
Here is bit more optimized algorithm:
function primeSeq(num1, num2) {
var primes = [];
var isPrime;
var j;
var results = [];
for (var i = 2; i < num2; i++) {
isPrime = true;
j = 0;
while (j < primes.length) {
if (i % primes[j] === 0) {
isPrime = false;
break;
}
j++;
}
if (isPrime) {
primes.push(i);
if (i >= num1) {
results.push(i);
}
}
}
return results.join(' ');
}
In order for number to be prime it must not be dividable with all the smaller primes, so we are generating an array of primes to check upon.
There is a theory also that every prime bigger than 3 has a following form:
6k+1 or 6k-1
So this would simplify it bit more.
Try this one
<input ng-model="range" type="number" placeholder="Enter the range">
<button ng-click="findPrimeNumber(range)">
$scope.findPrimeNumber=function(range){
var tempArray=[];
for(var i=0;i<=range;i++){
tempArray.push(i)
}
var primenumbers= tempArray.filter((number) => {
for (var i = 2; i <= Math.sqrt($scope.range); i++) {
if (number % i === 0) return false;
}
return true;
});
console.log(primenumbers);
}

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
}
*/

Factorialize a Number

I'm taking the freecodecamp course one of the exercises it's to create a Factorialize function, I know there is several ways to do it just not sure what this one keeps returning 5
function factorialize(num) {
var myMax = num;
var myCounter = 1;
var myTotal = 0;
for (i = 0; i>= myMax; i++) {
num = myCounter * (myCounter + 1);
myCounter++;
}
return num;
}
factorialize(5);
This is a recursive solution of your problem:
function factorialize(num) {
if(num <= 1) {
return num
} else {
return num * factorialize(num-1)
}
}
factorialize(5)
This is the iterative solution:
function factorialize(num) {
var cnt = 1;
for (var i = 1; i <= num ; i++) {
cnt *= i;
}
return cnt;
}
factorialize(5)
with argument 5, it will return the 5! or 120.
To answer your question, why your function is returning 5:
Your function never reaches the inner part of the for-loop because your testing if i is greater than myMax instead of less than.
So you are just returning your input parameter which is five.
But the loop does not calculate the factorial of num, it only multiplies (num+1) with (num+2);
My solution in compliance with convention for empty product
function factorializer(int) {
if (int <= 1) {
return 1;
} else {
return int * factorializer(int - 1);
}
}
Here is another way to solve this challenge and I know it is neither the shortest nor the easiest but it is still a valid way.
function factorialiaze(num){
var myArr = []; //declaring an array.
if(num === 0 || num === 1){
return 1;
}
if (num < 0){ //for negative numbers.
return "N/A";
}
for (var i = 1; i <= num; i++){ // creating an array.
myArr.push(i);
}
// Reducing myArr to a single value via .reduce:
num = myArr.reduce(function(a,b){
return a * b;
});
return num;
}
factorialiaze(5);
Maybe you consider another approach.
This solution features a very short - cut to show what is possible to get with an recursive style and a implicit type conversion:
function f(n) { return +!~-n || n * f(n - 1); }
+ convert to number
! not
~ not bitwise
- negative
function f(n) { return +!~-n || n * f(n - 1); }
var i;
for (i = 1; i < 20; i++) {
console.log(f(i));
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
Try this function
const factorialize = (num) => num === 0 ? 1 : num * factorialize(num-1)
Use it like this:
factorialize(5) // returns 120
Try this :
function factorialize(num) {
var value = 1;
if(num === 1 || num ===0) {
return value;
} else {
for(var i = 1; i<num; i++) {
value *= i;
}
return num * value;
}
}
factorialize(5);
// My solution
const factorialize = num => {
let newNum = 1;
for (let i = 1; i <= num; i++) {
newNum *= i
}
return newNum;
}
I love syntactic sugar, so
let factorialize = num => num <= 1 ? num : num * factorialize(num -1)
factorialize(5)

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