How to find prime numbers between 0 - 100? - javascript

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

How to limit a number between several numbers (get the most nearest small number)? [duplicate]

Example: I have an array like this: [0,22,56,74,89] and I want to find the closest number downward to a different number. Let's say that the number is 72, and in this case, the closest number down in the array is 56, so we return that. If the number is 100, then it's bigger than the biggest number in the array, so we return the biggest number. If the number is 22, then it's an exact match, just return that. The given number can never go under 0, and the array is always sorted.
I did see this question but it returns the closest number to whichever is closer either upward or downward. I must have the closest one downward returned, no matter what.
How do I start? What logic should I use?
Preferably without too much looping, since my code is run every second, and it's CPU intensive enough already.
You can use a binary search for that value. Adapted from this answer:
function index(arr, compare) { // binary search, with custom compare function
var l = 0,
r = arr.length - 1;
while (l <= r) {
var m = l + ((r - l) >> 1);
var comp = compare(arr[m]);
if (comp < 0) // arr[m] comes before the element
l = m + 1;
else if (comp > 0) // arr[m] comes after the element
r = m - 1;
else // arr[m] equals the element
return m;
}
return l-1; // return the index of the next left item
// usually you would just return -1 in case nothing is found
}
var arr = [0,22,56,74,89];
var i=index(arr, function(x){return x-72;}); // compare against 72
console.log(arr[i]);
Btw: Here is a quick performance test (adapting the one from #Simon) which clearly shows the advantages of binary search.
var theArray = [0,22,56,74,89];
var goal = 56;
var closest = null;
$.each(theArray, function(){
if (this <= goal && (closest == null || (goal - this) < (goal - closest))) {
closest = this;
}
});
alert(closest);
jsFiddle http://jsfiddle.net/UCUJY/1/
Array.prototype.getClosestDown = function(find) {
function getMedian(low, high) {
return (low + ((high - low) >> 1));
}
var low = 0, high = this.length - 1, i;
while (low <= high) {
i = getMedian(low,high);
if (this[i] == find) {
return this[i];
}
if (this[i] > find) {
high = i - 1;
}
else {
low = i + 1;
}
}
return this[Math.max(0, low-1)];
}
alert([0,22,56,74,89].getClosestDown(75));
Here's a solution without jQuery for more effiency. Works if the array is always sorted, which can easily be covered anyway:
var test = 72,
arr = [0,56,22,89,74].sort(); // just sort it generally if not sure about input, not really time consuming
function getClosestDown(test, arr) {
var num = result = 0;
for(var i = 0; i < arr.length; i++) {
num = arr[i];
if(num <= test) { result = num; }
}
return result;
}
Logic: Start from the smallest number and just set result as long as the current number is smaller than or equal the testing unit.
Note: Just made a little performance test out of curiosity :). Trimmed my code down to the essential part without declaring a function.
Here's an ES6 version using reduce, which OP references. Inspired by this answer get closest number out of array
lookup array is always sorted so this works.
const nearestBelow = (input, lookup) => lookup.reduce((prev, curr) => input >= curr ? curr : prev);
const counts = [0,22,56,74,89];
const goal = 72;
nearestBelow(goal, counts); // result is 56.
Not as fast as binary search (by a long way) but better than both loop and jQuery grep https://jsperf.com/test-a-closest-number-function/7
As we know the array is sorted, I'd push everything that asserts as less than our given value into a temporary array then return a pop of that.
var getClosest = function (num, array) {
var temp = [],
count = 0,
length = a.length;
for (count; count < length; count += 1) {
if (a[count] <= num) {
temp.push(a[count]);
} else {
break;
}
}
return temp.pop();
}
getClosest(23, [0,22,56,74,89]);
Here is edited from #Simon.
it compare closest number before and after it.
var test = 24,
arr = [76,56,22,89,74].sort(); // just sort it generally if not sure about input, not really time consuming
function getClosest(test, arr) {
var num = result = 0;
var flag = 0;
for(var i = 0; i < arr.length; i++) {
num = arr[i];
if(num < test) {
result = num;
flag = 1;
}else if (num == test) {
result = num;
break;
}else if (flag == 1) {
if ((num - test) < (Math.abs(arr[i-1] - test))){
result = num;
}
break;
}else{
break;
}
}
return result;
}

For loop in which the counter goes up to a value generated by Math.floor()

