Reputation: 63
I am doing challenge 7 on the Euler project, which requires me to find the 10001:st prime number.
My attempt is as follows:
int i=2; //the number to check if prime
int c=0; //the amount of prime numbers
while(true){
//checks if i%n == 0, if so, i is not a prime number.
for(int n=2;n<=prob.getMax(i);n++){
//it is not a prime number
if(i%n==0){
break;
}
//it is a prime number
if(n==prob.getMax(i)){
c++;
break;
}
}
i++;
//if c == 10001 we have found the 10001:st prime number
if(c==10001){
System.out.println(i);
break;
}
}
}
public int getMax(int x){
return (int) Math.ceil(Math.sqrt(x));
}
I am returned the value 104760 but that does not seem to be correct. I cannot understand what I am doing wrong, since I seem to get a reasonable value. Could anyone point me in the right direction?
And also: is there any better way to compute these kind of problems? I seem to be using a for-loop and brute forcing my way to the solution on every problem.
Upvotes: 0
Views: 2879
Reputation: 9041
One thing to note for prime numbers is that with the exception of the number 2, they are always odd numbers and you don't have to check if the number is divisible by every number before it.
public class StackOverflow {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// Starting at 1 cause I'm already including 2
long primeCount = 1;
// Start with an odd number cause primes are never even
long prime = 1;
Calendar start = Calendar.getInstance();
while (primeCount < 10001) {
prime += 2;
if (isPrime(prime)) {
primeCount++;
}
}
System.out.println(prime);
System.out.println(String.format("Elapsed Time: %d ms", Calendar.getInstance().getTimeInMillis() - start.getTimeInMillis()));
}
private static boolean isPrime(long prime) {
if (prime <= 1)
return false;
else if (prime % 2 == 0)
return (prime == 2);
else
{
int divisor = 3;
double upperLimit = Math.sqrt((double)prime) + 1;
while (divisor <= upperLimit)
{
if (prime % divisor == 0)
return false;
// Skip by two cause an odd number is never evenly divisible by an even number
divisor +=2;
}
return true;
}
}
}
Result (!!!!SPOILER ALERT!!!!!)
Upvotes: 0
Reputation: 59
By searching you can find out that the 10001st prime number is 104743. I changed your algorithm to :
public static void main(String... args) {
int i = 2; //the number to check if prime
int c = 1; //the counter for prime numbers have found so far
while (true) {
if(isPrime(i)){
c++;
}
//if c == 10001 we have found the 10001:st prime number
if (c == 10001) {
System.out.println(i);
break;
}
i++;
}
}
public static boolean isPrime(int number) {
for (int i = 2; i <= getMax(number); i++) {
if (number % i == 0)
return false;
}
return true;
}
public static int getMax(int x) {
return (int) Math.ceil(Math.sqrt(x));
}
Upvotes: 0
Reputation: 31
You are increasing i
(with i++
) before showing the result. The 100001 prime may be 104760-1.
One advise, try to avoid those while(true). You can do something like:
c = 0;
while (c < 10001) {
....
c++
}
Upvotes: 0
Reputation: 1259
In your code, you are not checking the prob.getMax(i)
which is in for loop.
Add another check in the body of your for
loop, something like the following:
if(n==theDesiredNumber){
//...
break;
}
Upvotes: 0
Reputation: 531
You increase i before checking whether the found prime is the 10001st one. By swapping the order of these actions, it should work.
Upvotes: 2