Arcthor
Arcthor

Reputation: 63

Finding the 10001:st prime number (Euler project)

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

Answers (5)

Shar1er80
Shar1er80

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!!!!!)

enter image description here

Upvotes: 0

Soheil Sharifzadeh
Soheil Sharifzadeh

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

figarocorso
figarocorso

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

Nirmal
Nirmal

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

user4759923
user4759923

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

Related Questions