I am trying to get the sum of an array of prime numbers, and I understand there are more elegant ways to do that and have seen the links to those solutions.
My problem is something that's wrong within this specific script, and I'm trying to understand what's causing THIS code to fail.
The issue is that the numbers 9, 15 and many others are being being added into the primes array, even though they all, correctly, fail a test to check if they're prime numbers. I can't wrap my head around what in the script is causing the numbers to push to the array despite failing that test. Again, I'm not looking for a completely different/better approach to summing the primes, but some help in identifying what exactly is wrong in this script would be really appreciated.
function totalPrime(num) {
var nums = [];
var primes = [];
for (var i = 1;
(num - i) > 1; i++) {
nums.push(num - i);
}
nums.forEach(isPrime);
function isPrime(n) {
var a = [];
var test;
if (n === 1) {} else if (n === 2) {
primes.push(n);
} else {
for (var i = 1;
(n - i) > 1; i++) {
a.push(n - i);
}
a.forEach(function(x) {
if ((n % x) === 0) {
test = false;
} else {
test = true;
}
});
if (test) {
primes.push(n);
} else {}
};
}
console.log(primes.reduce(function(a, b) {
return a + b
}));
}
totalPrime(5);
Same script with logging I was using to debug:
function totalPrime(num) {
var nums = [];
var primes = [];
for (var i = 1;
(num - i) > 1; i++) {
nums.push(num - i);
}
nums.forEach(isPrime);
function isPrime(n) {
var a = [];
var test;
if (n === 1) {
console.log(n + ' is NOT a prime number');
} else if (n === 2) {
console.log(n + ' IS a prime number');
primes.push(n);
} else {
for (var i = 1;
(n - i) > 1; i++) {
a.push(n - i);
}
a.forEach(function(x) {
if ((n % x) === 0) {
test = false;
console.log(n + ' % ' + x + ' equals 0');
console.log(x + ' fails check');
} else {
test = true;
console.log(n + ' % ' + x + ' does NOT equal 0');
console.log(x + ' passes check');
}
});
if (test) {
console.log(n + ' IS a prime number.');
primes.push(n);
} else {
console.log(n + ' is NOT a prime number.');
}
};
}
console.log(primes);
console.log(primes.reduce(function(a, b) {
return a + b
}));
}
totalPrime(5);
Your test value in each test override the previous check. Thus, actualy only the last check (divide in 2) become relevant, and all the odd primes fail.
You can correct it by change the default of test to true, and remove the exist line in the code test = true;.
The corrected code:
function isPrime(n) {
var a = [];
var test = true;
if (n === 1) {} else if (n === 2) {
primes.push(n);
} else {
for (var i = 1;
(n - i) > 1; i++) {
a.push(n - i);
}
a.forEach(function(x) {
if ((n % x) === 0) {
test = false;
}
});
if (test) {
primes.push(n);
}
};
}
Related
I'm studying node.js and have some interesting task - Write a program that finds and prints the biggest prime number which is <= N.
Input // Output - 13 // 13
126 // 113
26 // 23
In last course with java i have the same task and my code is really simple:
import java.util.Scanner;
public class BiggestPrimeNumber {
public static void main(String[] args){
int n;
Scanner in = new Scanner(System.in);
n=in.nextInt();
while(prim(n) == false){
n--;
}
System.out.println(n);
}
public static boolean prim(int m){
int n=m;
for(int i=2;i<n;i++){
if(n%i == 0){
return false;
}
}
return true;
}
}
I try similar way to test it, but I'm don't have idea how to convert it:
let n = 126;
while (isPrime(n) === false) {
n -= 1;
}
console.log(n);
let n = m;
for (let i = 2; i < n; i += 1) {
if (n % i === 0) {
return false;
}
}
return true;
Can you help me, because I'm really have problem with js using in console.
I think this is what you want. You only need to declare a function and use it as you are doing.
let n = 126;
while (isPrime(n) === false) {
n -= 1;
}
console.log(n);
function isPrime(m) {
let n = m;
for (let i = 2; i < n; i += 1) {
if (n % i === 0) {
return false;
}
}
return true;
}
If your running it with NodeJS in console, you can save it in a file called prime.js (for example) and execute it with: node prime.js.
You can pass parameters to the script like: node prime.js 126 and then get them in the code. That will be something like that:
const args = process.argv;
let n = args[2];
while (isPrime(n) === false) {
n -= 1;
}
console.log(n);
function isPrime(m) {
let n = m;
for (let i = 2; i < n; i += 1) {
if (n % i === 0) {
return false;
}
}
return true;
}
You're pretty close. First off, you don't have isPrime defined. Second, if you were to paste all of your code into the browser console, it isn't going to like that you are defining n twice. I also cleaned up your isPrime bit of code.
let n = 100;
let result = n;
const isPrime = num => {
for(let i = 2; i < num; i++)
if(num % i === 0) return false;
return num !== 1 && num !== 0;
}
while (isPrime(result) === false) {
result -= 1;
}
console.log(result + " is the next prime below " + n);
Also, remember that javascript is not a compiled language, so unless you are defining your function in a class, the browser will interpret the code sequentially. Therefore, you have to have isPrime defined before you use it.
The algorithm to find the nearest prime number can be further optimized. All prime numbers are of the form 6k+1 or 6k-1 except the numbers 2 and 3. Also, instead of checking all the way to the number the check can be made till Sqrt(n). Here is the modified isPrime function:
let n = 126;
while (isPrime(n) === false) {
n -= 1;
}
console.log(n);
function isPrime(num) {
if (num <= 1) return false;
if (num < 4) return true;
if (num%2 === 0 || num%3 === 0) return false;
for (var i = 5; i*i <= num; i+=6) {
if (num % i === 0 || num % (i + 2) === 0)
return false;
}
return true;
}
What have I done wrong with this code? It can't print anything on the console.
Here it is the description of the problem:
Implement a javascript function that accepts an array containing an integer N and uses an expression to check if given N is prime (i.e. it is divisible without remainder only to itself and 1).
var n = ['2'];
function isPrime(n) {
if (n < 2) {
return false;
}
var isPrime = true;
for(var i = 2; i < Math.sqrt(n); i += 1) {
if (n % i === 0) {
isPrime = false;
}
}
return isPrime;
}
return isPrime(n);
There are couple errors in your code.
First, you need to check for every integer between 2 and Math.sqrt(n) inclusively. Your current code returns true for 4.
I don't think this is in a function, so you need to omit return from return isPrime(n) and replace it with a function wich prints out the return value of the funnction, like alert or console.log.
n is not a number, it's an array. You need to either make n a number, or call the function with isPrime(n[0]).
The correct code is
var n = 2;
function isPrime(n) {
if (n < 2) {
return false;
}
var isPrime = true;
for(var i = 2; i <= Math.sqrt(n); i += 1) {
if (n % i === 0) {
isPrime = false;
}
}
return isPrime;
}
alert(isPrime(n));
Note: You can change n += 1 to n++, and it works the same way.
n is an array, you want to access first element in the array and convert it to number first.
try replacing
return isPrime(n);
with
return isPrime(parseInt(n[0],10));
Your for-loop condition also needs a little modification
for(var i = 2; i <= Math.sqrt(n); i += 1) { //observe that i is not <= Math.sqrt(n)
A couple of little errors:
var n = 2;//<--no need to put n in an array
function isPrime(n) {
if (n < 2) {
return false;
}
var isPrime = true;
for(var i = 2; i < Math.sqrt(n); i += 1) {
if (n % i === 0) {
isPrime = false;
}
}
return isPrime;
}
isPrime(n);//<--no need for "return"
As to no output being printed, it is because you need to use console.log.
Replace return isPrime(n); with console.log(isPrime(n));.
Full working code:
var n = ['2', '3', '4', '5', '6', '7']; // you can use as many values as you want
function isPrime(n) {
if (n < 2) {
return false;
}
var isPrime = true;
for (var i = 2; i <= Math.sqrt(n); i += 1) { // Thanks to gurvinder372's comment
if (n % i === 0) {
isPrime = false;
}
}
return isPrime;
}
n.forEach(function(value) { // this is so you can iterate your array with js
console.log('is ' + value + ' prime or not? ' + isPrime(value)); // this so you can print a message in the console
});
/*
// Another approach of parsing the data, uncomment this piece of code and comment the one above to see it in action (both will give the same result)
for (index = 0; index < n.length; ++index) {
console.log('is ' + n[index] + ' prime or not? ' + isPrime(n[index])); // this so you can print a message in the console
}
*/
Here is my code. It would really help me if someone could tell me what is wrong. And performance tips are also highly appreciated.
btw the html is just a button onclick prime().
function prime() {
var teller = 1;
var n = document.getElementById("a").value;
document.write("2, ");
checkPrime(n, 1);
}
function checkPrime(n, teller) {
if(isPrime(teller)) {
document.write(teller + ", ");
}
if(teller < n) {
checkPrime(n, teller = teller + 2);
}
}
function isPrime(n) {
var isPrime = true;
if (n < 2 || n != Math.round(n) ) {
return false;
}
for (var i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
isPrime = false;
}
}
return isPrime;
}
Your logic for checking with modulus seems correct but the teller variable seemed strange to me. Here is a fiddle and your code without the teller var.
function prime() {
var teller = 1;
var n = document.getElementById("a").value;
checkPrime(n);
}
function checkPrime(n) {
var primes = isPrime(n);
if (primes) alert(primes.length + " primes found : " + primes.join())
else alert("Error");
}
function isPrime(n) {
var isPrime = true;
var primeArray = new Array();
if (n <= 2 || n != Math.round(n)) {
return false;
}
for (var j = 3; j <= n; j++) {
var primeFound = true;
for (var i = 2; i <= Math.sqrt(j); i++) {
if (j % i == 0) {
primeFound = false;
}
}
if (primeFound) primeArray.push(j);
}
return primeArray;
}
This isn't the most efficient code though. It would be faster to check by only the primes already found instead of trying to divide by all the integers up to sqrt(j).
I'm attempting to get better with optimizing algorithms and understanding big-o, etc.
I threw together the below function to calculate the n-th Fibonacci number. This works (for a reasonably high input). My question is, how can I improve this function? What are the drawbacks of calculating the Fibonacci sequence this way?
function fibo(n) {
var i;
var resultsArray = [];
for (i = 0; i <= n; i++) {
if (i === 0) {
resultsArray.push(0);
} else if (i === 1) {
resultsArray.push(1);
} else {
resultsArray.push(resultsArray[i - 2] + resultsArray[i - 1]);
}
}
return resultsArray[n];
}
I believe my big-o for time is O(n), but my big-o for space is O(n^2) due to the array I created. Is this correct?
If you don't have an Array then you save on memory and .push calls
function fib(n) {
var a = 0, b = 1, c;
if (n < 3) {
if (n < 0) return fib(-n);
if (n === 0) return 0;
return 1;
}
while (--n)
c = a + b, a = b, b = c;
return c;
}
Performance Fibonacci:
var memo = {};
var countInteration = 0;
var fib = function (n) {
if (memo.hasOwnProperty(n)) {
return memo[n];
}
countInteration++;
console.log("Interation = " + n);
if (n == 1 || n == 2) {
result = 1;
} else {
result = fib(n - 1) + fib(n - 2);
}
memo[n] = result;
return result;
}
//output `countInteration` = parameter `n`
I tried to rewrite this indexOf MDN example to practice recursion
var str = 'To be, or not to be, that is the question.';
var count = 0;
var pos = str.indexOf('e');
while (pos !== -1) {
count++;
pos = str.indexOf('e', pos + 1);
}
console.log(count); // displays 4
This was my solution:
var count = 0;
function countLetters(str, p) {
var pos = str.indexOf(p);
if (pos == -1) {
return count;
}
else {
count ++;
return countLetters(str.substr(pos + 1), p)
}
}
console.log(countLetters('To be, or not to be, that is the question.', 'e'));
It works, but is there anyway to get the count variable inside the function itself? Is it not really a true recursion if I have a count variable outside the function?
In a recursive function, if you want to keep a variable around from one "iteration" to the next, then you need to pass it as an argument:
function countLetters(str, p, count) {
count = count || 0;
var pos = str.indexOf(p);
if (pos == -1) {
return count;
}
else {
return countLetters(str.substr(pos + 1), p, count + 1);
}
}
console.log(countLetters('To be, or not to be, that is the question.', 'e'));
// => 4
However, this is not always necessary, as Arun P Johny's answer illustrates.
What you can do is to return the count value form the method, so if the item is not found you return 0, else you return 1 + value-of-recursive-call
function countLetters(str, p) {
var pos = str.indexOf(p);
if (pos == -1) {
return 0;
} else {
return 1 + countLetters(str.substr(pos + 1), p)
}
}
console.log(countLetters('To be, or not to be, that is the question.', 'e'));
Demo: Fiddle