I'm a new web developer, been learning web dev for around 8-9 months. I recently became a mentor for new students in the bootcamp I graduated and I wanted to write a simple program to calculate all prime numbers up to a given upper limit. I have solved the exact same problem in C, C++ and Python. I am using the "naive" implementation, not the Sieve of Eratosthenes.
This is the code that works:
"use strict";
function primeNumbers() {
let highNumber;
highNumber = window.prompt("Calculate all prime numbers up to:");
for (let i = 2; i <= highNumber; i++) {
let numberOfDivisors = 0;
for (let j = 2; j < highNumber; j++) {
if (i % j == 0) numberOfDivisors += 1;
}
if (numberOfDivisors == 1) console.log(i);
}
}
Of course, j doesn't have to go all the way up to highNumber, as for any number, all possible divisors are less than half of the number. Thus, I changed the inside for loop making j only going up to Math.round(highNumber / 2 + 1):
"use strict";
function primeNumbers() {
let highNumber;
highNumber = window.prompt("Calculate all prime numbers up to:");
for (let i = 2; i <= highNumber; i++) {
let numberOfDivisors = 0;
for (let j = 2; j < Math.round(highNumber / 2 + 1); j++) {
if (i % j == 0) numberOfDivisors += 1;
}
if (numberOfDivisors == 1) console.log(i);
}
}
But this somehow breaks the code and causes unexpected results. I know all numbers are technically floating point numbers in JavaScript, but I thought that using Math.floor() would help me deal with that.
Any ideas on why this isn't working and what can be done? Thanks!
Try this.
// Utility function to create a range starting from 2
const range = (num: number) => [...Array(num + 1).keys()].slice(2);
const primeNumbers = (limit: number) => {
// Create a range based on the limit
const arr = range(limit);
// Create an array for the prime numbers which will be returned.
// Hardcode 1
const prime: number[] = [1];
// Loop through the range
for (const x of arr) {
// Create an array of divisors by filtering through
// new range based on x
const divisors = range(x).filter((num) => !(x % num));
// If there is only 1 divisor and it === x, it is prime
if (divisors.length === 1 && divisors[0] === x) prime.push(x);
}
return prime;
};
console.log(primeNumbers(50).length);
Here is the compiled TypeScript:
"use strict";
const range = (num) => [...Array(num + 1).keys()].slice(2);
const primeNumbers = (limit) => {
const arr = range(limit);
const prime = [1];
for (const x of arr) {
const divisors = range(x).filter((num) => !(x % num));
if (divisors.length === 1 && divisors[0] === x)
prime.push(x);
}
return prime;
};
console.log(primeNumbers(50).length);
A number always have two divisors, 1 and the number itself. j != i would ensure that an unnecessary computation does not takes place. I have initialized numberOfDivisors as 2 in the declaration. As we iterate, we check if numberOfDivisors increases any further. If so, that is not a prime number.
"use strict";
function primeNumbers() {
let highNumber;
highNumber = window.prompt("Calculate all prime numbers up to:");
for (let i = 2; i <= highNumber; i++) {
let numberOfDivisors = 2;
for (let j = 2; j < Math.round(highNumber / 2 + 1), j != i; j++) {
if (i % j == 0) numberOfDivisors += 1;
}
if (numberOfDivisors == 2) console.log(i);
}
}

Better solution for finding numbers with exactly 3 divisors

I was studying some programming and I found an exercise to write an algorithm finding "threesome numbers" (numbers that are divisible by exactly 3 numbers). I wrote this:
function threesomeNumber(N) {
var found = 0;
var i = 1;
var numberOfDivisions = 1;
while (found < N) {
for (var j = 2; j <= i; j++) {
if (i % j === 0) {
numberOfDivisions++;
}
}
if (numberOfDivisions === 3) {
found++;
console.log(found + " = " + i);
}
numberOfDivisions = 1;
i++;
}
}
The problem is it's running kinda slow and I was wondering if it can be done quicker. Does anybody know of a more optimized solution? I want it to find N consecutive threesome numbers.
The only threesome numbers are squares of primes (divisors 1, p, p^2). Just do Erathostenes and return the squares.
Proof: If it has an odd number of divisors it is known to be a square. Since 1 and n^2 are always divisors of n^2, we may only have one more divisor, i.e. n. Any divisor of n would be another divisor of n^2, therefore n is prime.
Example (based on given code):
function threesomeNumber(N) {
var found = 0;
var i = 2;
var prime = true;
while (found < N) {
// Naive prime test, highly inefficient
for (var j = 2; j*j <= i; j++) {
if (i % j === 0) {
prime = false;
}
}
if (prime) {
found++;
console.log(found + " = " + (i*i));
}
prime = true;
i++;
}
}
You could implement an algorithm based on the sieve of Eratosthenes. The only change is that you don't mark the multiples of found primes, but the multiples of found numbers which have at least 3 divisors. The reason is that you can be sure that the multiples of these numbers have more than 3 divisors.
EDIT: Hermann's solution is the best for "threesomes". My idea is more general and applicable for "N-somes".
A more optimized solution is to find the first N Prime numbers and square them. The idea behind that is that prime numbers are divisible by only two numbers. So numbers divisible by only three numbers have an extra divider which must be its square root. It must be a prime so it doesn't add extra divider to the main number dividers.
function threesomeNumber(N){
return firstPrimes(N).map(function(x){return x*x})
}
Where firstPrimes is a function that returns the first N primes.
Here's a simple one:
function threesomeNumber(N)
{
var found = 0;
var i = 1;
var numberOfDivisions = 1;
while(found < N)
{
for(var j = 2; j <= i; j++)
{
if(i % j === 0)
numberOfDivisions++;
// Stop trying if more that 3 Divisions are Found
if(numberOfDivisions > 3)
break;
}
if(numberOfDivisions === 3)
{
found++;
console.log(found + " = " + i);
}
numberOfDivisions = 1;
i++;
}
}
Here is one with time complexity= O(N^(1/2)*N^(1/4))
public int exactly3Divisors(int N)
{
int count=0,flag=0;
for(int i=2;i*i<=N;i++){
for(int j=2;j*j<=i;j++){
if(i%j==0){
flag=1;
break;
}
}
if(flag==0){
count++;
}
flag=0;
}
return count;
}
int threesomeNumber(int N)
{
//Your code here
int num =0;
bool prime = true;
for(int i=2; i<=sqrt(N); i++)
{
for(int j=2; j<i; j++)
{
if(i % j == 0)
{
prime = false;
break;
}
}
if(prime)
{
num++;
}
prime = true;
}
return num;
}

Is there any way to increase performance for this for loop in JS?

