Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
In Javascript how would i find prime numbers between 0 - 100? i have thought about it, and i am not sure how to find them. i thought about doing x % x but i found the obvious problem with that.
this is what i have so far:
but unfortunately it is the worst code ever.
var prime = function (){
var num;
for (num = 0; num < 101; num++){
if (num % 2 === 0){
break;
}
else if (num % 3 === 0){
break;
}
else if (num % 4=== 0){
break;
}
else if (num % 5 === 0){
break;
}
else if (num % 6 === 0){
break;
}
else if (num % 7 === 0){
break;
}
else if (num % 8 === 0){
break;
}
else if (num % 9 === 0){
break;
}
else if (num % 10 === 0){
break;
}
else if (num % 11 === 0){
break;
}
else if (num % 12 === 0){
break;
}
else {
return num;
}
}
};
console.log(prime());
Here's an example of a sieve implementation in JavaScript:
function getPrimes(max) {
var sieve = [], i, j, primes = [];
for (i = 2; i <= max; ++i) {
if (!sieve[i]) {
// i has not been marked -- it is prime
primes.push(i);
for (j = i << 1; j <= max; j += i) {
sieve[j] = true;
}
}
}
return primes;
}
Then getPrimes(100) will return an array of all primes between 2 and 100 (inclusive). Of course, due to memory constraints, you can't use this with large arguments.
A Java implementation would look very similar.
Here's how I solved it. Rewrote it from Java to JavaScript, so excuse me if there's a syntax error.
function isPrime (n)
{
if (n < 2) return false;
/**
* An integer is prime if it is not divisible by any prime less than or equal to its square root
**/
var q = Math.floor(Math.sqrt(n));
for (var i = 2; i <= q; i++)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
A number, n, is a prime if it isn't divisible by any other number other than by 1 and itself. Also, it's sufficient to check the numbers [2, sqrt(n)].
Here is the live demo of this script: http://jsfiddle.net/K2QJp/
First, make a function that will test if a single number is prime or not. If you want to extend the Number object you may, but I decided to just keep the code as simple as possible.
function isPrime(num) {
if(num < 2) return false;
for (var i = 2; i < num; i++) {
if(num%i==0)
return false;
}
return true;
}
This script goes through every number between 2 and 1 less than the number and tests if there is any number in which there is no remainder if you divide the number by the increment. If there is any without a remainder, it is not prime. If the number is less than 2, it is not prime. Otherwise, it is prime.
Then make a for loop to loop through the numbers 0 to 100 and test each number with that function. If it is prime, output the number to the log.
for(var i = 0; i < 100; i++){
if(isPrime(i)) console.log(i);
}
Whatever the language, one of the best and most accessible ways of finding primes within a range is using a sieve.
Not going to give you code, but this is a good starting point.
For a small range, such as yours, the most efficient would be pre-computing the numbers.
I have slightly modified the Sieve of Sundaram algorithm to cut the unnecessary iterations and it seems to be very fast.
This algorithm is actually two times faster than the most accepted #Ted Hopp's solution under this topic. Solving the 78498 primes between 0 - 1M takes like 20~25 msec in Chrome 55 and < 90 msec in FF 50.1. Also #vitaly-t's get next prime algorithm looks interesting but also results much slower.
This is the core algorithm. One could apply segmentation and threading to get superb results.
"use strict";
function primeSieve(n){
var a = Array(n = n/2),
t = (Math.sqrt(4+8*n)-2)/4,
u = 0,
r = [];
for(var i = 1; i <= t; i++){
u = (n-i)/(1+2*i);
for(var j = i; j <= u; j++) a[i + j + 2*i*j] = true;
}
for(var i = 0; i<= n; i++) !a[i] && r.push(i*2+1);
return r;
}
var primes = [];
console.time("primes");
primes = primeSieve(1000000);
console.timeEnd("primes");
console.log(primes.length);
The loop limits explained:
Just like the Sieve of Erasthotenes, the Sieve of Sundaram algorithm also crosses out some selected integers from the list. To select which integers to cross out the rule is i + j + 2ij ≤ n where i and j are two indices and n is the number of the total elements. Once we cross out every i + j + 2ij, the remaining numbers are doubled and oddified (2n+1) to reveal a list of prime numbers. The final stage is in fact the auto discounting of the even numbers. It's proof is beautifully explained here.
Sieve of Sundaram is only fast if the loop indices start and end limits are correctly selected such that there shall be no (or minimal) redundant (multiple) elimination of the non-primes. As we need i and j values to calculate the numbers to cross out, i + j + 2ij up to n let's see how we can approach.
i) So we have to find the the max value i and j can take when they are equal. Which is 2i + 2i^2 = n. We can easily solve the positive value for i by using the quadratic formula and that is the line with t = (Math.sqrt(4+8*n)-2)/4,
j) The inner loop index j should start from i and run up to the point it can go with the current i value. No more than that. Since we know that i + j + 2ij = n, this can easily be calculated as u = (n-i)/(1+2*i);
While this will not completely remove the redundant crossings it will "greatly" eliminate the redundancy. For instance for n = 50 (to check for primes up to 100) instead of doing 50 x 50 = 2500, we will do only 30 iterations in total. So clearly, this algorithm shouldn't be considered as an O(n^2) time complexity one.
i j v
1 1 4
1 2 7
1 3 10
1 4 13
1 5 16
1 6 19
1 7 22 <<
1 8 25
1 9 28
1 10 31 <<
1 11 34
1 12 37 <<
1 13 40 <<
1 14 43
1 15 46
1 16 49 <<
2 2 12
2 3 17
2 4 22 << dupe #1
2 5 27
2 6 32
2 7 37 << dupe #2
2 8 42
2 9 47
3 3 24
3 4 31 << dupe #3
3 5 38
3 6 45
4 4 40 << dupe #4
4 5 49 << dupe #5
among which there are only 5 duplicates. 22, 31, 37, 40, 49. The redundancy is around 20% for n = 100 however it increases to ~300% for n = 10M. Which means a further optimization of SoS bears the potentital to obtain the results even faster as n grows. So one idea might be segmentation and to keep n small all the time.
So OK.. I have decided to take this quest a little further.
After some careful examination of the repeated crossings I have come to the awareness of the fact that, by the exception of i === 1 case, if either one or both of the i or j index value is among 4,7,10,13,16,19... series, a duplicate crossing is generated. Then allowing the inner loop to turn only when i%3-1 !== 0, a further cut down like 35-40% from the total number of the loops is achieved. So for instance for 1M integers the nested loop's total turn count dropped to like 1M from 1.4M. Wow..! We are talking almost O(n) here.
I have just made a test. In JS, just an empty loop counting up to 1B takes like 4000ms. In the below modified algorithm, finding the primes up to 100M takes the same amount of time.
I have also implemented the segmentation part of this algorithm to push to the workers. So that we will be able to use multiple threads too. But that code will follow a little later.
So let me introduce you the modified Sieve of Sundaram probably at it's best when not segmented. It shall compute the primes between 0-1M in about 15-20ms with Chrome V8 and Edge ChakraCore.
"use strict";
function primeSieve(n){
var a = Array(n = n/2),
t = (Math.sqrt(4+8*n)-2)/4,
u = 0,
r = [];
for(var i = 1; i < (n-1)/3; i++) a[1+3*i] = true;
for(var i = 2; i <= t; i++){
u = (n-i)/(1+2*i);
if (i%3-1) for(var j = i; j < u; j++) a[i + j + 2*i*j] = true;
}
for(var i = 0; i< n; i++) !a[i] && r.push(i*2+1);
return r;
}
var primes = [];
console.time("primes");
primes = primeSieve(1000000);
console.timeEnd("primes");
console.log(primes.length);
Well... finally I guess i have implemented a sieve (which is originated from the ingenious Sieve of Sundaram) such that it's the fastest JavaScript sieve that i could have found over the internet, including the "Odds only Sieve of Eratosthenes" or the "Sieve of Atkins". Also this is ready for the web workers, multi-threading.
Think it this way. In this humble AMD PC for a single thread, it takes 3,300 ms for JS just to count up to 10^9 and the following optimized segmented SoS will get me the 50847534 primes up to 10^9 only in 14,000 ms. Which means 4.25 times the operation of just counting. I think it's impressive.
You can test it for yourself;
console.time("tare");
for (var i = 0; i < 1000000000; i++);
console.timeEnd("tare");
And here I introduce you to the segmented Seieve of Sundaram at it's best.
"use strict";
function findPrimes(n){
function primeSieve(g,o,r){
var t = (Math.sqrt(4+8*(g+o))-2)/4,
e = 0,
s = 0;
ar.fill(true);
if (o) {
for(var i = Math.ceil((o-1)/3); i < (g+o-1)/3; i++) ar[1+3*i-o] = false;
for(var i = 2; i < t; i++){
s = Math.ceil((o-i)/(1+2*i));
e = (g+o-i)/(1+2*i);
if (i%3-1) for(var j = s; j < e; j++) ar[i + j + 2*i*j-o] = false;
}
} else {
for(var i = 1; i < (g-1)/3; i++) ar[1+3*i] = false;
for(var i = 2; i < t; i++){
e = (g-i)/(1+2*i);
if (i%3-1) for(var j = i; j < e; j++) ar[i + j + 2*i*j] = false;
}
}
for(var i = 0; i < g; i++) ar[i] && r.push((i+o)*2+1);
return r;
}
var cs = n <= 1e6 ? 7500
: n <= 1e7 ? 60000
: 100000, // chunk size
cc = ~~(n/cs), // chunk count
xs = n % cs, // excess after last chunk
ar = Array(cs/2), // array used as map
result = [];
for(var i = 0; i < cc; i++) result = primeSieve(cs/2,i*cs/2,result);
result = xs ? primeSieve(xs/2,cc*cs/2,result) : result;
result[0] *=2;
return result;
}
var primes = [];
console.time("primes");
primes = findPrimes(1000000000);
console.timeEnd("primes");
console.log(primes.length);
Here I present a multithreaded and slightly improved version of the above algorithm. It utilizes all available threads on your device and resolves all 50,847,534 primes up to 1e9 (1 Billion) in the ballpark of 1.3 seconds on my trash AMD FX-8370 8 core desktop.
While there exists some very sophisticated sublinear sieves, I believe the modified Segmented Sieve of Sundaram could only be stretced this far to being linear in time complexity. Which is not bad.
class Threadable extends Function {
constructor(f){
super("...as",`return ${f.toString()}.apply(this,as)`);
}
spawn(...as){
var code = `self.onmessage = m => self.postMessage(${this.toString()}.apply(null,m.data));`,
blob = new Blob([code], {type: "text/javascript"}),
wrkr = new Worker(window.URL.createObjectURL(blob));
return new Promise((v,x) => ( wrkr.onmessage = m => (v(m.data), wrkr.terminate())
, wrkr.onerror = e => (x(e.message), wrkr.terminate())
, wrkr.postMessage(as)
));
}
}
function pi(n){
function scan(start,end,tid){
function sieve(g,o){
var t = (Math.sqrt(4+8*(g+o))-2)/4,
e = 0,
s = 0,
a = new Uint8Array(g),
c = 0,
l = o ? (g+o-1)/3
: (g-1)/3;
if (o) {
for(var i = Math.ceil((o-1)/3); i < l; i++) a[1+3*i-o] = 0x01;
for(var i = 2; i < t; i++){
if (i%3-1) {
s = Math.ceil((o-i)/(1+2*i));
e = (g+o-i)/(1+2*i);
for(var j = s; j < e; j++) a[i + j + 2*i*j-o] = 0x01;
}
}
} else {
for(var i = 1; i < l; i++) a[1+3*i] = 0x01;
for(var i = 2; i < t; i++){
if (i%3-1){
e = (g-i)/(1+2*i);
for(var j = i; j < e; j++) a[i + j + 2*i*j] = 0x01;
}
}
}
for (var i = 0; i < g; i++) !a[i] && c++;
return c;
}
end % 2 && end--;
start % 2 && start--;
var n = end - start,
cs = n < 2e6 ? 1e4 :
n < 2e7 ? 2e5 :
4.5e5 , // Math.floor(3*n/1e3), // chunk size
cc = Math.floor(n/cs), // chunk count
xs = n % cs, // excess after last chunk
pc = 0;
for(var i = 0; i < cc; i++) pc += sieve(cs/2,(start+i*cs)/2);
xs && (pc += sieve(xs/2,(start+cc*cs)/2));
return pc;
}
var tc = navigator.hardwareConcurrency,
xs = n % tc,
cs = (n-xs) / tc,
st = new Threadable(scan),
ps = Array.from( {length:tc}
, (_,i) => i ? st.spawn(i*cs+xs,(i+1)*cs+xs,i)
: st.spawn(0,cs+xs,i)
);
return Promise.all(ps);
}
var n = 1e9,
count;
console.time("primes");
pi(n).then(cs => ( count = cs.reduce((p,c) => p+c)
, console.timeEnd("primes")
, console.log(count)
)
)
.catch(e => console.log(`Error: ${e}`));
So this is as far as I could take the Sieve of Sundaram.
A number is a prime if it is not divisible by other primes lower than the number in question.
So this builds up a primes array. Tests each new odd candidate n for division against existing found primes lower than n. As an optimization it does not consider even numbers and prepends 2 as a final step.
var primes = [];
for(var n=3;n<=100;n+=2) {
if(primes.every(function(prime){return n%prime!=0})) {
primes.push(n);
}
}
primes.unshift(2);
To find prime numbers between 0 to n. You just have to check if a number x is getting divisible by any number between 0 - (square root of x). If we pass n and to find all prime numbers between 0 and n, logic can be implemented as -
function findPrimeNums(n)
{
var x= 3,j,i=2,
primeArr=[2],isPrime;
for (;x<=n;x+=2){
j = (int) Math.sqrt (x);
isPrime = true;
for (i = 2; i <= j; i++)
{
if (x % i == 0){
isPrime = false;
break;
}
}
if(isPrime){
primeArr.push(x);
}
}
return primeArr;
}
var n=100;
var counter = 0;
var primeNumbers = "Prime Numbers: ";
for(var i=2; i<=n; ++i)
{
counter=0;
for(var j=2; j<=n; ++j)
{
if(i>=j && i%j == 0)
{
++counter;
}
}
if(counter == 1)
{
primeNumbers = primeNumbers + i + " ";
}
}
console.log(primeNumbers);
Luchian's answer gives you a link to the standard technique for finding primes.
A less efficient, but simpler approach is to turn your existing code into a nested loop. Observe that you are dividing by 2,3,4,5,6 and so on ... and turn that into a loop.
Given that this is homework, and given that the aim of the homework is to help you learn basic programming, a solution that is simple, correct but somewhat inefficient should be fine.
Using recursion combined with the square root rule from here, checks whether a number is prime or not:
function isPrime(num){
// An integer is prime if it is not divisible by any prime less than or equal to its square root
var squareRoot = parseInt(Math.sqrt(num));
var primeCountUp = function(divisor){
if(divisor > squareRoot) {
// got to a point where the divisor is greater than
// the square root, therefore it is prime
return true;
}
else if(num % divisor === 0) {
// found a result that divides evenly, NOT prime
return false;
}
else {
// keep counting
return primeCountUp(++divisor);
}
};
// start # 2 because everything is divisible by 1
return primeCountUp(2);
}
You can try this method also, this one is basic but easy to understand:
var tw = 2, th = 3, fv = 5, se = 7;
document.write(tw + "," + th + ","+ fv + "," + se + ",");
for(var n = 0; n <= 100; n++)
{
if((n % tw !== 0) && (n % th !==0) && (n % fv !==0 ) && (n % se !==0))
{
if (n == 1)
{
continue;
}
document.write(n +",");
}
}
I recently came up with a one-line solution that accomplishes exactly this for a JS challenge on Scrimba (below).
ES6+
const getPrimes=num=>Array(num-1).fill().map((e,i)=>2+i).filter((e,i,a)=>a.slice(0,i).every(x=>e%x!==0));
< ES6
function getPrimes(num){return ",".repeat(num).slice(0,-1).split(',').map(function(e,i){return i+1}).filter(function(e){return e>1}).filter(function(x){return ",".repeat(x).slice(0,-1).split(',').map(function(f,j){return j}).filter(function(e){return e>1}).every(function(e){return x%e!==0})})};
This is the logic explained:
First, the function builds an array of all numbers leading up to the desired number (in this case, 100) via the .repeat() function using the desired number (100) as the repeater argument and then mapping the array to the indexes+1 to get the range of numbers from 0 to that number (0-100). A bit of string splitting and joining magic going on here. I'm happy to explain this step further if you like.
We exclude 0 and 1 from the array as they should not be tested for prime, lest they give a false positive. Neither are prime. We do this using .filter() for only numbers > 1 (≥ 2).
Now, we filter our new array of all integers between 2 and the desired number (100) for only prime numbers. To filter for prime numbers only, we use some of the same magic from our first step. We use .filter() and .repeat() once again to create a new array from 2 to each value from our new array of numbers. For each value's new array, we check to see if any of the numbers ≥ 2 and < that number are factors of the number. We can do this using the .every() method paired with the modulo operator % to check if that number has any remainders when divided by any of those values between 2 and itself. If each value has remainders (x%e!==0), the condition is met for all values from 2 to that number (but not including that number, i.e.: [2,99]) and we can say that number is prime. The filter functions returns all prime numbers to the uppermost return, thereby returning the list of prime values between 2 and the passed value.
As an example, using one of these functions I've added above, returns the following:
getPrimes(100);
// => [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
Here's a fast way to calculate primes in JavaScript, based on the previous prime value.
function nextPrime(value) {
if (value > 2) {
var i, q;
do {
i = 3;
value += 2;
q = Math.floor(Math.sqrt(value));
while (i <= q && value % i) {
i += 2;
}
} while (i <= q);
return value;
}
return value === 2 ? 3 : 2;
}
Test
var value = 0, result = [];
for (var i = 0; i < 10; i++) {
value = nextPrime(value);
result.push(value);
}
console.log("Primes:", result);
Output
Primes: [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 ]
It is faster than other alternatives published here, because:
It aligns the loop limit to an integer, which works way faster;
It uses a shorter iteration loop, skipping even numbers.
It can give you the first 100,000 primes in about 130ms, or the first 1m primes in about 4 seconds.
function nextPrime(value) {
if (value > 2) {
var i, q;
do {
i = 3;
value += 2;
q = Math.floor(Math.sqrt(value));
while (i <= q && value % i) {
i += 2;
}
} while (i <= q);
return value;
}
return value === 2 ? 3 : 2;
}
var value, result = [];
for (var i = 0; i < 10; i++) {
value = nextPrime(value);
result.push(value);
}
display("Primes: " + result.join(', '));
function display(msg) {
document.body.insertAdjacentHTML(
"beforeend",
"<p>" + msg + "</p>"
);
}
UPDATE
A modern, efficient way of doing it, using prime-lib:
import {generatePrimes, stopWhen} from 'prime-lib';
const p = generatePrimes(); //=> infinite prime generator
const i = stopWhen(p, a => a > 100); //=> Iterable<number>
console.log(...i); //=> 2 3 5 7 11 ... 89 97
<code>
<script language="javascript">
var n=prompt("Enter User Value")
var x=1;
if(n==0 || n==1) x=0;
for(i=2;i<n;i++)
{
if(n%i==0)
{
x=0;
break;
}
}
if(x==1)
{
alert(n +" "+" is prime");
}
else
{
alert(n +" "+" is not prime");
}
</script>
Sieve of Eratosthenes. its bit look but its simple and it works!
function count_prime(arg) {
arg = typeof arg !== 'undefined' ? arg : 20; //default value
var list = [2]
var list2 = [0,1]
var real_prime = []
counter = 2
while (counter < arg ) {
if (counter % 2 !== 0) {
list.push(counter)
}
counter++
}
for (i = 0; i < list.length - 1; i++) {
var a = list[i]
for (j = 0; j < list.length - 1; j++) {
if (list[j] % a === 0 && list[j] !== a) {
list[j] = false; // assign false to non-prime numbers
}
}
if (list[i] !== false) {
real_prime.push(list[i]); // save all prime numbers in new array
}
}
}
window.onload=count_prime(100);
And this famous code from a famous JS Ninja
var isPrime = n => Array(Math.ceil(Math.sqrt(n)+1)).fill().map((e,i)=>i).slice(2).every(m => n%m);
console.log(Array(100).fill().map((e,i)=>i+1).slice(1).filter(isPrime));
A list built using the new features of ES6, especially with generator.
Go to https://codepen.io/arius/pen/wqmzGp made in Catalan language for classes with my students. I hope you find it useful.
function* Primer(max) {
const infinite = !max && max !== 0;
const re = /^.?$|^(..+?)\1+$/;
let current = 1;
while (infinite || max-- ) {
if(!re.test('1'.repeat(current)) == true) yield current;
current++
};
};
let [...list] = Primer(100);
console.log(list);
Here's the very simple way to calculate primes between a given range(1 to limit).
Simple Solution:
public static void getAllPrimeNumbers(int limit) {
System.out.println("Printing prime number from 1 to " + limit);
for(int number=2; number<=limit; number++){
//***print all prime numbers upto limit***
if(isPrime(number)){
System.out.println(number);
}
}
}
public static boolean isPrime(int num) {
if (num == 0 || num == 1) {
return false;
}
if (num == 2) {
return true;
}
for (int i = 2; i <= num / 2; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
A version without any loop. Use this against any array you have. ie.,
[1,2,3...100].filter(x=>isPrime(x));
const isPrime = n => {
if(n===1){
return false;
}
if([2,3,5,7].includes(n)){
return true;
}
return n%2!=0 && n%3!=0 && n%5!=0 && n%7!=0;
}
Here's my stab at it.
Change the initial i=0 from 0 to whatever you want, and the the second i<100 from 100 to whatever to get primes in a different range.
for(var i=0; i<100000; i++){
var devisableCount = 2;
for(var x=0; x<=i/2; x++){
if (devisableCount > 3) {
break;
}
if(i !== 1 && i !== 0 && i !== x){
if(i%x === 0){
devisableCount++;
}
}
}
if(devisableCount === 3){
console.log(i);
}
}
I tried it with 10000000 - it takes some time but appears to be accurate.
Here are the Brute-force iterative method and Sieve of Eratosthenes method to find prime numbers upto n. The performance of the second method is better than first in terms of time complexity
Brute-force iterative
function findPrime(n) {
var res = [2],
isNotPrime;
for (var i = 3; i < n; i++) {
isNotPrime = res.some(checkDivisorExist);
if ( !isNotPrime ) {
res.push(i);
}
}
function checkDivisorExist (j) {
return i % j === 0;
}
return res;
}
Sieve of Eratosthenes method
function seiveOfErasthones (n) {
var listOfNum =range(n),
i = 2;
// CHeck only until the square of the prime is less than number
while (i*i < n && i < n) {
listOfNum = filterMultiples(listOfNum, i);
i++;
}
return listOfNum;
function range (num) {
var res = [];
for (var i = 2; i <= num; i++) {
res.push(i);
}
return res;
}
function filterMultiples (list, x) {
return list.filter(function (item) {
// Include numbers smaller than x as they are already prime
return (item <= x) || (item > x && item % x !== 0);
});
}
}
You can use this for any size of array of prime numbers. Hope this helps
function prime() {
var num = 2;
var body = document.getElementById("solution");
var len = arguments.length;
var flag = true;
for (j = 0; j < len; j++) {
for (i = num; i < arguments[j]; i++) {
if (arguments[j] % i == 0) {
body.innerHTML += arguments[j] + " False <br />";
flag = false;
break;
} else {
flag = true;
}
}
if (flag) {
body.innerHTML += arguments[j] + " True <br />";
}
}
}
var data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
prime.apply(null, data);
<div id="solution">
</div>
public static void main(String[] args) {
int m = 100;
int a[] =new int[m];
for (int i=2; i<m; i++)
for (int j=0; j<m; j+=i)
a[j]++;
for (int i=0; i<m; i++)
if (a[i]==1) System.out.println(i);
}
Using Sieve of Eratosthenes, source on Rosettacode
fastest solution: https://repl.it/#caub/getPrimes-bench
function getPrimes(limit) {
if (limit < 2) return [];
var sqrtlmt = limit**.5 - 2;
var nums = Array.from({length: limit-1}, (_,i)=>i+2);
for (var i = 0; i <= sqrtlmt; i++) {
var p = nums[i]
if (p) {
for (var j = p * p - 2; j < nums.length; j += p)
nums[j] = 0;
}
}
return nums.filter(x => x); // return non 0 values
}
document.body.innerHTML = `<pre style="white-space:pre-wrap">${getPrimes(100).join(', ')}</pre>`;
// for fun, this fantasist regexp way (very inefficient):
// Array.from({length:101}, (_,i)=>i).filter(n => n>1&&!/^(oo+)\1+$/.test('o'.repeat(n))
Why try deleting by 4 (and 6,8,10,12) if we've already tried deleting by 2 ?
Why try deleting by 9 if we've already tried deleting by 3 ?
Why try deleting by 11 if 11 * 11 = 121 which is greater than 100 ?
Why try deleting any odd number by 2 at all?
Why try deleting any even number above 2 by anything at all?
Eliminate the dead tests and you'll get yourself a good code, testing for primes below 100.
And your code is very far from being the worst code ever. Many many others would try dividing 100 by 99. But the absolute champion would generate all products of 2..96 with 2..96 to test whether 97 is among them. That one really is astonishingly inefficient.
Sieve of Eratosthenes of course is much better, and you can have one -- under 100 -- with no arrays of booleans (and no divisions too!):
console.log(2)
var m3 = 9, m5 = 25, m7 = 49, i = 3
for( ; i < 100; i += 2 )
{
if( i != m3 && i != m5 && i != m7) console.log(i)
else
{
if( i == m3 ) m3 += 6
if( i == m5 ) m5 += 10
if( i == m7 ) m7 += 14
}
} "DONE"
This is the sieve of Eratosthenes, were we skip over the composites - and that's what this code is doing. The timing of generation of composites and of skipping over them (by checking for equality) is mixed into one timeline. The usual sieve first generates composites and marks them in an array, then sweeps the array. Here the two stages are mashed into one, to avoid having to use any array at all (this only works because we know the top limit's square root - 10 - in advance and use only primes below it, viz. 3,5,7 - with 2's multiples, i.e. evens, implicitly skipped over in advance).
In other words this is an incremental sieve of Eratosthenes and m3, m5, m7 form an implicit priority queue of the multiples of primes 3, 5, and 7.
I was searching how to find out prime number and went through above code which are too long. I found out a new easy solution for prime number and add them using filter. Kindly suggest me if there is any mistake in my code as I am a beginner.
function sumPrimes(num) {
let newNum = [];
for(let i = 2; i <= num; i++) {
newNum.push(i)
}
for(let i in newNum) {
newNum = newNum.filter(item => item == newNum[i] || item % newNum[i] !== 0)
}
return newNum.reduce((a,b) => a+b)
}
sumPrimes(10);
Here is an efficient, short solution using JS generators. JSfiddle
// Consecutive integers
let nats = function* (n) {
while (true) yield n++
}
// Wrapper generator
let primes = function* () {
yield* sieve(primes(), nats(2))
}
// The sieve itself; only tests primes up to sqrt(n)
let sieve = function* (pg, ng) {
yield ng.next().value;
let n, p = pg.next().value;
while ((n = ng.next().value) < p * p) yield n;
yield* sieve(pg, (function* () {
while (n = ng.next().value) if (n % p) yield n
})())
}
// Longest prefix of stream where some predicate holds
let take = function* (vs, fn) {
let nx;
while (!(nx = vs.next()).done && fn(nx.value)) yield nx.value
}
document.querySelectorAll('dd')[0].textContent =
// Primes smaller than 100
[...take(primes(), x => x < 100)].join(', ')
<dl>
<dt>Primes under 100</dt>
<dd></dd>
</dl>
First, change your inner code for another loop (for and while) so you can repeat the same code for different values.
More specific for your problem, if you want to know if a given n is prime, you need to divide it for all values between 2 and sqrt(n). If any of the modules is 0, it is not prime.
If you want to find all primes, you can speed it and check n only by dividing by the previously found primes. Another way of speeding the process is the fact that, apart from 2 and 3, all the primes are 6*k plus or less 1.
It would behoove you, if you're going to use any of the gazillion algorithms that you're going to be presented with in this thread, to learn to memoize some of them.
See Interview question : What is the fastest way to generate prime number recursively?
Use following function to find out prime numbers :
function primeNumbers() {
var p
var n = document.primeForm.primeText.value
var d
var x
var prime
var displayAll = 2 + " "
for (p = 3; p <= n; p = p + 2) {
x = Math.sqrt(p)
prime = 1
for (d = 3; prime && (d <= x); d = d + 2)
if ((p % d) == 0) prime = 0
else prime = 1
if (prime == 1) {
displayAll = displayAll + p + " "
}
}
document.primeForm.primeArea.value = displayAll
}
Related
I was asked this question in an interview:
An integer is special if it can be expressed as a sum that's a palindrome (the same backwards as forwards). For example, 22 and 121 are both special, because 22 equals 11+11 and 121 equals 29+92.
Given an array of integers, count how many of its elements are special.
but I couldn't think of any solution. How can this be done?
In the stress and the hurry of an interview, I would have certainly found a dumb and naive solution.
pseudo code
loop that array containing the numbers
Looping from nb = 0 to (*the number to test* / 2)
convert nb to string and reverse the order of that string (ie : if you get "29", transform it to "92")
convert back the string to a nb2
if (nb + nb2 == *the number to test*)
this number is special. Store it in the result array
end loop
end loop
print the result array
function IsNumberSpecial(input)
{
for (let nb1 = 0; nb1 <= (input / 2); ++nb1)
{
let nb2 = parseInt(("" + nb1).split("").reverse().join("")); // get the reverse number
if (nb2 + nb1 == input)
{
console.log(nb1 + " + " + nb2 + " = " + input);
return (true);
}
}
return (false);
}
let arr = [22, 121, 42];
let len = arr.length;
let result = 0;
for (let i = 0; i < len; ++i)
{
if (IsNumberSpecial(arr[i]))
++result;
}
console.log(result + " number" + ((result > 1) ? "s" : "") + " found");
Here's a rather naïve solution in pseudocode for determining if a number is 'special':
Given an number N (assumed to be an integer)
Let I = Floor(N / 2)
Let J = Ceil(N / 2)
While (I > 0)
If I is the reverse of J Then
Return True
End
I <- I - 1
J <- J + 1
End
Return False
A quick JS implementation:
function isSpecial(n) {
for (var i = Math.floor(n / 2), j = Math.ceil(n / 2); i > 0; i--, j++) {
console.info(`checking ${i} + ${j}`);
if (i.toString().split('').reverse().join('') === j.toString())
return true;
}
return false;
}
console.log(isSpecial(121));
I'll leave it up to the you implement the function to count the special numbers in the array. This could be made more efficient by improving the rather crude method for checking for string reversals or possibly by more intelligently skipping numbers.
Some pseudo code?
num_special = 0
for item in array:
for num in range(1, total):
if num + int(string(num).reversed()) == item
num_special += 1
break
print(num_special)
EDIT:
Here's a working Python example:
array = [22, 121]
num_special = 0
for item in array:
for num in range(1, item):
if (num + int(str(num)[::-1]) == item):
num_special += 1
break
print(num_special)
https://repl.it/repls/UsedLovelyCategory
Assuming we want two summands - this does not seem to be specified in the question but every answer has assumed it!
(Without this assumption, every number can be written as a reversible sum of 1s.)
Single digit summands:
n is even
Two digit summands:
10x + y + 10y + x
11x + 11y
11(x + y)
n is divisible by 11
Three digit summands:
100x + 10y + z + 100z + 10y + x
101x + 20y + 101z
101(x + z) + 20y
more complex but we can still
do better than a brute force
loop of 1 to n / 2
Etc... (we could probably write a function that generalises and searches over this algebra)
UPDATE
JavaScript code (interestingly, a result for 1111111110 seems to be found faster by the brute force 1 to n/2 loop! Maybe some other optimisations can be made):
function f(n){
let start = new Date;
let numDigits = 0;
let t = Math.ceil(n / 2);
while (t){
numDigits++;
t = ~~(t/10);
}
// Summands split between x and x+1 digits
if (n / 2 + 0.5 == Math.pow(10, numDigits - 1))
return false;
let cs = [];
let l = Math.pow(10, numDigits - 1);
let r = 1;
while (l >= r){
cs.push(l + r);
l /= 10;
r *= 10;
}
let sxs = new Array(cs.length);
const m = cs.length & 1 || 2;
sxs[cs.length-1] = m*cs[cs.length-1];
for (let i=cs.length-2; i>=0; i--)
sxs[i] = 2*cs[i] + sxs[i + 1];
let stack = [[0, n, []]];
let results = [];
while (stack.length){
let [i, curr, vs] = stack.pop();
if (i == cs.length - 1){
let d = curr / cs[i];
if (d == ~~d &&
((cs.length & 1 && d < 10) || ((!(cs.length & 1) || cs.length == 1) && d < 19)))
results.push(vs.concat('x'));
continue;
}
t = 2;
curr -= t*cs[i];
stack.push([
i + 1, curr,
vs.slice().concat(t)]);
while (curr >= sxs[i + 1]){
curr -= cs[i];
stack.push([
i + 1, curr,
vs.slice().concat(++t)]);
}
}
let time = new Date - start;
return [!!results.length, (time) + 'ms', cs, results];
}
let ns = [
22, 121, 42,
66666,
777777,
8888888,
99999999,
68685,
68686]
for (let n of ns)
console.log(n, JSON.stringify(f(n)));
My JS variant:
const reverseInt = (n) =>
parseInt(n.toString().split('').reverse().join(''))
const checkSpecialInt = (n) =>{
for(let i=1;i<=n;i++){
if (i+reverseInt(i)==n) return true;
}
return false;
}
const checkSpecialIntArray = (arr) =>
arr.filter((e,i)=>checkSpecialInt(e)).length;
let test = [122, 121, 22, 21];
console.log(checkSpecialIntArray(test));
The requirement does not includes returning every possible combination of matched "special numbers", only that a match is found.
const isSpecialInteger = arr => {
// `arr`: `Array`
// result, initialized to `0`
let res = 0;
// iterate input `arr`
for (let n of arr) {
// divide `n` by `2`
const c = n / 2;
// check if `n` is an integer or decimal
// if decimal subtract decimal portion of 1st divided decimal
// add decimal portion to 2nd portion of divided decimal
// else set `x`, `y` to even division of input `n`
let [x, y] = !Number.isInteger(c) ? [c - (c % 10), c + (c % 10)] : [c, c];
// set label for `for` loop
// decrement result of `Math.max(x, y)`
N: for (let i = Math.max(x, y); i; i--) {
// check if `i` converted to
// string, then array reveresed
// if equal to `n`
// if `true` increment `res` by `1` `break` `N` loop
if (i + +[...`${i}`].reverse().join`` === n) {
res+= 1;
break N;
}
}
}
// return positive integer or `0`
return res;
}
console.log(
isSpecialInteger([22, 121])
);
Here is one of the brute-force approaches in JAVA and this can be optimised further,
import java.util.Scanner;
public class Solution
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
String str = in.nextLine();
String[] inp = str.split(",");
System.out.println(isSpecial(inp,inp.length));
}
public static int isSpecial(String[] inp, int inpSize)
{
int arr[] = new int[inp.length];
for(int i=0;i<inpSize;i++)
{
arr[i] = Integer.parseInt(inp[i]);
}
int spclCount = 0;
for(int i=0;i<arr.length;i++)
{
for(int j=1;j<((arr[i]/2)+1);j++)
{
if(j+getReverse(j) == arr[i])
{
spclCount++;
break;
}
}
}
return spclCount;
}
public static int getReverse(int n)
{
int rem,rev=0;
while(n != 0)
{
rem = n % 10;
rev = (rev*10) + rem;
n /= 10;
}
return rev;
}
}
Question:
An integer is special if it can be expressed as a sum that's a palindrome (the same backwards as forwards). For example, 22 and 121 are both special, because 22 equals 11+11 and 121 equals 29+92.
Given an array of integers, count how many of its elements are special
My Approach:
public class PalindromicSum {
public static void getSplNumber(int[] arrip) {
//to iterate i/p array
for (int i = 0; i < arrip.length; i++) {
int tempSum = 0;
//to iterate from 1 to number/2
for (int j = 1; j <= arrip[i] / 2; j++) {
//to get the reverse of the number
int revNum = getRevNum(j);
tempSum = revNum + j;
if (tempSum == arrip[i]) {
System.out.println(arrip[i]);
break;
}
}
}
}
public static int getRevNum(int num) {
int rev = 0;
//to get reverse of a number
while(num!=0) {
int reminder = num%10;
rev = rev*10 + reminder;
num = num/10;
}
return rev;
}
public static void main(String[] args) {
int[] arr = { 121, 11, 10, 3, 120, 110};
getSplNumber(arr);
}
}
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.
I was trying to find the prime factors of a number, recorded below as 'integer' using a for loop in javascript. I can't seem to get it working and I'm not sure whether it's my JavaScript or my calculation logic.
//integer is the value for which we are finding prime factors
var integer = 13195;
var primeArray = [];
//find divisors starting with 2
for (i = 2; i < integer/2; i++) {
if (integer % i == 0) {
//check if divisor is prime
for (var j = 2; j <= i / 2; j++) {
if (i % j == 0) {
isPrime = false;
} else {
isPrime = true;
}
}
//if divisor is prime
if (isPrime == true) {
//divide integer by prime factor & factor store in array primeArray
integer /= i
primeArray.push(i);
}
}
}
for (var k = 0; k < primeArray.length; k++) {
console.log(primeArray[k]);
}
The answer above is inefficient with O(N^2) complexity. Here is a better answer with O(N) complexity.
function primeFactors(n) {
const factors = [];
let divisor = 2;
while (n >= 2) {
if (n % divisor == 0) {
factors.push(divisor);
n = n / divisor;
} else {
divisor++;
}
}
return factors;
}
const randomNumber = Math.floor(Math.random() * 10000);
console.log('Prime factors of', randomNumber + ':', primeFactors(randomNumber).join(' '))
You can filter for duplicates as you please!
Here's a working solution:
function getPrimeFactors(integer) {
const primeArray = [];
let isPrime;
// Find divisors starting with 2
for (let i = 2; i <= integer; i++) {
if (integer % i !== 0) continue;
// Check if the divisor is a prime number
for (let j = 2; j <= i / 2; j++) {
isPrime = i % j !== 0;
}
if (!isPrime) continue;
// if the divisor is prime, divide integer with the number and store it in the array
integer /= i
primeArray.push(i);
}
return primeArray;
}
console.log(getPrimeFactors(13195).join(', '));
You were very much on the right track. There were two minor mistakes. The evaluation of integer - 1 seemed to be incorrect. I believe the more appropriate evaluation is <= integer in your outer for loop. This is because when you divide your integer below integer /= i, this results in the final integer evaluation to be 29. The final prime divisor in this case is also 29 and as such will need to be evaluated as <= as oppose to < integer - 1.
As for why the final log statement isn't working, there was a simple typo of primeArray[i] as oppose to primeArray[k].
I do believe there is a mistake in both code above. If you replace the integer by 100 the prime factorization won't work anymore as the factor 2 cannot be considered with those for loops. As j = 2, i = 2 and j<=i/2 in the condition - meaning the loop will never run for i=2, which is a prime factor.
Tried to make it work this way but couldn't figure out.
Had to rely on a different approach with a while loop here :
function getAllFactorsFor(remainder) {
var factors = [], i;
for (i = 2; i <= remainder; i++) {
while ((remainder % i) === 0) {
factors.push(i);
remainder /= i;
}
}
return factors;
}
https://jsfiddle.net/JamesOR/RC7SY/
You could also go with something like that :
let findPrimeFactors = (num) => {
let arr = [];
for ( var i = 2; i < num; i++) {
let isPrime
if (num % i === 0) {
isPrime = true;
for (var j = 2; j <= i; j++) {
if ( i % j === 0) {
isPrime == false;
}
}
}if (isPrime == true) { arr.push(i)}
}console.log(arr)
}
findPrimeFactors(543)
We can find the prime factor numbers up to n with only one loop. It is a very simple solution without any nested loop.
Time complexity would be less than O(n) because we are dividing "n" by "i".
function primeFactors(n) {
let arr=[];
let i = 2;
while(i<=n){
if(n%i == 0) {
n= n/i;
arr.push(i);
} else {
i++;
}
}
return arr;
}
// primeFactors(10) [2,5]
// primeFactors(10) [2,2,5,5]
// primeFactors(2700) [2, 2, 3, 3, 3, 5, 5]
When factorizing an integer (n) to its prime factors, after finding the first prime factor, the problem in hand is reduced to finding prime factorization of quotient (q).
Suppose n is divisible to prime p1 then we have n = p1 * q1 so after finding p1 the problem is reduced to factorizing q1 (quotient). If the function name is primeFactorizer then we can call it recursively and solution for n would be:
n = p1 * primeFactorizer(q1)
n = p1 * p2 * primeFactorizer(q2)
...
Until qn is prime itself.
Also I'm going to use a helper generator function which generates primes for us:
function * primes () {
let n = 2
while (true) {
let isPrime = true
for (let i = 2; i <= n / 2; i++) {
if (n % i === 0) {
isPrime = false
break
}
}
if (isPrime) {
yield n
}
n++
}
}
And function to factorize n would be:
function primeFactorizer (n, result = []) {
for (const p of primes()) {
if (n === p) {
result.push(p)
return result
}
if (n % p === 0) {
result.push(p)
return primeFactorizer(n / p, result)
}
}
}
I've refined this function over time, trying to get it as fast as possible (racing it against others' functions that I've found online, haven't found one that runs consistently faster than it yet).
function primFact(num) {
var factors = [];
/* since 2 is the only even prime, it's easier to factor it out
* separately from the odd factor loop (for loop doesn't need to
* check whether or not to add 1 or 2 to f).
* The condition is essentially checking if the number is even
* (bitwise "&" operator compares the bits of 2 numbers in binary
* and outputs a binary number with 1's where their digits are the
* same and 0's where they differ. In this case it only checks if
* the final digit for num in binary is 1, which would mean the
* number is odd, in which case the output would be 1, which is
* interpreted as true, otherwise the output will be 0, which is
* interpreted as false. "!" returns the opposite boolean, so this
* means that '!(num & 1)' is true when the num is not odd)
*/
while (!(num & 1)) {
factors.push(2);
num /= 2;
}
// 'f*f <= num' is faster than 'f <= Math.sqrt(num)'
for (var f = 3; f*f <= num; f += 2) {
while (!(num % f)) { // remainder of 'num / f' isn't 0
factors.push(f);
num /= f;
}
}
/* if the number is already prime, then this adds it to factors so
* an empty array isn't returned
*/
if (num != 1) {
factors.push(num);
}
return factors;
}
This performs very well at large numbers compared to functions I've run it against, especially when the number is prime, (rarely runs slower than 10ms when I've run it in an online compiler like OneCompiler) so if you want speed I'd say this is a pretty good way to go about it.
Still working on making it even faster, but only way to include all primes without adding new conditions to check is to iterate through all odd numbers.
I just started JavaScript but i managed to come up with my own solution for this while working on a school project with a similar objective.
Only issue is that it takes a very long time for large numbers, its not v ery efficient. But it works perfectly.
function isPrime(n){
if (n === 1){
return false;
}
else if (n === 2){
return true;
}
else{
for (let x = 2; x < n; x ++){
if (n % x === 0){
return false;
}
}
return true;
}
}
let primeFac = []
let num = 30
for (let x = 0; x <= num; x++){
if (num % x === 0 && isPrime(x) === true){
primeFac.push(x);
}
}
console.log(`${primeFac}`)
If you work up from the bottom there's no need to check if any following factor is prime. This is because any lower primes will have already been divided out.
function getPrimeFactorsFor(num) {
const primes = [];
for (let factor = 2; factor <= num; factor++) {
while ((num % factor) === 0) {
primes.push(factor);
num /= factor;
}
}
return primes;
}
console.log("10 has the primes: ", getPrimeFactorsFor(10));
console.log("8 has the primes: ", getPrimeFactorsFor(8));
console.log("105 has the primes: ", getPrimeFactorsFor(105))
console.log("1000 has the primes: ", getPrimeFactorsFor(1000))
console.log("1155 has the primes: ", getPrimeFactorsFor(1155))
In case somebody is looking for the fastest solution, here's one based on my library prime-lib. It can calculate prime factors for any number between 2 and 2^53 - 1, in under 1ms. The function source code is available here.
import {primeFactors} from 'prime-lib';
const factors = primeFactors(600851475143);
//=> [71, 839, 1471, 6857]
Here an other implementation to find prime factors, in three variations. It's more efficient than the other implementations, worst case sqrt(n), because it stops earlier.
The function* means it's a generator function. So a generator is returned instead of an array and the next prime factor is only calculated as soon as it is requested.
// Example: 24 -> 2, 3
function* singlePrimeFactors (n) {
for (var k = 2; k*k <= n; k++) {
if (n % k == 0) {
yield k
do {n /= k} while (n % k == 0)
}
}
if (n > 1) yield n
}
// Example: 24 -> 2, 2, 2, 3
function* repeatedPrimeFactors (n) {
for (var k = 2; k*k <= n; k++) {
while (n % k == 0) {
yield k
n /= k
}
}
if (n > 1) yield n
}
// Example: 24 -> {p: 2, m: 3}, {p: 3, m: 1}
function* countedPrimeFactors (n) {
for (var k = 2; k*k <= n; k++) {
if (n % k == 0) {
var count = 1
for (n /= k; n % k == 0; n /= k) count++
yield {p: k, m: count}
}
}
if (n > 1) yield {p: n, m: 1}
}
// Test code
for (var i=1; i<=100; i++) {
var single = JSON.stringify(Array.from(singlePrimeFactors(i)))
var repeated = JSON.stringify(Array.from(repeatedPrimeFactors(i)))
var counted = JSON.stringify(Array.from(countedPrimeFactors(i)))
console.log(i, single, repeated, counted)
}
// Iterating over a generator
for (var p of singlePrimeFactors(24)) {
console.log(p)
}
// Iterating over a generator, an other way
var g = singlePrimeFactors(24)
for (var r = g.next(); !r.done; r = g.next()) {
console.log(r.value);
}
My solution avoids returning not prime factors:
let result = [];
let i = 2;
let j = 2;
let number = n;
for (; i <= number; i++) {
let isPrime = number % i === 0;
if (isPrime) {
result.push(i);
number /= i;
}
while (isPrime) {
if (number % i === 0) {
result.push(i);
number /= i;
} else {
isPrime = false;
}
}
}
return result;
With so many good solutions above, wanted to make a little bit of improvement by using this theorem in the Math Forum Finding prime factors by taking the square root
.
function primeFactors(n)
{
// Print the number of 2s that divide n
while (n%2 == 0)
{
console.log(2);
n = n/2;
}
// n must be odd at this point. So we can skip
// one element (Note i = i +2)
for (var i = 3; i <= Math.sqrt(n); i = i+2)
{
// While i divides n, print i and divide n
while (n%i == 0)
{
console.log(i);
n = n/i;
}
}
// This condition is to handle the case when n
// is a prime number greater than 2
if (n > 2)
console.log(n);
}
primeFactors(344);
console.log("--------------");
primeFactors(4);
console.log("--------------");
primeFactors(10);
Hope this answer adds value.
Here is a solution using recursion
function primeFactors(num, primes){
let i = 2;
while(i < num){
if(num % i === 0){
primes.push(i);
return primeFactors(num/i, primes);
}
i++
}
primes.push(num);
return primes;
}
console.log(primeFactors(55, []))
console.log(primeFactors(15, []))
console.log(primeFactors(40, []))
console.log(primeFactors(13, []))
// [ 5, 11 ]
// [ 3, 5 ]
// [ 2, 2, 2, 5 ]
// [ 13 ]
I found this solution by chance when i was trying to simplify several
solutions that i saw here. Although it doesn't check if the divisor
is a prime number somehow it seems to work, i tested it with
miscellaneous numbers but i could not explain how this was possible.
function start() {
var integer = readInt("Enter number: ");
println("The prime factorization is: ");
for(var i = 2; i <= integer; i++) {
if (integer % i == 0) {
println(i);
integer = integer / i;
i = i - 1;
}
}
}
I checked the algorithm with yield, but that is a lot slower than recursive calls.
function rootnth(val, power=2) {
let o = 0n; // old approx value
let x = val;
let limit = 100;
let k = BigInt(power);
while(x**k!==k && x!==o && --limit) {
o=x;
x = ((k-1n)*x + val/x**(k-1n))/k;
}
return x;
}
// Example: 24 -> 2, 2, 2, 3
function repeatedPrimeFactors (n,list) {
if (arguments.length == 1) list = "";
if (n % 2n == 0) return repeatedPrimeFactors(n/2n, list + "*2")
else if (n % 3n == 0) return repeatedPrimeFactors(n/3n, list + "*3")
var sqrt = rootnth(n);
let k = 5n;
while (k <= sqrt) {
if (n % k == 0) return repeatedPrimeFactors(n/k, list + "*" + k)
if (n % (k+2n) == 0) return repeatedPrimeFactors(n/(k+2n), list + "*" + (k+2n))
k += 6n;
}
list = list + "*" + n;
return list;
}
var q = 11111111111111111n; // seventeen ones
var t = (new Date()).getTime();
var count = repeatedPrimeFactors(BigInt(q)).substr(1);
console.log(count);
console.log(("elapsed=" + (((new Date()).getTime())-t)+"ms");
Here I try for the factors 2 and 3, followed by alternatingly adding 2 anf 4 (5,7,11,13,17,...) until the square root of the number.
Seventeen ones (which is not prime) takes about 1 second and nineteen ones (which is prime) eight seconds (Firefox).
Here is the solution with the nested function using the filter method.
function primeFactors(params) {
function prime(number) {
for (let i = 2; i < number + 1; ) {
if (number === 2) {
return true;
}
if (number % i === 0 && number !== i) {
return false;
} else if (i < number) {
i++;
} else {
return true;
}
}
}
let containerPrime = [];
let containerUnPrime = [];
for (let i = 0; i < params; i++) {
if (prime(i)) {
containerPrime.push(i);
} else {
containerUnPrime.push(i);
}
}
return containerPrime.filter((e) => params % e === 0);
}
console.log(primeFactors(13195));
function primeFactorization(n) {
let factors = [];
while (n % 2 === 0) {
factors.push(2);
n = n / 2;
}
for (let i = 3; i <= Math.sqrt(n); i += 2) {
while (n % i === 0) {
factors.push(i);
n = n / i;
}
}
if (n > 2) {
factors.push(n);
}
return factors;
}
console.log(primeFactorization(100));
The answer with O(sqrt(n)) complexity, it's faster than O(n):
const number = 13195;
let divisor = 2;
const result = [];
let n = number;
while (divisor * divisor <= number) {
if (n % divisor === 0) {
result.push(divisor);
n /= divisor;
} else {
divisor++;
}
}
if (n > 1) {
result.push(n);
}
console.log(result);
The above code (the code which has while loop) is correct, but there is one small correction in that code.
var num, i, factorsArray = [];
function primeFactor(num) {
for (i = 2; i <= num; i++) {
while (num % i == 0) {
factorsArray.push(i);
num = num / 2;
}
}
}
primeFactor(18);
var newArray = Array.from(new Set(factorsArray));
document.write(newArray);
This is my solution
function prime(n) {
for (var i = 1; i <= n; i++) {
if (n%i===0) {
myFact.push(i);
var limit = Math.sqrt(i);
for (var j = 2; j < i; j++) {
if (i%j===0) {
var index = myFact.indexOf(i);
if (index > -1) {
myFact.splice(index, 1);
}
}
}
}
}
}
var n = 100, arr =[],primeNo = [],priFac=[];
for(i=0;i<=n;i++){
arr.push(true);
}
//console.log(arr)
let uplt = Math.sqrt(n)
for(j=2;j<=uplt;j++){
if(arr[j]){
for(k=j*j;k<=n;k+=j){
arr[k] = false;
}
}
}
for(l=2;l<=n;l++){
if(arr[l])
primeNo.push(l)
}
for(m=0;m<primeNo.length;m++){
if(n%primeNo[m]==0)
priFac.push(primeNo[m])
}
console.log(...priFac);
http://jsfiddle.net/xCX9W/8/
I noticed this question on Code Review and decided to play with one of the answers' JSfiddles to look at a long list of primes. However, his answer only reached 7. Why?
function findPrimes(lowerLimit, upperLimit) {
var primes = []; // will become a list of prime numbers
if (lowerLimit === 2) {
primes.push(2);
}
if (lowerLimit % 2 === 0) {
lowerLimit++;
}
primes_loop: for (var n = lowerLimit; n < upperLimit; n = n + 2) {
for (var i = 2; i < n; i++) {
if (n % i === 0) {
break primes_loop; // n is not prime if condtion is ture
}
}
primes.push(n); // update prime list with the prime number
}
for (var index = 0; index < primes.length; index++) {
$("#body").append(primes[index] + '<br/>');
}
}
findPrimes(2, 150);
It should be continue primes_loop instead of break primes_loop. Currently when it reaches a composite number (the first being 9 as it is incrementing by 2) it breaks out of the outer loop and stops the search entirely instead of just skipping that number.
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.