Code-Challenge:The Nearest Prime

8

Challenge

In this task you would be given an integer N you have to output the nearest prime to the integer.

If the number is prime itself output the number.

The input N is given in a single line,the inputs are terminated by EOF.The number of inputs would not exceed 10000 values.

The challenge is to implement the fastest solution so that it can process a maximum of 10000 values as fast as possible.

Input

 299246598
 211571591
 71266182
 645367642
 924278231

Output

 299246587
 211571573
 71266183
 645367673
 924278233

Constraints

  • N is less than 2^64
  • Take care of your fingers do not use more than 4096 bytes in your solution.
  • You can use any language of your choice as long as you are not using it's any inbuilt things for the primes.
  • Fastest solution,with the most efficient time complexity wins!

ADDED:

This is a easier version of the this same problem (with N < 2^31) so that you may try checking your approach in smaller cases before building it up for this actual problem.

Quixotic

Posted 2011-04-09T21:12:23.933

Reputation: 2 199

Would you provide some more test data please? – alexander-brett – 2015-04-21T08:54:19.290

2

The basic calculation you're requestion was a sub-part of http://codegolf.stackexchange.com/q/1977/78, just a couple of days ago. Personally (i.e. not wearing my moderator hat) I find such repetition boring.

– dmckee --- ex-moderator kitten – 2011-04-09T22:45:09.943

Can we use probabilistic primality tests? – Keith Randall – 2011-04-10T02:52:58.117

2How do you plan on judging fastest? By speed of execution on fixed hardware? Or by analyzing the complexity of the submissions? Will you somehow normalize the cost of operations in different languages? -- Lastly, this challenge seems way too simple. There really isn't any room to innovate here. – MtnViewMark – 2011-04-10T03:41:10.223

@dmckee:No that problem is way more simple and very weak itself. – Quixotic – 2011-04-10T11:08:21.010

Can I use a 2^64 lookup table? – gnibbler – 2011-04-10T11:09:09.460

@Keith Randall:My solution is developed on Miller-Rabin + an optimized sieve for small numbers but you may use fast deterministic tests too :-) – Quixotic – 2011-04-10T11:15:33.207

@MtnViewMark:I have mentioned in the constraints that the Fastest solution,with the most efficient time complexity wins! and I think it is not that simple,please take a look on the restrictions (carefully) and if you still find it way more simple and there isn't any room for innovation,then I am sorry,probably this challenge is not for you :-) – Quixotic – 2011-04-10T11:19:20.413

1@gnibbler: Using a lookup table of all 2^64 values will give you the fastest solution iff you can squeeze the entire thing (solution) through the 4096 bytes window :-) – Quixotic – 2011-04-10T11:27:23.903

2@Debanjan, may we assume the generalised Riemann hypothesis in stating time complexity? – Peter Taylor – 2011-04-10T15:40:13.863

@Peter Taylor: Okay :-) – Quixotic – 2011-04-10T17:40:14.960

Answers

6

Python

import sys,random

# Miller-Rabin primality test, error rate 2^-200.                                                                                                                           
def prime(N):
  if N<3:return N==2
  s=0
  d=N-1
  while (d&1)==0:s+=1;d>>=1
  for i in xrange(100):
    a=random.randrange(1,N)
    if pow(a,d,N)!=1 and all(pow(a,d<<r,N)!=N-1 for r in xrange(s)):return 0
  return 1

for N in map(int,sys.stdin):
  d=0
  while 1:
    if prime(N+d):print N+d;break
    if prime(N-d):print N-d;break
    d+=1

Keith Randall

Posted 2011-04-09T21:12:23.933

Reputation: 19 865

I think it should be noted that the Miller-Rabin primality test is not unconditionally deterministic. http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test

– mbomb007 – 2015-04-21T16:50:16.353

2

PARI GP

a(n)=x=[precprime(n),nextprime(n)];print(if(x[1]-n<n-x[2],x[1],x[2]))
while(1,print(a(input())))

st0le

Posted 2011-04-09T21:12:23.933

Reputation: 2 002

I suppose mathematica would be something similar but it's NextPrime[n] works strictly above n so 3 conditions.... – st0le – 2011-04-16T07:53:58.440

0

Haskell

import Data.Numbers.Primes

-- Assuming, we are on x64
nearestPrime :: Int -> Int
nearestPrime n | n - s < l - n = s
               | otherwise     = l where
  l = head $ dropWhile (not . isPrime) [n..]
  s = head $ dropWhile (not . isPrime) [n,n-1..]

