I recently was part of a small java programming competition at my school. My partner and I have just finished our first pure oop class and most of the questions were out of our league so we settled on this one (and I am paraphrasing somewhat): "given an input integer n return the next int that is prime and its reverse is also prime for example if n = 18 your program should print 31" because 31 and 13 are both prime. Your .class file would then have a test case of all the possible numbers from 1-2,000,000,000 passed to it and it had to return the correct answer within 10 seconds to be considered valid.
We found a solution but with larger test cases it would take longer than 10 seconds. I am fairly certain there is a way to move the range of looping from n,..2,000,000,000 down as the likely hood of needing to loop that far when n is a low number is small, but either way we broke the loop when a number is prime under both conditions is found. At first we were looping from 2,..n no matter how large it was then i remembered the rule about only looping to the square root of n. Any suggestions on how to make my program more efficient? I have had no classes dealing with complexity analysis of algorithms. Here is our attempt.
public class P3
{
public static void main(String[] args){
long loop = 2000000000;
long n = Integer.parseInt(args[0]);
for(long i = n; i<loop; i++)
{
String s = i +"";
String r = "";
for(int j = s.length()-1; j>=0; j--)
r = r + s.charAt(j);
if(prime(i) && prime(Long.parseLong(r)))
{
System.out.println(i);
break;
}
}
System.out.println("#");
}
public static boolean prime(long p){
for(int i = 2; i<(int)Math.sqrt(p); i++)
{
if(p%i==0)
return false;
}
return true;
}
}
ps sorry if i did the formatting for code wrong this is my first time posting here. Also the output had to have a '#' after each line thats what the line after the loop is about Thanks for any help you guys offer!!!
The simplest primality test is trial division: given an input number, n, check whether it is evenly divisible by any prime number between 2 and √n (i.e. that the division leaves no remainder). If so, then n is composite. Otherwise, it is prime.
That algorithm would have complexity O(sqrt(n)).
A prime number is a number that is divisible by only two numbers: 1 and itself. So, if any number is divisible by any other number, it is not a prime number.
We will discuss and implement all of the above problems in Python and C++ A prime number is a natural number (greater than 1) that has exactly two factors, 1 and itself. In order to check if a number is prime or not, we can count the number of factors.
Here is one efficient way to check a given number is prime. Show activity on this post. Here is an efficinent way to check prime number. Thanks for contributing an answer to Stack Overflow!
A prime is a natural number greater than 1 that has no positive divisors other than 1 and itself. Examples of first few prime numbers are {2, 3, 5, We provide nothing but the best curated videos and practice problems for our students.
A prime number is a natural number (greater than 1) that has exactly two factors, 1 and itself. In order to check if a number is prime or not, we can count the number of factors. If it is 2, then we say that the number is prime, else it is a composite number.
First you should precompute all prime numbers up to 2,000,000,000 using something like the Sieve of Eratosthenes. You can store whether each number is prime in a bit array.
This is pretty fast, and then checking each individual number for primality is a simple lookup.
If you can't do this because you need to run a new instance of your program for each test case, use a fast primality testing algorithm like Miller-Rabin.
Your prime check is very inefficient. In fact, you don't need to re-check multiples of already checked numbers. So when you check for %2, you don't need to check for %4.
To find out whether a number is a prime, you only have to try to divide it by all known primes until you reach the square root of the number to be checked. Doing this reduces the number of divisions vastly: if your app has a list of the primes from 2..~44721 (for instance computed as preparation step), you can check all numbers until 2000000000 pretty quickly.
Also, you should make sure to check the smaller of the two permutations first (e.g. in your sample first check 13, then 31).
Edit:
Here's a sample I quickly put together in C# (you'll need to do some minor syntactic changes to have it run on Java, but I just had a C# compiler at hand):
public static long reverse(long value) {
long result = 0;
while (value > 0) {
result = result*10+(value%10);
value /= 10;
}
return result;
}
public static long[] knownPrimes = new long[1000000];
public static int knownPrimeCount = 0;
public static bool isPrime(long value) {
// we loop through all already known primes and try to divide by those (sieve sort of)
for (int primeIndex = 0; primeIndex < knownPrimeCount; primeIndex++) {
long primeToCheck = knownPrimes[primeIndex];
if (value % knownPrimes[primeIndex] == 0) {
// can be divided by the given prime -> not a prime
return false;
}
if ((primeToCheck * primeToCheck) > value) {
// square exceeds the value -> is a prime, no more checks needed
return true;
}
}
// if we come here, we've run out of primes to check against, and therefore we should indicate this as error
throw new ArgumentException(string.Format("{0} is too large to be checked against known primes", value), "value");
}
public static void Main(String[] args){
long loop = 2000000000;
long n = 1999990000;
// first we initialize all the primes we may be needing for the final computation
knownPrimes[knownPrimeCount++] = 2;
for (long i = 3; true; i++) {
if (isPrime(i)) {
// store the new prime
knownPrimes[knownPrimeCount++] = i;
if ((i * i) > loop) {
break; // we have all the primes we need now
}
}
}
// now we try to find matches
for (long i = n; i <= loop; i++) {
long reversed = reverse(i);
if ((reversed <= i) && isPrime(reversed) && isPrime(i)) {
Console.WriteLine("{0} <-> {1}", i, reversed);
}
}
Console.WriteLine("#");
Console.ReadKey(true);
}
On my computer and with the given loop
and n
in the source the result shows up instantaneous.
Using BigInteger.isProbablePrime(certainty)
and BigInteger.nextProbablePrime()
can significantly cut down the number of cases you need to check quite efficiently
It seems like you are incrementing by 1, but you should be incrementing by 2. No even number is prime but 2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With