Laketek
Laketek

Reputation: 11

Javascript getting the nth prime number

This should return the nth prime (n being the number given by the user). It works fine for the first few numbers (1 returns 2, 2 returns 3, 3 returns 5) but when 5 is given, it returns 9 which isn't prime (it should be 11). This happens with other numbers as well above this (7 returns 15 when it should be 17).

The 'document' stuff is to do with HTML where I'm getting the userValue and to display the prime number.

function isPrime(value) {
  for(var i = 2; i < value; i++) {
      if(value % i === 0) {
          return false;
      }
  }
  return value > 1;
}


function generatePrime() {
  var userValue = document.getElementById("inputValue").value;
  var iter = 1;
  var returnValue = 2;
  //checks for an integer
  if (parseInt(userValue) === parseFloat(userValue)) {
    //checks if the user inputted a value above 0
    if (userValue > 0) {
      //loops to find the correct prime
      while (iter < userValue) {
        if (isPrime(returnValue)) {
          returnValue += 1;
          iter += 1;
        }
        if (!isPrime(returnValue)) {
          returnValue += 1;
        }
      }
    }
    else {
      returnValue = "That is not a number above 0!";
    }
  }
  else {
    returnValue = "That is not a number!";
  }
  document.getElementById("returnValue").innerHTML = returnValue;
}

I need help with making this return the correct number.

Upvotes: 0

Views: 3464

Answers (4)

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48600

The following is based on Bhaskara Arani's submission, but I added caching.

Note: I also threw in an addition condition to check for palindrome.

This check can be removed via:

while (i <= root && value % i /* && isPalindrome(value) */)

const main = () => {
  for (let i = 15; i >= 0; i--) {
    console.log(`Palindrome Prime ${i + 1} = ${generatePrime(i)}`);
  }
};

const cachedPrimes = [];
const generatePrime = (index) => {
  let value = cachedPrimes[cachedPrimes.length - 1] ?? 0;
  for (let i = cachedPrimes.length; i <= index; i++) {
    value = nextPrime(value);
    cachedPrimes.push(value);
  }
  return cachedPrimes[index];
};

const nextPrime = (value) => {
  if (value > 2) {
    let i, root;
    do {
      i = 3; value += 2; root = ~~Math.sqrt(value);
      while (i <= root && value % i && isPalindrome(value)) {
        i += 2;
      }
    } while (i <= root);
    return value;
  }
  return value === 2 ? 3 : 2;
};

const isPalindrome = (n) => n === reverse(n);

const reverse = n => +`${n}`.split('').reverse().join('');

main();
.as-console-wrapper { top: 0; max-height: 100% !important; }

Upvotes: 0

Bhaskara Arani
Bhaskara Arani

Reputation: 1657

Try this one.

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;
}


function generatePrime() {
	var userValue = document.getElementById("inputValue").value;
	var value = 0, result = [];
	for (var i = 0; i < userValue; i++) {
		value = nextPrime(value);
		result.push(value);
	}
  document.getElementById("returnValue").innerHTML = result[userValue-1];
}
<!DOCTYPE html>
<html>
<head>
<script>

</script>
</head>
<body>

Input value: <input type="text" name="inputValue" id="inputValue"/>
<button onclick="generatePrime()">Prime number</button>
<div id="returnValue">Test: </div>

</body>
</html>

Upvotes: 1

Rajesh
Rajesh

Reputation: 24915

You can try something like this:

function getNthPrimeNumber(n){
  var count = 0;
  var num = 2;
  while(count++ != n){
    num = getNextPrimeNumber(num);
  }
  return num;
}

function getNextPrimeNumber(n){
  for(var i = ++n; i< n*n; i++){
    if(isPrime(i)) return i
  }
  return 0;
}

function isPrime(n){
  for(var i = 2; i< n; i++)
    if (n%i===0) 
      return false;
  return true;
}

console.log(getNthPrimeNumber(0))
console.log(getNthPrimeNumber(2))
console.log(getNthPrimeNumber(5))

Upvotes: 1

kevin ternet
kevin ternet

Reputation: 4612

You could reduce the range of iteration for function isPrime() :

function isPrime(value) {
  for(var i = 2; i < Math.sqrt(value) + 1; i++) {
      if(value % i === 0) {
          return false;
      }
  }
  return value > 1;
}

Upvotes: 0

Related Questions