main = readLine >>= print . nearestPrime . read

Should be quite fast. Requires the package primes, available from hackage.

FUZxxl

Posted 2011-04-09T21:12:23.933

Reputation: 9 656

As you said, importing code is a shame. Unless you judge others by another standard than your own – Dr. belisarius – 2012-12-28T00:09:43.020

@belisarius You err. This is not code golf so code size is not an option. The task you attempted to solve was code golf however. – FUZxxl – 2012-12-28T00:22:28.230

1Using inbuilt primes is not a good choice as this is not codegolf and the whole point is to implement a fast approach This answer deserves a -1, clearly. I don't feel in a downvoting mood, though. – Dr. belisarius – 2012-12-28T01:18:38.583

@belisarius If you have the need for any sort of "revenge", just vote me down. There is no problem with that; neverthless, that is bad style. – FUZxxl – 2012-12-28T09:23:12.900

Sorry,that is not allowed,this is code challenge and I guess this should not work in the shorter version of the problem too. – Quixotic – 2011-04-10T14:44:00.423

0

Ruby

require 'prime'
gets(p).split.each{|n|
    a=b=n.to_i
    a,b = a-1,b+1 while !a.prime?  and !b.prime?
    p a.prime? ? a : b
}

st0le

Posted 2011-04-09T21:12:23.933

Reputation: 2 002

Using inbuilt primes is not a good choice as this is not codegolf and the whole point is to implement a fast approach,the decision of the best score is to be based on the complexity of the solution so this is not allowed,sorry. – Quixotic – 2011-04-10T14:46:31.890

0

Java

This takes <1 second until num starts being greater than 10^8. Not efficient enough, considering 2^64 is about 1.8*10^19. (Started 10^15 6 minutes ago, and is still running D:)

import java.util.*;

class ClosestPrime {

    public static double closest(double num) {
        double returnme = 0;
        if (isPrime(num)){returnme = num;}
        for (double i = 0; i < num / 2; i++) { //checks each side of num
            if (isPrime(num - i)) {returnme = num - i;
                break;}
            if (isPrime(num + i)) {returnme = num + i;
                break;}
        }
        return returnme;
    }

    private static boolean isPrime(double num) {
        long sqrtnum = (long) Math.sqrt(num); //no need to check for factors above sqrt(num)
        List<Double> primes = new LinkedList<Double>();
        primes.add((double) 2);
        for (double i = 3; i < sqrtnum; i+=2) {primes.add(i);} //fill list with odd numbers

        for (long i = 2; i <= sqrtnum; i++) {
            if (num / i % 1 == 0) {return false;}   
            ListIterator<Double> iter = primes.listIterator();
            while (iter.hasNext()) {if ((iter.next()) / i % 1 == 0){iter.remove();}} //sieving by Eratosthenes
        }
        return true;
    }
}

This gives a surefire answer every time, since it doesn't use a probabilistic algorithm, but pays heavily for that in terms of efficiency - 10^18 would have over 5 million primes in the list, and even more before sieving. May improve this sometime with a better sieve algorithm. I don't expect this to beat any of the others :)

Rin's Fourier transform

Posted 2011-04-09T21:12:23.933

Reputation: 827

0

Haskell

This is pretty fast, and non-deterministic up to a large limit. Also my first ever Haskell :). wc says 903b uncompiled.

Edit: If anyone wants to estimate the time complexity, be my guest...

import System.Environment
import Math.NumberTheory.Moduli -- arithmoi
import Data.List.Ordered -- data-ordlist

main :: IO ()
main = interact processInputStrings

processInputStrings :: String -> String
processInputStrings input = unlines $ map show $ getClosestMembers $ map read $ lines $ input 

isPrime :: Integer -> Bool
{- Implement the Miller–Rabin test with basis valid up to somewhere > 2^64 -}
isPrime 2 = True
isPrime 3 = True
isPrime t =  let
        factor :: (Integer, Integer) -> (Integer, Integer)
        factor (d,s) = if even d then factor (d `div` 2, s+1) else (d,s)
        (d,s) = factor (t-1, 0)
    in 
        and $ map (\a ->
            or [(powerMod a d t) == 1, or [(powerMod a (2^r * d) t) == t-1 | r <- [0..s-1]]]
        ) $ filter (<t) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]


getClosestMembers :: [Integer] -> [Integer]
getClosestMembers inputs = map (\i -> head [n | n <- concat [[i-d, i+d] | d <- [0..]], isPrime n]) inputs

alexander-brett

Posted 2011-04-09T21:12:23.933

Reputation: 1 485