Prime Number Simple Test - javascript

the following code always seems to return true whatever value of n I plug in and I can't see why. If n = 8, then arr2 should contain the value of i for 2, 4 and 8?
Can someone please explain? Thank you very much.
var primetest = function(n){
var divisor = [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
for (var i = 0; i < divisor.length; i++) {
var arr2 = [];
if(n%divisor[i] == 0) {arr2.push(i);}
if(arr2.length > 1) {prime = false;}
else {prime = true;}
return prime;
};
};

Couple of problems in your original code:
You are doing only one iteration
You declare the array holding divisions inside the loop, causing it to always have maximum 1 item.
Quick fix of the above would be:
var primetest = function(n){
var divisor = [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
var arr2 = [];
for (var i = 0; i < divisor.length; i++) {
if(n%divisor[i] == 0) {
arr2.push(i);
}
}
return arr2.length <=1;
}
Live test case.
Optimized code that does not iterate through the whole list of divisors if not reuired (guess that's what you were trying to achieve) is:
var primetest = function(n){
var divisor = [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
var arr2 = [];
for (var i = 0; i < divisor.length; i++) {
if(n % divisor[i] === 0) {
arr2.push(i);
if (arr2.length > 1)
return false;
}
}
return true;
};
Updated fiddle.

Two problems:
Don't declare you array inside the loop, because it will reset in every loop.
And move your return outside of the loop because your function will return at first loop, wich always true for odd numbers(n%2 = 0 for even numbers).
JSFiddle
function primetest(n){
var divisor = [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
var arr2 = [];
for (var i = 0; i < divisor.length; i++) {
if((n%divisor[i]) === 0)
arr2.push(i);
if(arr2.length > 1)
prime = false;
else prime = true;
};
return prime;
}
$(function (){
var pprime = 7;
if(primetest(pprime))
alert("ok");
});

Return the first 1001 positions into an array of prime numbers.
Usefull code to modify, enjoy!
//cum calculam daca un numar este prim
//chiar mai mult - care este al 1001-lea nr prim
function isPrime(num) {
if(num < 2) return false;
for (var i = 2; i < num; i++) {
if(num%i===0)
return false;
}
return true;
}
var shir=[];
var j=0;
var i=1;
while(j<1001)
{
if(isPrime(i))
{shir[j]=i;
j++;i++}
else{i++}
}
console.log(shir);
console.log (shir[0]);
console.log (shir[1000]);
alert("Al 1001-lea numar prim este " + shir[1000]);

Your condition
if(arr2.length > 1) {prime = false;}
is checking for >1 instead of >0 or >=1 which is ignoring the prime condition that you specified. Hence your corrected code would be something like this:
var primetest = function(n){
var divisor = [2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
for (var i = 0; i < divisor.length; i++) {
var arr2 = [];
if(n%divisor[i] == 0) {arr2.push(i);}
if(arr2.length > 0) {prime = false;}
else {prime = true;}
return prime;
};
};
if(arr2.length > 1) {prime = false;}
There are better ways to check for prime number. Here's the fastest one I could lay my hands on:
var primetest = function(n) {
if (isNaN(n) || !isFinite(n) || n%1 || n<2) return false;
if (n==leastFactor(n)) return true;
return false;
}
// leastFactor(n)
// returns the smallest prime that divides n
// NaN if n is NaN or Infinity
// 0 if n=0
// 1 if n=1, n=-1, or n is not an integer
leastFactor = function(n){
if (isNaN(n) || !isFinite(n)) return NaN;
if (n==0) return 0;
if (n%1 || n*n<2) return 1;
if (n%2==0) return 2;
if (n%3==0) return 3;
if (n%5==0) return 5;
var m = Math.sqrt(n);
for (var i=7;i<=m;i+=30) {
if (n%i==0) return i;
if (n%(i+4)==0) return i+4;
if (n%(i+6)==0) return i+6;
if (n%(i+10)==0) return i+10;
if (n%(i+12)==0) return i+12;
if (n%(i+16)==0) return i+16;
if (n%(i+22)==0) return i+22;
if (n%(i+24)==0) return i+24;
}
return n;
}
Source: http://www.javascripter.net/faq/numberisprime.htm

Related

Lucky palindrome with longest prime number need help i couldn't able to do

A string is called a palindrome if it may be read the same way in either direction. For example, “12321” is a palindrome, but “12341” is not. A palindrome string can itself compose of one or more palindrome sub-strings. Now, your task is to find out the length (denoted by L) of the longest palindrome sub-string, maximum-length contiguous substring of a given
string that is also a palindrome, and print "YES" if it is lucky otherwise print "NO". A palindrome sub-string is called lucky iff it's length is a prime number.
For example : Consider a string s =”122321”. The longest palindrome sub-strings in s is of length 3. Hence, you need to output "YES" (quotes only for clarity).
function solution(r) {
if (r.match(/[a-z]/g) || r.match(/[A-Z]/g) || r.match(/[0-9]/g)) {
for (var t = gettingPrimeList(r), o = "", n = 0; n < r.length; n++)
for (var e = t.length; t > 0; t--) {
var a = r.substr(n, t[e - 1]);
console.log(a);
for (var i = a.length; i > 0; i--) {
var g = a.substr(0, i);
console.log(g);
var s = g.split("").reverse().join("");
if (g == s) {
o = "YES";
break
}
o = "NO"
}
}
return o
}
}
function gettingPrimeList(r) {
for (var t = [], o = 2; o <= r.length; o++) {
for (var n = !1, e = 2; e <= o; e++) o % e == 0 && e !== o && (n = !0);
!1 === n && t.push(o)
}
return t
}
alert(solution("random12321random"));
You can do that in following steps:
Create two function isPrime() to check if number is prime or not. Second to check if string is a palindrome or not.
Get all the substrings starting from str.length - 1 then str.length - 2 and so on.
The way to get substrings is that create a variable l which will be length of substring.
Keep making substrings until the length of substring is greater than 1.
If the while loop create a nested for loop which will get all substrings.
Note: I am not sure that you want to check the whole string or not. If you want to check also the whole string then change let l = str.length - 1; to let l = str.length; in check function.
The code returns true and false. You can fix it according to your needs.
function isPal(str){
return [...str].reverse().join('') === str
}
function isPrime(num){
if(num === 3 || num === 2) return true;
if(num === 1) return false;
if(num % 2 === 0) return false;
for(let i = 3;i<Math.sqrt(num) + 1;i+=2){
if(num % i === 0) return false;
}
return true;
}
function check(str){
let l = str.length - 1;
while(l>1){
for(let i = 0;i<str.length-l;i++){
let temp = str.slice(i,l);
if(isPal(temp)) return isPrime(l)
}
l--;
}
return false;
}
console.log(check("122321")) //true
console.log(check("123454321")) // false
function solution(S) {
var max_length = 0,
maxp = '';
for(var i=0; i < S.length; i++){
var subs = S.substr(i, S.length);
for(var j=subs.length; j>=0; j--){
var sub_subs_str = subs.substr(0, j);
if (sub_subs_str.length <= 1)
continue;
if (is_Palindrome(sub_subs_str)){
if (sub_subs_str.length > max_length){
max_length = sub_subs_str.length;
maxp = sub_subs_str;
}
}
}
}
maxp = IsPrimeNumber(maxp.length);
return maxp;
}
function is_Palindrome(S) {
var rev = S.split("").reverse().join("");
return S == rev;
}
function IsPrimeNumber(n){
if (n===1){
return "NO";
}
else if(n === 2){
return "YES";
}
else{
for(var x = 2; x < n; x++)
{
if(n % x === 0)
{
return "NO";
}
}
return "YES";
}
}
console.log(solution('random12321random'))

Javascript Function Issues for Prime Numbers

So what I'm trying to do is use a function that prompts to enter a number and then prints all prime numbers up till that number. I have the code as far as I know but I keep getting an error that the bracket following prime(num) is wrong. Not sure what I'm doing wrong here, would appreciate any help.
function p5Bela() {
var num = prompt("Please enter a number: ", "");
for (i = 2; i <= num; i++) {
if (prime(i)==true) {
alert(i);
}
}
prime(num) {
var flag = true;
var d = 2;
while (flag==true && d <= num/2) {
if (num%d == 0) {
flag = false;
}
d++;
}
return flag;
}
}
Simplest Way
function isPrime(num) {
for(var i = 2; i < num; i++)
if(num % i === 0) return false;
return num > 1;
}
With the ES6 syntax:
const isPrime = num => {
for(let i = 2; i < num; i++)
if(num % i === 0) return false;
return num > 1;
}
You can also decrease the complexity of the algorithm from O(n) to O(sqrt(n)) if you run the loop until square root of a number:
const isPrime = num => {
for(let i = 2, s = Math.sqrt(num); i <= s; i++)
if(num % i === 0) return false;
return num > 1;
}

Javascript - Code for finding a list of prime numbers keeps freezing

While working on problem 3 of Project Euler, I'm coming across a problem I can't seem to fix where javascript keeps freezing. Here's my code:
var is_prime = function(n) {
if (n === 1) {
return true;
}
if (n === 2) {
return true;
}
var list1 = []
for (i = 2; i < n; i++) {
list1.push(i);
}
for (i = 2; i < list1.length; i++) {
if (n % i === 0) {
return false;
}
}
return true;
}
var list_of_primes = function(n) {
var list1 = [];
var list2 = [];
for (i = 2; i < n; i++) {
list1.push(i);
}
for (i = 2; i < list1.length; i++) {
if (is_prime(i)) {
list2.push(i);
}
}
return list2;
}
confirm(list_of_primes(1000))
I know my algorithm isn't the most efficient and that I'm just brute forcing the problem, but I'm just wondering what it is I'm doing wrong. I'm pretty sure the problem lies somewhere within this block of code:
for (i = 2; i < list1.length; i++) {
if (is_prime(i)) {
list2.push(i);
}
}
I think a potential problem is that my algorithm is taking too long and that is what is causing javascript to freeze. Is there anyway to get my problem to run long enough to give me the answer?
You could try this.
var is_prime = function(n) {
if (n == 1) {
return true;
}
if (n == 2) {
return true;
}
for (var i = 2; i < n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
var list_of_primes = function(n) {
var list2 = [];
for (var i = 2; i < n; i++) {
if (is_prime(i)) {
list2.push(i);
}
}
return list2;
}
confirm(list_of_primes(1000))
Working fine in less than seconds. https://jsfiddle.net/LL85rxv5/
A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
Strictly speaking, 1 is not a prime number so be sure to update that in your code.
Not really sure why your code is timing out, it's just a bit longhand and has an unnecessary array (list1). Anyway, here's a pretty shortened version of the code that comes up with a list of prime numbers from 2 to n.
This isn't too efficient for a large number set because it checks every number individually.
var list_of_primes = function(n) {
var list = [];
for (i = 2; i < n; i++) {
if (is_prime(i)) {
list.push(i);
}
}
return list;
}
function is_prime(i) {
for (var c = 2; c <= Math.sqrt(i); ++c)
if (i % c === 0)
return false;
return true;
}
If you want a bit more efficiency, look into the Sieve of Eratosthenes which can handle much larger sets:
// Credit: http://stackoverflow.com/a/15471749/1265817
var eratosthenes = function(n) {
// Eratosthenes algorithm to find all primes under n
var array = [], upperLimit = Math.sqrt(n), output = [];
// Make an array from 2 to (n - 1)
for (var i = 0; i < n; i++) {
array.push(true);
}
// Remove multiples of primes starting from 2, 3, 5,...
for (var i = 2; i <= upperLimit; i++) {
if (array[i]) {
for (var j = i * i; j < n; j += i) {
array[j] = false;
}
}
}
// All array[i] set to true are primes
for (var i = 2; i < n; i++) {
if(array[i]) {
output.push(i);
}
}
return output;
};
Working examples: https://jsfiddle.net/daCrosby/wfgq28no/
i is a global variable within is_prime function, which interferes with instance used in list_of_primes function. Fix by declaring i as local like this...
var is_prime = function(n) {
var i; // <~~ declare i as local variable here
if (n === 1) {

"Steps in Primes" of Codewars

I got problems when doing "Steps in Primes" of Codewars.
Make function step(g,m,n) which g=step >= 2 , m=begin number >=2,
n=last number>= n. Step(g,m,n) will return the first match [a,b] which
m < a,b is prime < n and a+g=b.
I did right in basic test cases but when i submit , i got infinity loop somewhere. Can anyone give me suggestion?
function isInt(n) {
if(typeof n==='number' && (n%1)===0) {
return true;
}
else return false;
}
function step(g, m, n) {
if(isInt(g) && isInt(m) && isInt(n) &&g >= 2 && m >= 2 && n>=m) {
var p=[];
var ans=[];
for (var temp=m; temp<=n;temp++)
{
var a=0;
for (var chk=2; chk<temp-1;chk++)
if (temp%chk===0) a++;
if (a===0) p.push(temp);
}
for (var a=0;a<p.length-1;a++)
{
for (var b=a+1;b<p.length;b++)
if (p[b]===(p[a]+g)) return [p[a],p[b]];
}
}
return "nil";
}
this code might help you
function gap(g, m, n) {
var prime-numbers = [];
var final = [];
var prime;
for (var i = m; i <= n; i++) {
prime = true;
for (var j = 2; j < i / 2; j++) {
if (i % j === 0) {
prime = false;
}
}
if (prime) {
prime-numbers.push(i);
}
}
prime-numbers.forEach(function(prime, index) {
if (prime + g === prime-numbers[index + 1]) {
final.push(prime, prime-numbers[index + 1]);
}
});
if (final) return final.slice(0,2);
else return null;
}

determine if array is arithmetic or geometric progression (from Coderbyte)

Here is my functional code, as far as coderbyte is concerned.
But I have a feeling it shouldn't be this complicated.
Am I missing a simple trick?
function ArithGeo(arr)
{
var array_type = -1;
if (arr.length <= 2) return true;
var a = arr[1], r = a/arr[0], i;
for (i = 2; i < arr.length; ++i) {
if ((a *= r) == arr[i]){
array_type = "Geometric";
}
else{
array_type = -1;
break;
}
}
if (array_type == "Geometric")
return array_type;
a = arr[1], d = a - arr[0], i;
for (i = 2; i < arr.length; ++i) {
if ((a += d) == arr[i]){
array_type = "Arithmetic";
}
else {
array_type = -1;
break;
}
}
return array_type;
}
ArithGeo([3,9,15,21,27, 28]);
function ArithGeo(arr) {
var diff = arr[1] - arr[0];
var ratio = arr[1] / arr[0];
var arith = true;
var geo = true;
for(var i = 0; i < arr.length - 1; i++)
{
if( arr[i + 1] - arr[i] !== diff )
arith = false;
if(arr[i + 1] / ratio !== arr[i])
geo = false;
}
if(arith === true)
return "arithmetic";
else if(geo === true)
return" geometric";
else
return -1;
}
Here's a simple solution as well. I'm either looking for a geometric pattern, where a given element will be divisible by the previous element, or an arithmetic pattern, where each element increases by a constant amount. Two variables, diff and ratio, contain each pattern to search for throughout the array.
I start by assuming that arith and geo are true, and if I find an example where one is not true, I set its value to false. Note that your code has two for loops, with the exact same conditions. This is a good indication that your code can be condensed into one loop.
With each pass through the loop, I test whether the conditions are present to set either arith or geo to false. Finally, after the loop exits, I will determine if either arith or geo remained true throughout the loop. If not, I return - 1 as the problem from Coderbyte requests.
edit: quick note on my for loop condition. Since I am checking the value of i + 1 with each pass, I make sure that I don't reach out of bounds by setting my exit condition to arr.length - 1. This way, i + 1 can still reach the last element, and will be sure not to overreach.
For arithmetic progression, subtract each element from previous element; their difference should be equal; for geometric, divide each element by the previous element, the ratio should stay the same. As for divide by zero when you meet 0, javascript gives you Inf (and it certainly is not a geometric progression). Because floats are inaccurate, maybe you'd want to store the min and max of these values and then see if they are close enough to each other.
function arithGeo(arr) {
var minRatio = 1/0,
maxRatio = -1/0,
minDiff = 1/0,
maxDiff = -1/0,
epsilon = 0.000001,
i,
ratio,
diff;
if (arr.length <= 2) {
return;
}
for (i = 1; i < arr.length; ++i) {
diff = arr[i] - arr[i - 1];
ratio = arr[i] / arr[i - 1];
minDiff = Math.min(diff, minDiff);
maxDiff = Math.max(diff, maxDiff);
minRatio = Math.min(ratio, minRatio);
maxRatio = Math.max(ratio, maxRatio);
}
if (Math.abs(minDiff - maxDiff) < epsilon) {
return "Arithmetic";
}
if (Math.abs(minRatio - maxRatio) < epsilon) {
return "Geometric";
}
return;
}
alert(arithGeo([3,9,15,21,27,28]));
alert(arithGeo([3,9,15,21,27]));
alert(arithGeo([4,2,1,0.5]));
It might not be the most efficient way to solve the problem, and it doesn't address the epsilon Problem, that Antti Haapala mentioned, but this is my solution to the problem:
function sequenceMatches(arr, fn) {
var compare = fn(arr[0], arr[1]);
for (var i = 2; i < arr.length; i++) {
if (fn(arr[i - 1], arr[i]) !== compare) return false;
}
return true;
}
function ArithGeo(arr) {
if (sequenceMatches(arr, function(a, b) { return b - a; })) return 'Arithemetic';
if (sequenceMatches(arr, function(a, b) { return b / a; })) return 'Geometric';
return -1;
}
I choose to solve that in two different functions, as that helps to clean up the code imho.
function ArithGeo(arr) {
var apCnt = 1;
var gpCnt = 1;
var diff = arr[1] - arr[0]; //ap difference
var div = arr[1]/arr[0]; //gp difference
for(var i=1;i<arr.length-1;i++){ //traverse array
if(arr[i+1] - arr[i] == diff) { //check for ap
apCnt+=1;
}
else if(arr[i+1]/arr[i] == div) { //check for gp
gpCnt+=1;
}
else{
break; //break if not ap or gp
}
}
return apCnt == arr.length-1 ? "Arithmetic": gpCnt == arr.length-1 ? "Geometric": -1; //return if its ap or gp
}
function ArithGeo(arr){
if(arr == null || !Array.isArray(arr)){
return "error";
}
var length = arr.length;
if(length === 0){
return "neither";
}
if(length === 1){
return "both";
}
var arithCount = 0,
geoCount = 0,
d = arr[1] - arr[0],
q = arr[1] / arr[0];
for(var i = length - 1; i > 0; i--){
if((arr[i] - arr[i-1]) === d){
arithCount++;
}
if((arr[i] / arr[i-1]) === q){
geoCount++;
}
}
if(arithCount === length - 1){
return "Arithmetic";
}else if (geoCount === length - 1){
return "Geometric";
}else if((arithCount === length - 1) && (geoCount === length - 1)){
return "both";
}else{
return "neither";
}
}
Sorry, only considered the integer sequence. #Antti Haapala's answer is correct.
Extremely late but I pretty much did the same on my own (novice javascript user).
It calculates the difference between i + 1 and i (or i + 1 / i) and pushes it into a new array. I then use a function to check if every element in the array is the same.
function numberCheck(array) {
var arithResult = null;
var geoResult = null;
var arithCounter = [];
var geoCounter = [];
Array.prototype.allValuesSame = function() {
for(var i = 1; i < this.length; i++) {
if(this[i] !== this[0])
return false;
} return true;
}
for (var b = 0; b < array.length - 1; b++) {
arithCounter.push(array[b + 1] - array[b]);
}
for (var i = 0; i < array.length - 1; i++) {
geoCounter.push(array[i + 1] / array[i])
}
arithResult = arithCounter.allValuesSame();
geoResult = geoCounter.allValuesSame();
if (arithResult === true) { return "Arithmetic";}
else if (geoResult === true) { return "Geometric";}
else { return "-1";}
}
numberCheck([1,2,4,8])

Categories