Im trying to solve project euler 10 problem (find the sum of all the primes below two million), but the code takes forever to finish, how do i make it go faster?
console.log("Starting...")
var primes = [1000];
var x = 0;
var n = 0;
var i = 2;
var b = 0;
var sum = 0;
for (i; i < 2000000; i++) {
x = 0;
if (i === 2) {
primes[b] = i
sum += primes[b];
console.log(primes[b]);
b++;
}
for (n = i - 1; n > 1; n--) {
if (i % n === 0) {
x++;
}
if (n === 2 && x === 0) {
primes[b] = i;
sum += primes[b];
console.log(primes[b]);
b++;
}
}
}
console.log(sum)
The biggest super easy things you can do to make this a lot faster:
Break out of the inner loop when you find a divisor!
When you're checking for primality, start with the small divisors instead of the big ones. You'll find the composites a lot faster.
You only have to check for divisors <= Math.sqrt(n)
You only need to check prime divisors. You have a list of them.
Process 2 outside the loop, and then only do odd numbers inside the loop: for(i=3;i<2000000;i+=2)
Here is another version based on the Sieve of Eratosthenes. It requires much more memory but if this does not concern you it's also pretty fast.
// just a helper to create integer arrays
function range(from, to) {
var numbers = [];
for (var i=from ; i<=to ; i++) {
numbers.push(i);
}
return numbers;
}
function primesUpTo(limit) {
if (limit < 2) return [];
var sqrt = Math.floor(Math.sqrt(limit));
var testPrimes = primesUpTo(sqrt);
var numbers = range(sqrt+1, limit);
testPrimes.forEach(function(p) {
numbers = numbers.filter(function(x) { return x % p > 0 });
});
return testPrimes.concat(numbers);
}
var primes = primesUpTo(2000000);
var sum = primes.reduce(function(acc, e) { return acc + e });
Since you keep an array of your primes anyway, you can split the process in two steps:
Generating the primes up to your limit of 2 million
and summing up.
As pointed out by others, you need only check whether a candidate number is divisable by another prime not larger than the square root of the candidate. If you can write a number as a product of primes, then one of those primes will always be lower than or equal to the number's square root.
This code can be optimized further but it is several orders of magnitude faster than your initial version:
function primesUpTo(limit) {
if (limit < 2) return [];
var sqrt = Math.floor(Math.sqrt(limit));
var testPrimes = primesUpTo(sqrt);
var result = [].concat(testPrimes);
for (var i=sqrt+1 ; i<=limit ; i++) {
if (testPrimes.every(function(x) { return (i % x) > 0 })) {
result.push(i);
}
}
return result;
}
var primes = primesUpTo(2000000);
var sum = primes.reduce(function(acc, e) { return acc + e });

Peak and Flag Codility latest chellange

