const input = 3;
let isPrime = true;
outer: for(let i = 2; i < input; i++){
for(let j = 2; j < input; j++) {
if((i * j) === input) {
isPrime = false;
console.log(`${input} is Not a prime number`);
break outer;
}
}
}
if(isPrime) {
console.log(`${input} is a prime number`); }
Personally, I think this is not the right way, even though I could've done it in an easier way, I approached the problem like so.
I needed some feedback from my seniors, can I get a code review?
Nested loops are mostly time consuming solutions. If you have an other option you need to probably do that. In this case you using nested for loops to determine prime number. But you can do it with only one for loop.
const number = 3
let isPrime = true;
// check if number is equal to 1
if (number === 1) {
console.log("1 is neither prime nor composite number.");
}
// check if number is greater than 1
else if (number > 1) {
for (let i = 2; i <= Math.sqrt(number); i++) {
if (number % i == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
console.log(`${number} is a prime number`);
} else {
console.log(`${number} is a not prime number`);
}
}
For more information you can check these links:
Why nested loops are bad practice
Finding a prime number
Related
I am trying to make a javaScript function to check the prime number. It's perfectly working for lot of all the numbers I've tested but only comes wrong output when the value is 9.
Could you please anyone check below code and advise?
const primeDetector = function (inputNumber) {
if (inputNumber < 1) {
console.log("Your input is not a prime");
}
if (inputNumber === 1) {
console.log("Your input is Neither prime nor composite");
}
if (inputNumber === 2) {
console.log(`${inputNumber} is a prime number`);
} else if (inputNumber > 2) {
for (var i = 2; i < inputNumber; i++) {
if (inputNumber % i == 0) {
console.log(`${inputNumber} is NOT a prime number`);
break;
} else {
console.log(`${inputNumber} is a PRIME number`);
break;
}
}
}
};
primeDetector();
As far as I can tell your function only checks if a number is even or odd, because you break the loop instantly. You are just checking i=2.
The problem is that you are forgetting that you are doing your check in a loop. You treat it as if it is not in a loop:
for (var i = 2; i < inputNumber; i++) {
if (inputNumber % i == 0) {
console.log(`${inputNumber} is NOT a prime number`);
break;
} else {
console.log(`${inputNumber} is maybe a PRIME number, if I don't say it is not a prime number at the end then it is PRIME, right now I'm not sure yet`);
// break; // <-- this break is the bug
}
}
Remember, this is a loop. If the number is not divisible by i then it does NOT mean it is a prime but it just means you have not tested with all the values of i yet. You still need to complete the loop to test all the values of i.
If you want to only print one message when it is a prime you need to remember if you have passed the test or not. In programming, remembering means using memory and using memory means using a variable:
var is_prime = true;
for (var i = 2; i < inputNumber; i++) {
if (inputNumber % i == 0) {
console.log(`${inputNumber} is NOT a prime number`);
is_prime = false;
break;
}
}
// We only know if the number is a prime HERE
// not inside the loop above
if (is_prime) {
console.log(`${inputNumber} is PRIME`);
}
The logic of the loop is very simple. Iterate from i = 2 until i = inputNumber - 1, see if inputNumber is divisible by i. If yes, definitely not a prime number. If no, keep going until we are sure it is not divisible by ANY of i in that range.
const primeDetector = function (inputNumber) {
let isPrime = true;
if (inputNumber < 1) {
console.log("Your input is not a prime");
isPrime = false;
}
if (inputNumber === 1) {
console.log("Your input is Neither prime nor composite");
isPrime = false;
}
if (inputNumber === 2) {
console.log(`${inputNumber} is a prime number`);
isPrime = true;
} else if (inputNumber > 2) {
for (var i = 2; i < inputNumber; i++) {
console.log(`Checking if ${inputNumber} is divisible by ${i}`);
if (inputNumber % i == 0) {
console.log(`Opps. ${inputNumber} is divisible by ${i}. ${inputNumber} is then NOT a prime number`);
isPrime = false;
break; // Found one divisible, definitely not a prime number. No need to continue, just exit the loop
} else {
console.log(`${inputNumber} is not divisible by ${i}. Maybe a prime number. Wail till end ya`);
// break;
}
}
isPrime? console.log(`${inputNumber} is a prime number`) : console.log(`${inputNumber} is not a prime number`);
}
};
primeDetector(9);
primeDetector(11);
function isPrime(n) {
if (n == 1 ) {
return (`${n} is niether a prime number nor composite number`)
}
else if( n < 1){
return (`${n} is not a prime number`)
}
else{
for (let i = 2; i < n; i++) {
if( n % 2 == 0){
return result = `${n} is not a prime number`
break;
}
else{
return result = `${n} is a prime number`
}
}
}
}
console.log(isPrime(15))
I write a function to find the prime number , but it's not working because I'm not able to break the loop
Although answer by Dave addresses the question I would suggest this stack overflow answer as an better alternative.
https://stackoverflow.com/a/38643868/10738743
There are two glitches preventing your function working as intended.
the loop which tests for primeness is repeating n%2 on each iteration, which will evaluate the same, regardless of the value of i in the loop. Instead, you should be testing to see whether n%i is true.
With that fixed, the final return (which only happens if all non-prime conditions have been rejected with earlier returns) should be outside of any block as it becomes the default return value.
your code functions fine with the minor changes suggested above incorporated:
function isPrime(n) {
if (n == 1 ) {
return (`${n} is niether a prime number nor composite number`);
}
else if( n < 1){
return (`${n} is not a prime number`)
}
else {
for (let i = 2; i < n; i++) {
if( n % i == 0){
return result = `${n} is not a prime number`
// break; // (return breaks anyway)
} // end if
}// end for i;
} // end else
return result = `${n} is a prime number`; // default after no earlier rejection
}
console.log(isPrime(15));
how come the following is not accurately logging whether a number is prime or not?
function isPrime2(num) {
for(let i = 2; i < num; i++) {
if(num % i === 0) {
return console.log(false); break;
} else{return console.log(true)}
}
}
isPrime2(33)returns true, even though it is a prime number.
If i = 2, then the console will log true since 33/2 = 16.5
But since the loop isn't over, the next i value is i=3,
so shouldn't the console log false and then break out of the loop completely, leaving the final answer to be false?
There are two problems here.
Your logic is broken
function isPrime2(num) {
for (let i = 2; i < num; i++) {
const remainder = num % i;
console.log({
remainder
});
if (remainder === 0) {
return console.log(false);
break;
} else {
return console.log(true)
}
}
}
isPrime2(33);
i starts at 2.
if(num % i === 0) is false, so we go to else
else{return console.log(true)} causes it to log true and exit the function.
Your failure condition is triggered when the first test fails instead of waiting for the loop to finish with a success condition for any of the tests.
33 is not a prime
It is divisible by 3 and 11.
function isPrime2(num) {
for (let i = 2; i < num; i++) {
const remainder = num % i;
console.log({
remainder
});
if (remainder === 0) {
return console.log(false);
break;
}
}
return console.log(true)
}
isPrime2(33);
I'm trying to complete an algorithm challenge to find the largest prime factor of 600851475143. I'm not necessarily asking for the answer. Just trying to figure out why this code isn't working. Why does it return 'undefined' instead of a number?
let isPrime = n => {
let div = n - 1;
while (div > 1) {
if (n % div == 0) return false;
div--;
}
return true;
};
let primeFactor = x => {
for (let i = Math.floor(x / 2); i > 1; i--) {
if (x % i == 0 && isPrime(i) == true) {
return i;
}
}
};
console.log(primeFactor(35)); // 7
console.log(primeFactor(13195)); // 29
console.log(primeFactor(600851475143)); // undefined
The problem is not your algorithm it is perfectly valid, check the below slightly modified algorithm, all I've done is replaced your starting point Math.floor(x/2) with a parameter that you can choose:
let isPrime = n => {
let div = n - 1;
while (div > 1) {
if (n % div == 0) return false;
div--;
}
return true;
};
function primeFactor(x, n){
for (let i = n; i > 1; i--) {
if (x % i == 0 && isPrime(i) == true) {
return i;
}
}
}
console.log(primeFactor(35, 35));
console.log(primeFactor(13195, 13195));
console.log(primeFactor(600851475143, 100000))
Using the above you'll get an answer that proves your implementation works, but the loop is too big to do the entire thing(i.e. from Math.floor(600851475143/2)). Say your computer can do 500million loops per second, going through every one from 300,425,737,571 down to 1 would take 167 hours, even at 5 billion loops per second it would take 16 and a half hours. Your method is extremely inefficient but will return the correct answer. The reason you're not getting an answer on JSBin is more likely to do with browser/service limitations.
Spoilers on more efficient solution below
The following implementation uses a prime sieve(Sieve of Eratosthenes) in order to generate any list of primes requested and then checks if they fully factor into the given number, as long as you use a large enough list of primes, this will work exactly as intended. it should be noted that because it generates a large list of primes it can take some time if ran incorrectly, a single list of primes should be generated and used for all calls below, and the cached list of primes will pay off eventually by having to perform less calculations later on:
function genPrimes(n){
primes = new Uint32Array(n+1);
primes.fill(1)
for(var i = 2; i < Math.sqrt(n); i++){
if(primes[i]){
for(var j = 2*i; j < n; j+=i){
primes[j] = 0;
}
}
}
primeVals = []
for(var i = 2; i < primes.length; i++){
if(primes[i]){
primeVals.push(i);
}
}
return primeVals;
}
function primeFactor(x, primes){
var c = x < primes.length ? x : primes.length
for (var i = c; i > 1; i--) {
if(x % primes[i] == 0){
return primes[i];
}
}
}
primes = genPrimes(15487457);
console.log(primeFactor(35, primes));
console.log(primeFactor(13195, primes));
console.log(primeFactor(600851475143, primes));
console.log(primeFactor(30974914,primes));
let primeFactor = x => {
if (x === 1 || x === 2) {
return x;
}
while (x % 2 === 0) {
x /= 2;
}
if (x === 1) {
return 2;
}
let max = 0;
for (let i = 3; i <= Math.sqrt(x); i += 2) {
while (x % i === 0) {
x /= i;
max = Math.max(i, max);
}
}
if (x > 2) {
max = Math.max(x, max);
}
return max;
};
console.log(primeFactor(35));
console.log(primeFactor(13195));
console.log(primeFactor(27));
console.log(primeFactor(1024));
console.log(primeFactor(30974914));
console.log(primeFactor(600851475143));
Optimizations
Dividing the number by 2 until it's odd since no even number is prime.
The iteration increment is 2 rather than 1 to skip all even numbers.
The iteration stops at sqrt(x). The explanation for that is here.
var sum = 0
for (i = 0; i < 250; i++) {
function checkIfPrime() {
for (factor = 2; factor < i; factor++) {
if (i % factor = 0) {
sum = sum;
}
else {
sum += factor;
}
}
}
}
document.write(sum);
I am trying to check for the sum of all the prime numbers under 250. I am getting an error saying that i is invalid in the statement if (i % factor = 0) I know was creating in the original for statement, but is there any way to reference it in the if statement?
With the prime computation, have you considered using Sieve of Eratosthenes? This is a much more elegant way of determining primes, and, summing the result is simple.
var sieve = new Array();
var maxcount = 250;
var maxsieve = 10000;
// Build the Sieve, marking all numbers as possible prime.
for (var i = 2; i < maxsieve; i++)
sieve[i] = 1;
// Use the Sieve to find primes and count them as they are found.
var primes = [ ];
var sum = 0;
for (var prime = 2; prime < maxsieve && primes.length < maxcount; prime++)
{
if (!sieve[prime]) continue;
primes.push(prime); // found a prime, save it
sum += prime;
for (var i = prime * 2; i < maxsieve; i += prime)
sieve[i] = 0; // mark all multiples as non prime
}
document.getElementById("result").value =
"primes: " + primes.join(" ") + "\n"
+ "count: " + primes.length + "\n"
+ "sum: " + sum + "\n";
#result {
width:100%;
height:180px
}
<textarea id="result">
</textarea>
(EDIT) With the updated algorithm, there are now two max involved:
maxcount is the maximum number of prime numbers you wish to find
maxsieve is a guess of sieve large enough to contain maxcount primes
You will have to validate this by actually checking the real count since there are two terminating conditions (1) we hit the limit of our sieve and cannot find any more primes, or (2) we actually found what we're looking for.
If you were to increase the number to numbers much greater than 250, than the Sieve no longer becomes viable as it would be consume great deals of memory. Anyhow, I think this all makes sense right? You really need to play with the Sieve yourself at this point than rely on my interpretation of it.
You can equally use this
let sum = 0;
let num = 250;
for (let i = 2; i < num; i++) {
let isPrime = true;
for (let j = 2; j < i; j++) {
if (i % j === 0) {
isPrime = false;
}
}
if (isPrime) {
sum += i;
}
}
console.log(sum);
i % factor === 0
Use === for comparison. = is for assignment. Yeah I said triple equals. Type coercion is annoying.
You need a == or ===: if (i % factor == 0)
Here's a pretty decent way to do it. It's not as advanced as the sieve but it's a decent starting point. NOTE: I'm using ES6 syntax.
/*
* Sum the first n prime numbers
*
* #param n (integer)
* #return integer
*
*/
function sumNprimes(n){
const arr = [];
let i = 2
while (arr.length < n) {
if (isPrime(i)) {
arr.push(i)
}
i++
}
return arr.reduce( (x,y) => x+y );
/*
* #param n (integer)
* #return Boolean
*
*/
function isPrime(n) {
if ( n < 2 ) {
return false
}
for ( let i = 2; i <= Math.sqrt(n); i++ ) {
if ( n % i === 0 ) {
return false;
}
}
return true
}
}
So i had to face a similar challenge and here is my solution, i hope you find it helpful:
function sumPrimes(num) {
// determine if a number is prime
function isPrime(n) {
if (n === 2) return true;
if (n === 3) return true;
if (n % 2 === 0) return false;
if (n % 3 === 0) return false;
var i = 5;
var w = 2;
while (i * i <= n) {
if (n % i === 0) {
return false;
}
i += w;
w = 6 - w;
}
return true;
}
// subtract 1 for 'not being prime' in my context
var sum = isPrime(num) ? num - 1 : -1;
for (var x = 0; x < num; x++) {
if (isPrime(x) === true) {
sum += x;
}
}
return sum;
}
As per the "Sieve of Eratosthenes", I have implemented the code using JS:
function isPrime(n){
return ((n/2 === 1 || n/3 === 1 || n/5 === 1 || n/7 === 1)?true:(n%2===0 || n%3 === 0 || n%5 ===0 || n%7 === 0)?false:true);
};
var val = 250;
let outArr = [];
for(let i=2;i<val;i++){
if(isPrime(i)){
outArr.push(i);
}
}
console.log("Prime number between 0 - "+val+" : "+outArr.join(","));
Here is a simple way of looping through array and implementing the sieve of Eratosthenes...
function sumPrimes(num) {
var t, v = [],
w = [],
x = [],
y = [],
z = 0;
//enumerating Vee array starts at 2 as first prime number
for (let a = 2; a <= num; a++) {
v.push(a)
}
//creating a moving loop by splicing its first index
for (let i = 0; i < v.length; i) { //ensure all items spliced
t = v[i]; // t as prime to be removed from Vee array
x.push(t); // x storage of primes
z += t // total of peculiar primes
w.push(v.splice(i, 1)) //tested to move all one by one
// prompt(v) //tested that v loses its v[i] every iteration
//= now trying to remove others using remainder (%) vs prime t
for (let vi in v) {
v[vi] % t === 0 ? y.push(v.splice(vi, 1)) : ""; //recursive removal of composite items by prime t
}
}
return z // returns sum of primes
}
sumPrimes(250);
You generate the array beginning with 2 as first prime,
You sieve the array removing items by the remainder of prime using % === 0.
The you loop through the remaining array by using the next prime until the last remaining prime is pushed to the prime arrays. Add all primes to get the Sum.
If the question is purely academical, earlier answers are better suited.
The example below uses modern libraries, in case you need an efficient and elegant solution.
import {generatePrimes} from 'prime-lib';
import {from, reduce, takeWhile} from 'rxjs';
from(generatePrimes())
.pipe(takeWhile(p => p < 250), reduce((a, c) => a + c))
.subscribe(sum => {
// sum = 5830
});
Performance-wise, it will take significantly less than 1ms.
How would it affect the code if I wanted say the sum of the first 250 prime numbers instead of the prime numbers under 250?
You would just replace takeWhile(p => p < 250) with take(250):
import {generatePrimes} from 'prime-lib';
import {from, reduce, take} from 'rxjs';
from(generatePrimes())
.pipe(take(250), reduce((a, c) => a + c))
.subscribe(sum => {
// sum = 182109
});
P.S. I am the author of prime-lib.