Why is this function creating an infinite looop? - javascript

The first function determines if a number is prime. The second function is supposed to create an array with all prime numbers up to and including the max value, but it gives me an infinite loop for some reason.
function isPrime(num) {
for (i = 2; i < num; i++) {
if (num % i === 0) {
return false
}
}
if (num <= 1) {
return false;
}
return true;
}
function primes(max) {
var all = [];
for (i = 2; i <= max; i++) {
if (isPrime(i)) {
all.push(i);
}
}
}
primes(17);

Your i variable is global, so both functions use the same i. This means the first function changes it while the second one is looping.
As the first function will have set i to num-1 when it finishes, and num was the value of i before executing it, it effectively decrements i with one. And so i will get the same value in the next iteration of the loop in the second function, never getting forward.
Solve this by putting the var keyword in both functions.
for(var i=2; // ...etc)

The variable i in your two loops are global variables and they overwrite each other so the first loop never ends.

In ur code problem is with the scope of variable i, In prime no calculation, u can check upto the sqrt of no, if no is not divisible by any no upto its sqrt, then it will a prime no, Try this:
function isPrime(num) {
let k = Math.sqrt(num);
for (let i = 2; i <= k; i++) {
if (num % i === 0) {
return false
}
}
return true;
}
function primes(max) {
let all = [];
for (let i = 2; i <= max; i++) {
if (isPrime(i)) {
all.push(i);
}
}
console.log(all)
}
primes(17);
primes(25);

Related

Does anyone know how I can return the prime numbers in the matrix?

I want to build a function to know how many prime numbers there are in my matrix (5) and I want to return the quantity - 5
Can anyone understand where my mistakes are? At the end there is a mistake for sure, because I was unable to return the quantity
let matrix = [ [50,17], [19,20,6,40,14], [97] ,[31,9,5] ];
let counter = 0
for(let row = 0 ; row < matrix.length ; row++){
for(let col = 0 ; col < matrix[row].length ;col++){
function matrixPrimeNumbers(num){
for(let d = 2 ; d<= num -1 ; d++) {
if(num % d == 0){
return false;
}
num++;
return num.charAt();
}
}
}
}
There are many issues:
The function matrixPrimeNumbers is never executed. In your nested loop, you do nothing else then define the same function over and over again. The function is never invoked.
The function itself has a disfunctional loop: on the very first iteration of that loop, it will exit at the return statement. So there is actually no looping.
Calling num.charAt() is ... strange? charAt is a string method, and returns a character. Why would you want to call it on a number, and what does that have to do with finding a prime? Elsewhere you have return false, so presumably you want the function to return a boolean. True when num is prime, and false when it is not. So after the loop finishes, just add return true.
num++; is wrong. You want to determine whether num is a prime, so you should not change its value during the loop. Probably you intended to do counter++;, but it is placed at the wrong spot. This should only be done when you are certain there is no divisor, and so it should be placed after the loop. Better still, it should happen outside the function, after a call of that function.
You say you want to "return the quantity". But you never return the counter. In order to return something, you need a function for it. So wrap most of the code into a function, and let it return the counter;
It is OK to have a function for detecting whether num is a prime, but then name it accordingly, like isPrime. Use the name matrixPrimeNumbers for the main function that will do the nested looping over the matrix. I would even change the name to something more telling: countMatrixPrimeNumbers.
It is not necessary for prime detection to loop to num-1. You can stop at the square root of num.
Integers that are 1 or less are not considered primes, so you should deal with that case.
So here is a correction:
let matrix = [ [50,17], [19,20,6,40,14], [97] ,[31,9,5] ];
// Define functions at the top level, not inside for-loops
function isPrime(num) {
if (num <= 1) return false;
let root = Math.sqrt(num);
for (let d = 2; d <= root; d++) {
if (num % d == 0) {
return false;
}
}
return true;
}
function countMatrixPrimeNumbers(matrix) {
let counter = 0
for (let row = 0; row < matrix.length; row++) {
for (let col = 0; col < matrix[row].length; col++) {
if (isPrime(matrix[row][col])) {
counter++;
}
}
}
return counter;
}
// call it:
console.log(countMatrixPrimeNumbers(matrix));
First of all, you should not declare a function in a for loop. I don't think that this throw an error but with some text editor, it probably shows a warning.
You can modify this method (in ES6 syntax) to check if anumber is a prime number, and returns (0 or 1) instead of (true or false).
// This method returns 1 if the number is a prime number, else return 0
const isPrime = num => {
for(let i = 2, s = Math.sqrt(num); i <= s; i++)
if(num % i === 0) return 0; // Not a prime number, return 0
return ( (num > 1) ? 1 : 0 ); // Return 1 if num > 1, else return 0
}
You can now use the isPrime function in your code like this :
let matrix = [ [50,17], [19,20,6,40,14], [97] ,[31,9,5] ];
let counter = 0
for(let row = 0 ; row < matrix.length ; row++){
// Counter will increase if isPrime returns 1
for(let col = 0 ; col < matrix[row].length ;col++)
counter += isPrime(matrix[row][col])
}
console.log(counter); // Should show in console how many prime numbesr you have in the matrix

Variable for loop

If reverse == true I want to run one kind of loop, else I want to run another one.
Currently, here is an example of my code:
if (reverse) {
for (var i = 0; i < length; i++) {
...
}
} else {
for (var i = length; i >= 0; i--) {
...
}
}
The code inside is really big, and is quite the same. I could use a function, but this function would have so many params that is not a good choice.
So I've tried to do something like that:
var loopStart1 = startPageIndex;
if (!reverse) {
condition1 = function(i) {
return i < length;
}
increment1 = function(i) {
return ++i;
}
} else {
condition1 = function(i) {
return i >= 0;
}
increment1 = function(i) {
return i--;
}
}
mainLoop: for (var i = loopStart1; condition1(i); increment1(i)) {
But now I have an infinite loop.
Any idea on how to solve this issue?
Why not do it inline?! ;)
var start = startPageIndex;
for (var i = start; (reverse && i >= 0) || (!reverse && i < length); reverse ? --i : ++i) { }
Assuming the specific case is to traverse through an array either backwards or forwards, there are two simple ways to do that.
1) Just conditionally reverse the array before looping, or
2) Use a single loop but conditionally map the loop variable to something else. Something like...
for (var i = 0; i < length; i++) {
var j = i;
if (reverse) {
j = length - (i + 1);
}
// ...then use j instead of i
}
If you want to make it dynamic, I wouldn't use a for loop, but a do..while loop to be easier to customize.
Your main function would just have a simple reverse bool flag and you could just pass that.
Inside that function that you want to depend on the reverse flag, you can use the ternary expression in the condition (x ? y : z)
Makes it clearer to read. In theory you can do it in a for loop directly, using two ternary directions.
do {
//Your actions here, using i as counter
//Here you will do the counter direction change
if(reverse)
i--;
else
i++;
// Use ternary expression if (x ? y : z) in the while condition
// Reads as: If x is true, do y, else do z
// All in one line
} while(reverse ? i>=0 : i<n);
Ideally, in these situations I would consider using iterators.
How about a simple loop function,
Below I've created a simple function called myLoop, were you can pass the length, if it's reversed, and what callback you want for each loop iteration.
eg.
function myLoop(length, reverse, each) {
var index;
if (!reverse) {
for (index = 0; index < length; index ++) each(index);
} else {
for (index = length -1; index >= 0; index --) each(index);
}
}
function show(index) {
console.log("Loop index = " + index);
}
console.log("forward");
myLoop(5, false, show); //normal
console.log("revere");
myLoop(5, true, show); //reversed
I would opt for the same code, just change the array.
var array = ['one', 'two', 'three'];
var reversed = true;
let arrToUse = reversed ? array.reverse() : array;
for (var i = 0; i < arrToUse.length; i++) {
console.log(arrToUse[i]);
}
Check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions
Primitive parameters (such as a number) are passed to functions by value; the value is passed to the function, but if the function changes the value of the parameter, this change is not reflected globally or in the calling function.
This is what happens when you call increment1(i), outer i in for loop is not changed. To fix it just set i from increment1(i)'s return value.
mainLoop: for (var i = loopStart1; condition1(i); i = increment1(i)) {

Factorize function javascript

I am having a little issue writing a function that factorizes numbers. The hard part is done. However I cannot seem to tell the function to return 1 when num is 0.
PS: which other ways would you write the same function in JavaScript?
var arrOfNum = [];
function factorialize(num) {
for(i = 1; i <= num; i++){
// push all numbers to array
arrOfNum.push(i);
}
// multiply each element of array
var result = arrOfNum.reduce(function(a,b){
return a * b;
});
console.log(result);
}
You already have a for loop, in which you can calculate the factorial at once, without array and reduce.
function factorial(num) {
var result = 1;
for(i = 2; i <= num; i++) {
result *= i;
}
return result;
}
You can use the following method that uses the recursion:
function factorize(num){
if(num === 0){
return 1 ;
}
else {
return num = num * factorize(num-1);
}
}
Roundup:
Declaration of local variable i is missing
var i;
Declaration of other used variables are over the function distributed. A better way is to declare the variables at top of the function.
Array#reduce needs for this task an initialValue as the second parameter.
The first time the callback is called, previousValue and currentValue can be one of two values. If initialValue is provided in the call to reduce, then previousValue will be equal to initialValue and currentValue will be equal to the first value in the array. If no initialValue was provided, then previousValue will be equal to the first value in the array and currentValue will be equal to the second.
function factorial(num) {
var i,
arrOfNum = [],
result;
for (i = 1; i <= num; i++) {
// push all numbers to array
arrOfNum.push(i);
}
// multiply each element of array
result = arrOfNum.reduce(function (a, b) {
return a * b;
}, 1);
document.write(num+'! = '+result + '<br>');
}
factorial(0);
factorial(1);
factorial(2);
factorial(5);
factorial(8);
Simply return the value 1
function factorialize(num) {
if (num < 1) return 1; //this line is added
for(i = 1; i <= num; i++){
arrOfNum.push(i);
}
var result = arrOfNum.reduce(function(a,b){
return a * b;
});
console.log(result);
}
If you give reduce an initial value of 1, everything will work fine even without an explicit check:
var result = arrOfNum.reduce(function(a,b){
return a * b;
}, 1);
^^^ // PROVIDE EXPLICIT INITIAL VALUE TO REDUCE
function factorial(n) {
return Array.apply(0, Array(n)).reduce(function(x, y, z) {
return x + x * z; //1+(1*0), 1+(1*1),2+(2*2), 6+(6*3), 24+(24*4), ...
}, 1);
}
DEMO
Here's a fairly streamlined function that returns an array of all factors of 'n'
You only need to look at candidates < sqrt(n)
For those of you who don't know the | 0; bit when getting sqrt(n) is a faster equivalent of Math.floor()
As factn is defined after some sanity checking the function will either return undefined or an array which is easy to check with something like if(factors = factorize(n) { success code } sorta structure
There are improvements that can be made to this but they're complex and were beyond the requirements when I wrote it - specifically I used this to calculate CSS sprite sizes from a large image by using factorize on the x + y dimensions of an image then creating a third array of shared factors (which gives you a list of all the possible square sprite sizes).
function factorize(n) {
n = Number(n);
if(n) {
if(n > 1) {
var sqrtn = Math.sqrt(n) | 0;
var factn = [1, n];
var ipos = 0;
for(i = 2; i <= sqrtn; i++) {
if((n % i) == 0) {
ipos++;
if((n / i) !== i) {
factn.splice(ipos, 0, i, n / i);
} else {
factn.splice(ipos, 0, i);
}
}
}
}
}
return factn;
}
Don't know why there are complicated answers. A very simple answer is:
var i;
function factorialOf(num) {
//Initially set factorial as number
var factorial = num;
//A for loop starting with 1 and running the times equal to num
for (i = 1; i < num; i++) {
//Set factorial to the number itself * i
factorial = factorial * i;
}
//Return factorial
return factorial;
}
console.log(factorialOf(5));

Prime Factor Calculator JS - Can't find infinite loop

So I was trying to go back over my problem solving abilities and wanted to redo my prime factor calculator. Code refactoring, more efficient, etc as I was a beginner at JS when I made it.
In recreating it I have come across a rather large issue - an infinite loop. Now, I've broken down my function into different parts and called them separately - they work fine. The main function itself even works fine, so long as the number is 10 or less. But for some reason whenever I call the function with a parameter greater than 10 there is an infinite loop.
I'm sorry if the answer is glaringly obvious, it's quite late at night. I just can't seem to spot it.
The plain code is here:
var findPrimeFactors = function (number) {
var isPrime = function (number) {
var primes = [];
for (i = 2; i < number; i++) {
if (number % i === 0) {
return false;
}
}
primes.push(number);
return primes;
};
var findFactors = function (number) {
var factors = [];
for (i = 2; i < number; i++) {
if (number % i === 0) {
factors.push(i);
}
}
return factors;
};
var factors = findFactors(number);
var primes = [];
for (i = 0; i < factors.length; i++) {
primes += isPrime(factors[i]);
}
return primes;
};
console.log(findPrimeFactors(10));
The fiddle for the code is here: https://jsfiddle.net/uk26q4ff/
Thanks everyone!
Likely you are hitting this because in each function you aren't declaring i so it is using it from the global scope.
I found a couple of bugs.
Your isPrime function should return either true or false, not an array
the loop in findFactors should include the 'number' value (changed < to <=)
The infinite loops was cause by using the same variable i in every
loop.
Finally I changed the following I changed the following line
at the end: if (isPrime(factors[k])) primes.push(factors[k]);
Here is how I would do it:
var findPrimeFactors = function (number) {
var isPrime = function (number) {
var primes = [];
for (i = 2; i < number; i++) {
if (number % i === 0) {
return false;
}
}
//primes.push(number);
//return primes;
return true;
};
var findFactors = function (number) {
var factors = [];
for (j = 2; j <= number; j++) {
if (number % j === 0) {
factors.push(j);
}
}
return factors;
};
var factors = findFactors(number);
var primes = [];
for (k = 0; k < factors.length; k++) {
//primes += isPrime(factors[k]);
if (isPrime(factors[k])) primes.push(factors[k]);
}
return primes;
};
console.log(findPrimeFactors(37));

Euler 7 Javascript

Can someone help with this code? It's supposed to get the 10,001th prime number. I know the is_prime function works to test if a number is prime since I successfully utilized this code for a previous problem. Now I'm just trying to call that in a for loop until counter hits what I want, while storing the most recent number into a variable 'holder' and printing holder at the end.
function is_prime(num) {
if (isNaN(num)) return false;
for (var i=2; i<=Math.sqrt(num); i++) {
if (num % i === 0) {
return false;
}
}
return true;
}
function getBigPrime () {
var holder = 0;
var counter = 0;
for (var k=3; counter<=10000; k+=2) {
if (is_prime(k))
holder = k;
counter += 1;
}
console.log(holder);
}
getBigPrime();
If you omit the brackets for an if block, only the first line will actually be part of your block. Your current if statement behaves like this:
if (is_prime(k)) {
holder = k;
}
counter += 1;
Also, your loop skips 2, the first prime number.
You have a scoping error with counter.
For your for loop you can initialize counter = 1; to account for 2 and leave as is
http://jsfiddle.net/XtTYm/2/
function is_prime(num) {
if (isNaN(num)) return false;
var sq = Math.sqrt(num);
for (var i=2; i<=sq; i++) {
if (num % i === 0) {
return false;
}
}
return true;
}
function getBigPrime () {
var holder = 0;
var counter = 1;
for (var k=3; counter<=10000; k+=2) {
if (is_prime(k)){
holder = k;
counter += 1; // should be inside the if
}
}
console.log(holder);
}
getBigPrime();

Categories