I'm trying to solve the latest codility.com question (just for enhance my skills). I tried allot but not getting more than 30 marks there so now curious what exactly I am missing in my solution.
The question says
A non-empty zero-indexed array A consisting of N integers is given. A peak is an array element which is larger than its neighbours. More precisely, it is an index P such that
0 < P < N − 1 and A[P − 1] < A[P] > A[P + 1]
For example, the following array A:
A[0] = 1
A[1] = 5
A[2] = 3
A[3] = 4
A[4] = 3
A[5] = 4
A[6] = 1
A[7] = 2
A[8] = 3
A[9] = 4
A[10] = 6
A[11] = 2
has exactly four peaks: elements 1, 3, 5 and 10.
You are going on a trip to a range of mountains whose relative heights are represented by array A. You have to choose how many flags you should take with you. The goal is to set the maximum number of flags on the peaks, according to certain rules.
Flags can only be set on peaks. What's more, if you take K flags, then the distance between any two flags should be greater than or equal to K. The distance between indices P and Q is the absolute value |P − Q|.
For example, given the mountain range represented by array A, above, with N = 12, if you take:
> two flags, you can set them on peaks 1 and 5;
> three flags, you can set them on peaks 1, 5 and 10;
> four flags, you can set only three flags, on peaks 1, 5 and 10.
You can therefore set a maximum of three flags in this case.
Write a function that, given a non-empty zero-indexed array A of N integers, returns the maximum number of flags that can be set on the peaks of the array.
For example, given the array above
the function should return 3, as explained above.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [0..1,000,000,000].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(N), beyond input storage (not counting the
storage required for input arguments).
So I tried this code according to my understanding of question
var A = [1,5,3,4,3,4,1,2,3,4,6,2];
function solution(A) {
array = new Array();
for (i = 1; i < A.length - 1; i++) {
if (A[i - 1] < A[i] && A[i + 1] < A[i]) {
array.push(i);
}
}
//console.log(A);
//console.log(array);
var position = array[0];
var counter = 1;
var len = array.length;
for (var i = 0; i < len; i++) {
if (Math.abs(array[i+1] - position) >= len) {
position = array[i+1];
counter ++;
}
}
console.log("total:",counter);
return counter;
}
The above code works for sample array elements: [1,5,3,4,3,4,1,2,3,4,6,2]
Get peaks at indices: [1, 3, 5, 10] and set flags at 1, 5, and 10 (total 3)
But codility.com says it fails on array [7, 10, 4, 5, 7, 4, 6, 1, 4, 3, 3, 7]
My code get peaks at indices: [1, 4, 6, 8] and set flags at 1 and 6 (total 2)
but coditity.com says it should be 3 flags. (no idea why)
Am I miss-understanding the question ?
Please I am only looking for the hint/algo. I know this question is already asked by someone and solved on private chatroom but on that page I tried to get the help with that person but members rather flagging my posts as inappropriate answer so I am asking the question here again.
P.S: You can try coding the challenge yourself here!
This is a solution with better upper complexity bounds:
time complexity: O(sqrt(N) * log(N))
space complexity: O(1) (over the original input storage)
Python implementation
from math import sqrt
def transform(A):
peak_pos = len(A)
last_height = A[-1]
for p in range(len(A) - 1, 0, -1):
if (A[p - 1] < A[p] > last_height):
peak_pos = p
last_height = A[p]
A[p] = peak_pos
A[0] = peak_pos
def can_fit_flags(A, k):
flag = 1 - k
for i in range(k):
# plant the next flag at A[flag + k]
if flag + k > len(A) - 1:
return False
flag = A[flag + k]
return flag < len(A) # last flag planted successfully
def solution(A):
transform(A)
lower = 0
upper = int(sqrt(len(A))) + 2
assert not can_fit_flags(A, k=upper)
while lower < upper - 1:
next = (lower + upper) // 2
if can_fit_flags(A, k=next):
lower = next
else:
upper = next
return lower
Description
O(N) preprocessing (done inplace):
A[i] := next peak or end position after or at position i
(i for a peak itself, len(A) after last peak)
If we can plant k flags then we can certainly plant k' < k flags as well.
If we can not plant k flags then we certainly can not plant k' > k flags either.
We can always set 0 flags.
Let us assume we can not set X flags.
Now we can use binary search to find out exactly how many flags can be planted.
Steps:
1. X/2
2. X/2 +- X/4
3. X/2 +- X/4 +- X/8
...
log2(X) steps in total
With the preprocessing done before, each step testing whether k flags can be planted can be performed in O(k) operations:
flag(0) = next(0)
flag(1) = next(flag(1) + k)
...
flag(k-1) = next(flag(k-2) + k)
total cost - worst case - when X - 1 flags can be planted:
== X * (1/2 + 3/4 + ... + (2^k - 1)/(2^k))
== X * (log2(X) - 1 + (<1))
<= X * log(X)
Using X == N would work, and would most likely also be sublinear, but is not good enough to use in a proof that the total upper bound for this algorithm is under O(N).
Now everything depends on finding a good X, and it since k flags take about k^2 positions to fit, it seems like a good upper limit on the number of flags should be found somewhere around sqrt(N).
If X == sqrt(N) or something close to it works, then we get an upper bound of O(sqrt(N) * log(sqrt(N))) which is definitely sublinear and since log(sqrt(N)) == 1/2 * log(N) that upper bound is equivalent to O(sqrt(N) * log(N)).
Let's look for a more exact upper bound on the number of required flags around sqrt(N):
we know k flags requires Nk := k^2 - k + 3 flags
by solving the equation k^2 - k + 3 - N = 0 over k we find that if k >= 3, then any number of flags <= the resulting k can fit in some sequence of length N and a larger one can not; solution to that equation is 1/2 * (1 + sqrt(4N - 11))
for N >= 9 we know we can fit 3 flags
==> for N >= 9, k = floor(1/2 * (1 + sqrt(4N - 11))) + 1 is a strict upper bound on the number of flags we can fit in N
for N < 9 we know 3 is a strict upper bound but those cases do not concern us for finding the big-O algorithm complexity
floor(1/2 * (1 + sqrt(4N - 11))) + 1
== floor(1/2 + sqrt(N - 11/4)) + 1
<= floor(sqrt(N - 11/4)) + 2
<= floor(sqrt(N)) + 2
==> floor(sqrt(N)) + 2 is also a good strict upper bound for a number of flags that can fit in N elements + this one holds even for N < 9 so it can be used as a generic strict upper bound in our implementation as well
If we choose X = floor(sqrt(N)) + 2 we get the following total algorithm upper bound:
O((floor(sqrt(N)) + 2) * log(floor(sqrt(N)) + 2))
{floor(...) <= ...}
O((sqrt(N) + 2) * log(sqrt(N) + 2))
{for large enough N >= 4: sqrt(N) + 2 <= 2 * sqrt(N)}
O(2 * sqrt(N) * log(2 * sqrt(N)))
{lose the leading constant}
O(sqrt(N) * (log(2) + loq(sqrt(N)))
O(sqrt(N) * log(2) + sqrt(N) * log(sqrt(N)))
{lose the lower order bound}
O(sqrt(N) * log(sqrt(N)))
{as noted before, log(sqrt(N)) == 1/2 * log(N)}
O(sqrt(N) * log(N))
QED
Missing 100% PHP solution :)
function solution($A)
{
$p = array(); // peaks
for ($i=1; $i<count($A)-1; $i++)
if ($A[$i] > $A[$i-1] && $A[$i] > $A[$i+1])
$p[] = $i;
$n = count($p);
if ($n <= 2)
return $n;
$maxFlags = min(intval(ceil(sqrt(count($A)))), $n); // max number of flags
$distance = $maxFlags; // required distance between flags
// try to set max number of flags, then 1 less, etc... (2 flags are already set)
for ($k = $maxFlags-2; $k > 0; $k--)
{
$left = $p[0];
$right = $p[$n-1];
$need = $k; // how many more flags we need to set
for ($i = 1; $i<=$n-2; $i++)
{
// found one more flag for $distance
if ($p[$i]-$left >= $distance && $right-$p[$i] >= $distance)
{
if ($need == 1)
return $k+2;
$need--;
$left = $p[$i];
}
if ($right - $p[$i] <= $need * ($distance+1))
break; // impossible to set $need more flags for $distance
}
if ($need == 0)
return $k+2;
$distance--;
}
return 2;
}
import java.util.Arrays;
import java.lang.Integer;
import java.util.ArrayList;
import java.util.List;
public int solution(int[] A)
{
ArrayList<Integer> array = new ArrayList<Integer>();
for (int i = 1; i < A.length - 1; i++)
{
if (A[i - 1] < A[i] && A[i + 1] < A[i])
{
array.add(i);
}
}
if (array.size() == 1 || array.size() == 0)
{
return array.size();
}
int sf = 1;
int ef = array.size();
int result = 1;
while (sf <= ef)
{
int flag = (sf + ef) / 2;
boolean suc = false;
int used = 0;
int mark = array.get(0);
for (int i = 0; i < array.size(); i++)
{
if (array.get(i) >= mark)
{
used++;
mark = array.get(i) + flag;
if (used == flag)
{
suc = true;
break;
}
}
}
if (suc)
{
result = flag;
sf = flag + 1;
}
else
{
ef = flag - 1;
}
}
return result;
}
C++ solution, O(N) detected
#include <algorithm>
int solution(vector<int> &a) {
if(a.size() < 3) return 0;
std::vector<int> peaks(a.size());
int last_peak = -1;
peaks.back() = last_peak;
for(auto i = ++a.rbegin();i != --a.rend();i++)
{
int index = a.size() - (i - a.rbegin()) - 1;
if(*i > *(i - 1) && *i > *(i + 1))
last_peak = index;
peaks[index] = last_peak;
}
peaks.front() = last_peak;
int max_flags = 0;
for(int i = 1;i*i <= a.size() + i;i++)
{
int next_peak = peaks[0];
int flags = 0;
for(int j = 0;j < i && next_peak != -1;j++, flags++)
{
if(next_peak + i >= a.size())
next_peak = -1;
else
next_peak = peaks[next_peak + i];
}
max_flags = std::max(max_flags, flags);
}
return max_flags;
}
100% Java solution with O(N) complexity.
https://app.codility.com/demo/results/trainingPNYEZY-G6Q/
class Solution {
public int solution(int[] A) {
// write your code in Java SE 8
int[] peaks = new int[A.length];
int peakStart = 0;
int peakEnd = 0;
//Find the peaks.
//We don't want to traverse the array where peaks hasn't started, yet,
//or where peaks doesn't occur any more.
//Therefore, find start and end points of the peak as well.
for(int i = 1; i < A.length-1; i++) {
if(A[i-1] < A[i] && A[i+1] < A[i]) {
peaks[i] = 1;
peakEnd = i + 1;
}
if(peakStart == 0) {
peakStart = i;
}
}
int x = 1;
//The maximum number of flags can be √N
int limit = (int)Math.ceil(Math.sqrt(A.length));
int prevPeak = 0;
int counter = 0;
int max = Integer.MIN_VALUE;
while(x <= limit) {
counter = 0;
prevPeak = 0;
for(int y = peakStart; y < peakEnd; y++) {
//Find the peak points when we have x number of flags.
if(peaks[y] == 1 && (prevPeak == 0 || x <= (y - prevPeak))) {
counter++;
prevPeak = y;
}
//If we don't have any more flags stop.
if(counter == x ) {
break;
}
}
//if the number of flags set on the peaks starts to reduce stop searching.
if(counter <= max) {
return max;
}
//Keep the maximum number of flags we set on.
max = counter;
x++;
}
return max;
}
}
There is a ratio between the number of flags we can take with us and
the number of flags we can set. We can not set more than √N number of
flags since N/√N = √N. If we set more than √N, we will end up with
decreasing number of flags set on the peaks.
When we increase the numbers of flags we take with us, the number of
flags we can set increases up to a point. After that point the number
of flags we can set will decrease. Therefore, when the number of
flags we can set starts to decrease once, we don't have to check the
rest of the possible solutions.
We mark the peak points at the beginning of the code, and we also
mark the first and the last peak points. This reduces the unnecessary
checks where the peaks starts at the very last elements of a large
array or the last peak occurs at the very first elements of a large
array.
Here is a C++ Solution with 100% score
int test(vector<int> &peaks,int i,int n)
{
int j,k,sum,fin,pos;
fin = n/i;
for (k=0; k< i; k++)
{
sum=0;
for (j=0; j< fin; j++)
{ pos = j + k * fin;
sum=sum + peaks[ pos ];
}
if (0==sum) return 0;
}
return 1;
}
int solution(vector<int> &A) {
// write your code in C++98
int i,n,max,r,j,salir;
n = A.size();
vector<int> peaks(n,0);
if (0==n) return 0;
if (1==n) return 0;
for (i=1; i< (n-1) ; i++)
{
if ( (A[i-1] < A[i]) && (A[i+1] < A[i]) ) peaks[i]=1;
}
i=1;
max=0;
salir =0;
while ( ( i*i < n) && (0==salir) )
{
if ( 0== n % i)
{
r=test(peaks,i,n);
if (( 1==r ) && (i>max)) max=i;
j = n/i;
r=test(peaks,j,n);
if (( 1==r ) && (j>max)) max=j;
if ( max > n/2) salir =1;
}
i++;
}
if (0==salir)
{
if (i*i == n)
{
if ( 1==test(peaks,i,n) ) max=i;
}
}
return max;
}
The first idea is that we cannot set more than sqrt(N) flags. Lets imagine that we've taken N flags, in this case we should have at least N * N items to set all the flags, because N it's the minimal distance between the flags. So, if we have N items its impossible to set more than sqrt(N) flags.
function solution(A) {
const peaks = searchPeaks(A);
const maxFlagCount = Math.floor(Math.sqrt(A.length)) + 1;
let result = 0;
for (let i = 1; i <= maxFlagCount; ++i) {
const flagsSet = setFlags(peaks, i);
result = Math.max(result, flagsSet);
}
return result;
}
function searchPeaks(A) {
const peaks = [];
for (let i = 1; i < A.length - 1; ++i) {
if (A[i] > A[i - 1] && A[i] > A[i + 1]) {
peaks.push(i);
}
}
return peaks;
}
function setFlags(peaks, flagsTotal) {
let flagsSet = 0;
let lastFlagIndex = -flagsTotal;
for (const peakIndex of peaks) {
if (peakIndex >= lastFlagIndex + flagsTotal) {
flagsSet += 1;
lastFlagIndex = peakIndex;
if (flagsSet === flagsTotal) {
return flagsSet;
}
}
}
return flagsSet;
}
Such solution has O(N) complexity. We should iterate over A to find peaks and iterate from 1 to sqrt(N) flag counts trying to set all the flags. So we have O(N + 1 + 2 + 3 ... sqrt(N)) = O(N + sqrt(N*N)) = O(N) complexity.
Above solution is pretty fast and it gets 100% result, but it can be even more optimized. The idea is to binary search the flag count. Lets take F flags and try to set them all. If excess flags are left, the answer is less tan F. But, if all the flags have been set and there is space for more flags, the answer is greater than F.
function solution(A) {
const peaks = searchPeaks(A);
const maxFlagCount = Math.floor(Math.sqrt(A.length)) + 1;
return bSearchFlagCount(A, peaks, 1, maxFlagCount);
}
function searchPeaks(A) {
const peaks = [];
for (let i = 1; i < A.length - 1; ++i) {
if (A[i] > A[i - 1] && A[i] > A[i + 1]) {
peaks.push(i);
}
}
return peaks;
}
function bSearchFlagCount(A, peaks, start, end) {
const mid = Math.floor((start + end) / 2);
const flagsSet = setFlags(peaks, mid);
if (flagsSet == mid) {
return mid;
} else if (flagsSet < mid) {
return end > start ? bSearchFlagCount(A, peaks, start, mid) : mid - 1;
} else {
return bSearchFlagCount(A, peaks, mid + 1, end);
}
}
function setFlags(peaks, flagsTotal) {
let flagsSet = 0;
let lastFlagIndex = -flagsTotal;
for (const peakIndex of peaks) {
if (peakIndex >= lastFlagIndex + flagsTotal) {
flagsSet += 1;
lastFlagIndex = peakIndex;
// It only matters that we can set more flags then were taken.
// It doesn't matter how many extra flags can be set.
if (flagsSet > flagsTotal) {
return flagsSet;
}
}
}
return flagsSet;
}
Here is the official Codility solutions of the task.
My C++ solution with 100% result
bool check(const vector<int>& v, int flags, int mid) {
if (not v.empty()) {
flags--;
}
int start = 0;
for (size_t i = 1; i < v.size(); ++i) {
if (v[i] - v[start] >= mid) {
--flags;
start = i;
}
}
return flags <= 0;
}
int solution(vector<int> &A) {
vector<int> peaks;
for (size_t i = 1; i < A.size() - 1; ++i) {
if (A[i] > A[i - 1] and A[i] > A[i + 1]) {
peaks.push_back(i);
}
}
int low = 0;
int high = peaks.size();
int res = 0;
while (low <= high) {
int mid = high - (high - low) / 2;
if (check(peaks, mid, mid)) {
low = mid + 1;
res = mid;
} else {
high = mid - 1;
}
}
return res;
}
public int solution(int[] A) {
int p = 0;
int q = 0;
int k = 0;
for (int i = 0; i < A.length; i++) {
if (i > 0 && i < A.length && (i + 1) < A.length - 1) {
if (A[i] > A[i - 1] && A[i] > A[i + 1]) {
p = i;
if (i < A.length / 2)
k++;
}
if (i > 0 && i < A.length && (A.length - i + 1) < A.length) {
if (A[A.length - i] > A[A.length - i - 1]
&& A[A.length - i] > A[A.length - i + 1] ) {
q = A.length - i;
if (i < A.length / 2)
k++;
else {
if (Math.abs(p - q) < k && p != q)
k--;
}
}
}
}
}
return k;
}
import sys
def get_max_num_peaks(arr):
peaks = [i for i in range(1, len(arr)-1, 1) if arr[i]>arr[i-1] and arr[i]>arr[i+1]]
max_len = [1 for i in peaks]
smallest_diff = [0 for i in peaks]
smallest_diff[0] = sys.maxint
for i in range(1, len(peaks), 1):
result = 1
for j in range(0, i, 1):
m = min(smallest_diff[j], peaks[i]-peaks[j])
if smallest_diff[j]>0 and m>=max_len[j]+1:
max_len[i] = max_len[j]+1
smallest_diff[i] = m
result = max(result, max_len[i])
return result
if __name__ == "__main__":
result = get_max_num_peaks([7, 10, 4, 5, 7, 4, 6, 1, 4, 3, 3, 7])
print result
I used DP to solve this problem. Here is the python code:
The max num of flags can be set for array ending at i is the max num of flags can be set on j if min(min_diff(0 .. j), j to i) is no less than max_len(0 .. j)+1
Please correct me if I'm wrong or there is a O(N) solution
I know that the answer had been provided by francesco Malagrino, but i have written my own code. for the arrays {1,5,3,4,3,4,1,2,3,4,6,2} and { 7, 10, 4, 5, 7, 4, 6, 1, 4, 3, 3, 7 } my code is working just fine. and when I took my code on the codility exams i had failed on {9, 9, 4, 3, 5, 4, 5, 2, 8, 9, 3, 1}
my answer resulted to 3 maximum flags. the way I understand it it supposed to be 3 but instead
the correct answer is 2, and also with also in respect to francesco Malagrino's solution.
what seems to be wrong in my code and how come the answer should only be 2 the fact that
distances between peaks 4, 6, 9 followed the rule.
private static int getpeak(int[] a) {
List<Integer> peak = new ArrayList<Integer>();
int temp1 = 0;
int temp2 = 0;
int temp3 = 0;
for (int i = 1; i <= (a.length - 2); i++) {
temp1 = a[i - 1];
temp2 = a[i];
temp3 = a[i + 1];
if (temp2 > temp1 && temp2 > temp3) {
peak.add(i);
}
}
Integer[] peakArray = peak.toArray(new Integer[0]);
int max = 1;
int lastFlag = 0;
for (int i = 1; i <= peakArray.length - 1; i++) {
int gap = peakArray[i] - peakArray[lastFlag];
gap = Math.abs(gap);
if (gap >= i+1) {
lastFlag = i;
max = max + 1;
}
}
return max;
}
I cam up with an algorithm for this problem that is both of O(N) and passed all of the codility tests. The main idea is that the number of flags can not be more than the square root of N. So to keep the total order linear, each iteration should be less than the square root of N too, which is the number of flags itself.
So first, I built an array nextPeak that for each index of A provides the closest flag after the index.
Then, in the second part, I iterate f over all possible number of flags from root of N back to 0 to find the maximum number of flags that can be applied on the array. In each iteration, I try to apply the flags and use the nextPeak array to find the next peak in constant time.
The code looks like this:
public int solution(int[] A){
if( A==null || A.length<3){
return 0;
}
int[] next = new int[A.length];
int nextPeak=-1;
for(int i =1; i<A.length; i++){
if(nextPeak<i){
for(nextPeak=i; nextPeak<A.length-1; nextPeak++){
if(A[nextPeak-1]<A[nextPeak] && A[nextPeak]>A[nextPeak+1]){
break;
}
}
}
next[i] = nextPeak;
}
next[0] = next[1];
int max = new Double(Math.sqrt(A.length)).intValue();
boolean failed = true ;
int f=max;
while(f>0 && failed){
int v=0;
for(int p=0; p<A.length-1 && next[p]<A.length-1 && v<f; v++, p+=max){
p = next[p];
}
if(v<f){
f--;
} else {
failed = false;
}
}
return f;
}
Here is a 100% Java solution
class Solution {
public int solution(int[] A) {
int[] nextPeaks = nextPeaks(A);
int flagNumebr = 1;
int result = 0;
while ((flagNumebr-1)*flagNumebr <= A.length) {
int flagPos = 0;
int flagsTaken = 0;
while (flagPos < A.length && flagsTaken < flagNumebr) {
flagPos = nextPeaks[flagPos];
if (flagPos == -1) {
// we arrived at the end of the peaks;
break;
}
flagsTaken++;
flagPos += flagNumebr;
}
result = Math.max(result, flagsTaken);
flagNumebr++;
}
return result;
}
private boolean[] createPeaks(int[] A) {
boolean[] peaks = new boolean[A.length];
for (int i = 1; i < A.length-1; i++) {
if (A[i - 1] < A[i] && A[i] > A[i + 1]) {
peaks[i] = true;
}
}
return peaks;
}
private int[] nextPeaks (int[] A) {
boolean[] peaks = createPeaks(A);
int[] nextPeaks = new int[A.length];
// the last position is always -1
nextPeaks[A.length-1] = -1;
for (int i = A.length-2; i >= 0 ; i--) {
nextPeaks[i] = peaks[i] ? i : nextPeaks[i+1];
}
return nextPeaks;
}
}
to solve this problem:
you have to find peaks
calculate distance (indices differences) between every 2 peaks
Initially the number of flags is the same number of peaks
compare distance between every 2 peaks with the initially specified number of flags ([P - Q] >= K)
after the comparison you will find that you have to avoid some peaks
the final number of maximum flags is the same number of remain peaks
** I'm still searching for how to write the best optimized code for this problem
C# Solution with 100% points.
using System;
using System.Collections.Generic;
class Solution {
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
List<int> peaks = new List<int>();
for (int i = 1; i < A.Length - 1; i++)
{
if (A[i - 1] < A[i] && A[i + 1] < A[i])
{
peaks.Add(i);
}
}
if (peaks.Count == 1 || peaks.Count == 0)
{
return peaks.Count;
}
int leastFlags = 1;
int mostFlags = peaks.Count;
int result = 1;
while (leastFlags <= mostFlags)
{
int flags = (leastFlags + mostFlags) / 2;
bool suc = false;
int used = 0;
int mark = peaks[0];
for (int i = 0; i < peaks.Count; i++)
{
if (peaks[i] >= mark)
{
used++;
mark = peaks[i] + flags;
if (used == flags)
{
suc = true;
break;
}
}
}
if (suc)
{
result = flags;
leastFlags = flags + 1;
}
else
{
mostFlags = flags - 1;
}
}
return result;
}
}
100% working JS solution:
function solution(A) {
let peaks = [];
for (let i = 1; i < A.length - 1; i++) {
if (A[i] > A[i - 1] && A[i] > A[i + 1]) {
peaks.push(i);
}
}
let n = peaks.length;
if (n <= 2) {
return n;
}
let maxFlags = Math.min(n, Math.ceil(Math.sqrt(A.length)));
let distance = maxFlags;
let rightPeak = peaks[n - 1];
for (let k = maxFlags - 2; k > 0; k--) {
let flags = k;
let leftPeak = peaks[0];
for (let i = 1; i <= n - 2; i++) {
if (peaks[i] - leftPeak >= distance && rightPeak - peaks[i] >= distance) {
if (flags === 1) {
return k + 2;
}
flags--;
leftPeak = peaks[i];
}
if (rightPeak - peaks[i] <= flags * (distance + 1)) {
break;
}
}
if (flags === 0) {
return k + 2;
}
distance--;
}
return 2;
}
100 % python O(N) detected.
import math
def solution(A):
N=len(A)
#Trivial cases
if N<3:
return 0
Flags_Idx=[]
for p in range(1,N-1):
if A[p-1]<A[p] and A[p]>A[p+1] :
Flags_Idx.append(p)
if len(Flags_Idx)==0:
return 0
if len(Flags_Idx)<=2:
return len(Flags_Idx)
Start_End_Flags=Flags_Idx[len(Flags_Idx)-1]-Flags_Idx[0]
#Maximum number of flags N is such that Start_End_Flags/(N-1)>=N
#After solving a second degree equation we obtain the maximal value of N
num_max_flags=math.floor(1.0+math.sqrt(4*Start_End_Flags+1.0))/2.0
#Set the current number of flags to its total number
len_flags=len(Flags_Idx)
min_peaks=len(Flags_Idx)
p=0
#Compute the minimal number of flags by checking each indexes
#and comparing to the maximal theorique value num_max_flags
while p<len_flags-1:
add = 1
#Move to the next flag until the condition Flags_Idx[p+add]-Flags_Idx[p]>=min(num_max_flags,num_flags)
while Flags_Idx[p+add]-Flags_Idx[p]<min(num_max_flags,min_peaks):
min_peaks-=1
if p+add<len_flags-1:
add+=1
else:
p=len_flags
break
p+=add
if num_max_flags==min_peaks:
return min_peaks
#Bisect the remaining flags : check the condition
#for flags in [min_peaks,num_max_flags]
num_peaks=min_peaks
for nf in range (min_peaks,int(num_max_flags)+1):
cnt=1
p=0
while p<len_flags-1:
add = 1
while Flags_Idx[p+add]-Flags_Idx[p]<nf:
if p+add<len_flags-1:
add+=1
else:
cnt-=1
p=len_flags
break
p+=add
cnt+=1
num_peaks=max(min(cnt,nf),num_peaks)
return num_peaks
I first computed the maximal possible number of flags verifying the condition
Interval/(N-1) >= N , where Interval is the index difference between first and last flag. Then browsing all the flags comparing with the minimum of this value and the current number of flags. Subtract if the condition is not verified.
Obtained the minimal number of flags and use it as a starting point to check the condition
on the remaining ones (in interval [min_flag,max_flag]).
100% python solution which is far simpler than the one posted above by #Jurko Gospodnetić
https://github.com/niall-oc/things/blob/master/codility/flags.py
https://app.codility.com/demo/results/training2Y78NP-VHU/
You don't need to do a binary search on this problem. MAX flags is the (square root of the (spread between first and last flag)) +1. First peak at index 9 and last peak at index 58 means the spread is sqrt(49) which is (7)+1. So try 8 flags then 7 then 6 and so on. You should break after your solution peaks! no need to flog a dead horse!
def solution(A):
peak=[x for x in range(1,len(A))if A[x-1]<A[x]>A[x+1]]
max_flag=len(peak)
for x in range(1,max_flag+1):
for y in range(x-1):
if abs(peak[y]-peak[y+1])>=max_flag:
max_flag=max_flag-1
print(max_flag)**strong text**
I got 100% with this solution in Java. I did one thing for the first loop to find peaks, i.e. after finding the peak I am skipping the next element as it is less than the peak.
I know this solution can be further optimized by group members but this is the best I can do as of now, so please let me know how can I optimize this more.
Detected time complexity: O(N)
https://app.codility.com/demo/results/trainingG35UCA-7B4/
public static int solution(int[] A) {
int N = A.length;
if (N < 3)
return 0;
ArrayList<Integer> peaks = new ArrayList<Integer>();
for (int i = 1; i < N - 1; i++) {
if (A[i] > A[i - 1]) {
if (A[i] > A[i + 1]) {
peaks.add(i);
i++;// skip for next as A[i + 1] < A[i] so no need to check again
}
}
}
int size = peaks.size();
if (size < 2)
return size;
int k = (int) Math.sqrt(peaks.get(size - 1) - peaks.get(0))+1; // added 1 to round off
int flagsLeft = k - 1; // one flag is used for first element
int maxFlag = 0;
int prevEle = peaks.get(0);
while (k > 0) { // will iterate in descending order
flagsLeft = k - 1; // reset first peak flag
prevEle = peaks.get(0); // reset the flag to first element
for (int i = 1; i < size && flagsLeft > 0; i++) {
if (peaks.get(i) - prevEle >= k) {
flagsLeft--;
prevEle = peaks.get(i);
}
if ((size - 1 - i) < flagsLeft) { // as no. of peaks < flagsLeft
break;
}
}
if (flagsLeft == 0 && maxFlag < k) {
maxFlag = k;
break; // will break at first highest flag as iterating in desc order
}
k--;
}
return maxFlag;
}
int solution(int A[], int N) {
int i,j,k;
int count=0;
int countval=0;
int count1=0;
int flag;
for(i=1;i<N-1;i++)
{`enter code here`
if((A[i-1]<A[i]) && (A[i]>A[i+1]))
{
printf("%d %d\n",A[i],i);
A[count++]=i;
i++;
}
}
j=A[0];
k=0;
if (count==1 || count==0)
return count;
if (count==2)
{
if((A[1]-A[0])>=count)
return 2;
else
return 1;
}
flag=0;
// contval=count;
count1=1;
countval=count;
while(1)
{
for(i=1;i<count;i++)
{
printf("%d %d\n",A[i],j);
if((A[i]-j)>=countval)
{
printf("Added %d %d\n",A[i],j);
count1++;
j=A[i];
}
/* if(i==count-1 && count1<count)
{
j=A[0];
i=0;
count1=1;
}*/
}
printf("count %d count1 %d \n",countval,count1);
if (count1<countval)
{
count1=1;
countval--;
j=A[0];
}
else
{
break; }
}
return countval;
}

Categories

Resources