Return the Closest Prime Number

33

5

Challenge

This is a simple one: Given a positive integer up to 1,000,000, return the closest prime number.

If the number itself is prime, then you should return that number; if there are two primes equally close to the provided number, return the lower of the two.

Input is in the form of a single integer, and output should be in the form of an integer as well.

I don't care how you take in the input (function, STDIN, etc.) or display the output (function, STDOUT, etc.), as long as it works.

This is code golf, so standard rules apply—the program with the least bytes wins!

Test Cases

Input  =>  Output
------    -------
80     =>      79
100    =>     101
5      =>       5
9      =>       7
532    =>     523
1      =>       2

Nathan Dimmer

Posted 2019-03-27T15:16:02.610

Reputation: 511

5

Hi and welcome to PPCG!. To avoid down voting due to lack of quality I suggest you to post it to the sandbox first and after a couple of days post it here

– Luis felipe De jesus Munoz – 2019-03-27T15:17:50.320

This is one of the outputs requested in this challenge.

– Arnauld – 2019-03-27T15:24:13.603

Very closely related but not quite identical. – Giuseppe – 2019-03-27T15:35:43.907

@Arnauld I saw that one, but I thought that they were different enough to warrant a new question. – Nathan Dimmer – 2019-03-27T15:37:30.270

@Giuseppe Yeah, I found out about that one after already posting... – Nathan Dimmer – 2019-03-27T15:42:11.840

@Arnauld Good idea! Added. – Nathan Dimmer – 2019-03-27T15:53:25.973

@Arnauld Oh! That’s really good! – Nathan Dimmer – 2019-03-27T16:19:24.503

Welcome to PPCG. Nice challenge and +1 for your opening note. Sandbox, as suggested by others, is a great place to start. – ElPedro – 2019-03-27T19:12:19.357

2

See also OEIS A051697.

– Eric Towers – 2019-03-28T08:52:32.563

@EricTowers Oh wow... That's really convenient! How should I reference that in my question? – Nathan Dimmer – 2019-03-28T11:23:50.557

@Bobawob just add it in and say something like "This is OEIS A051697" with a link. Simple enough :-) – Giuseppe – 2019-03-28T14:30:43.543

Can anyone get this working with JS generators? I haven't had much luck here

– Pureferret – 2019-03-29T15:44:37.713

Answers

9

Gaia, 3 bytes

ṅD⌡

Try it online!

Rather slow for large inputs, but works given enough memory/time.

I'm not sure why D⌡ implicitly pushes z again, but it makes this a remarkably short answer!

ṅ	| implicit input z: push first z prime numbers, call it P
 D⌡	| take the absolute difference between P and (implicit) z,
	| returning the smallest value in P with the minimum absolute difference

Giuseppe

Posted 2019-03-27T15:16:02.610

Reputation: 21 077

13

JavaScript (ES6), 53 bytes

n=>(g=(o,d=N=n+o)=>N%--d?g(o,d):d-1?g(o<0?-o:~o):N)``

Try it online!

Commented

n => (            // n = input
  g = (           // g = recursive function taking:
    o,            //   o = offset
    d =           //   d = current divisor, initialized to N
    N = n + o     //   N = input + offset
  ) =>            //
    N % --d ?     // decrement d; if d is not a divisor of N:
      g(o, d)     //   do recursive calls until it is
    :             // else:
      d - 1 ?     //   if d is not equal to 1 (either N is composite or N = 1):
        g(        //     do a recursive call with the next offset:
          o < 0 ? //       if o is negative:
            -o    //         make it positive (e.g. -1 -> +1)
          :       //       else:
            ~o    //         use -(o + 1) (e.g. +1 -> -2)
        )         //     end of recursive call
      :           //   else (N is prime):
        N         //     stop recursion and return N
)``               // initial call to g with o = [''] (zero-ish)

Arnauld

Posted 2019-03-27T15:16:02.610

Reputation: 111 334

10

05AB1E, 5 bytes

Åps.x

Try it online! or as a Test Suite

Inefficient for big numbers

Emigna

Posted 2019-03-27T15:16:02.610

Reputation: 50 798

3Too bad Ån is "In case of a tie, the higher prime is pushed" Didn't even knew we had this builtin, tbh. – Kevin Cruijssen – 2019-03-28T07:51:01.577

@KevinCruijssen: Neither did I until now :) – Emigna – 2019-03-28T09:15:51.940

7

Octave, 40 bytes

@(n)p([~,k]=min(abs(n-(p=primes(2*n)))))

Try it online!

This uses the fact that there is always a prime between n and 2*n (Bertrand–Chebyshev theorem).

How it works

@(n)p([~,k]=min(abs(n-(p=primes(2*n)))))

@(n)                                      % Define anonymous function with input n
                       p=primes(2*n)      % Vector of primes up to 2*n. Assign to p
                abs(n-(             ))    % Absolute difference between n and each prime
      [~,k]=min(                      )   % Index of first minimum (assign to k; not used)
    p(                                 )  % Apply that index to p

Luis Mendo

Posted 2019-03-27T15:16:02.610

Reputation: 87 464

6

Japt, 5 bytes

_j}cU

Try it or run all test cases

_j}cU     :Implicit input of integer U
_         :Function taking an integer as an argument
 j        :  Test if integer is prime
  }       :End function
   cU     :Return the first integer in [U,U-1,U+1,U-2,...] that returns true

Shaggy

Posted 2019-03-27T15:16:02.610

Reputation: 24 623

5

05AB1E, 4 bytes

z-Ån

Try it online!

Grimmy

Posted 2019-03-27T15:16:02.610

Reputation: 12 521

5

Brachylog, 7 5 bytes

;I≜-ṗ

Try it online!

Saved 2 bytes thanks to @DLosc.

Explanation

;I≜      Label an unknown integer I (tries 0, then 1, then -1, then 2, etc.)
   -     Subtract I from the input
    ṗ    The result must be prime

Fatalize

Posted 2019-03-27T15:16:02.610

Reputation: 32 976

@DLosc Mostly because I am stupid. Thanks. – Fatalize – 2019-03-29T08:26:24.017

I think we just approached it from different directions. You were thinking about from the start, I assume, whereas I was thinking about pairing and subtracting and only later realized I'd need to make it work. :) – DLosc – 2019-03-29T21:27:43.023

5

Wolfram Language (Mathematica), 31 bytes

Nearest[Prime~Array~78499,#,1]&

Try it online!

                              & (*pure function*)
        Prime~Array~78499       (*among the (ascending) first 78499 primes*)
                            1   (*select one*)
Nearest[                 ,#, ]  (*which is nearest to the argument*)

1000003 is the 78499th prime. Nearest prioritizes values which appear earlier in the list (which are lower).

attinat

Posted 2019-03-27T15:16:02.610

Reputation: 3 495

5Nearest[Prime@Range@#,#,1]& for 27 – Ben – 2019-03-29T16:10:42.730

4

Pyth, 10 bytes

haDQfP_TSy

Try it online here, or verify all the test cases at once here.

haDQfP_TSyQ   Implicit: Q=eval(input())
              Trailing Q inferred
         yQ   2 * Q
        S     Range from 1 to the above
    f         Filter keep the elements of the above, as T, where:
     P_T        Is T prime?
  D           Order the above by...
 a Q          ... absolute difference between each element and Q
                This is a stable sort, so smaller primes will be sorted before larger ones if difference is the same
h             Take the first element of the above, implicit print

Sok

Posted 2019-03-27T15:16:02.610

Reputation: 5 592

4

Jelly, 9 7 bytes

ḤÆRạÞµḢ

Try it online!

Slow for larger input, but works ok for the requested range. Thanks to @EriktheOutgolfer for saving 2 bytes!

Nick Kennedy

Posted 2019-03-27T15:16:02.610

Reputation: 11 829

Hey, that's clever! Save two by substituting _A¥ with (absolute difference). Oh, and can really be . – Erik the Outgolfer – 2019-03-27T19:08:27.340

@EriktheOutgolfer thanks. Surely using won’t always work? It means that only primes up to n+1 will be found, while the closest might be n+2. – Nick Kennedy – 2019-03-27T22:39:37.063

Hm, that's a concern. – Erik the Outgolfer – 2019-03-27T22:40:21.620

4

Python 2, 71 bytes

f=lambda n,k=1,p=1:k<n*3and min(k+n-p%k*2*n,f(n,k+1,p*k*k)-n,key=abs)+n

Try it online!

A recursive function that uses the Wilson's Theorem prime generator. The product p tracks \$(k-1)!^2\$, and p%k is 1 for primes and 0 for non-primes. To make it easy to compare abs(k-n) for different primes k, we store k-n and compare via abs, adding back n to get the result k.

The expression k+n-p%k*2*n is designed to give k-n on primes (where p%k=1), and otherwise a "bad" value of k+n that's always bigger in absolute value and so doesn't affect the minimum, so that non-primes are passed over.

xnor

Posted 2019-03-27T15:16:02.610

Reputation: 115 687

4

C (gcc), 87 76 74 72 bytes

Optimization of innat3's C# (Visual C# Interactive Compiler), 100 bytes

f(n,i,t,r,m){for(t=0,m=n;r-2;t++)for(r=i=1,n+=n<m?t:-t;i<n;n%++i||r++);}

Try it online!

Natural Number Guy

Posted 2019-03-27T15:16:02.610

Reputation: 211

Hello and welcome to PPCG. A few tips: r!=2 is equivalent to r-2, n%++i?0:r++ can most likely be n%++i||r++. – Jonathan Frech – 2019-03-29T13:11:16.657

I didn't immediately see that. Thanks. – Natural Number Guy – 2019-03-29T15:13:16.900

3

Wolfram Language (Mathematica), 52 bytes

If[PrimeQ[s=#],s,#&@@Nearest[s~NextPrime~{-1,1},s]]&

Try it online!

J42161217

Posted 2019-03-27T15:16:02.610

Reputation: 15 931

You have an extra space that can be removed to save a byte. – Ben – 2019-03-29T16:03:13.823

@Ben you are right. thanx – J42161217 – 2019-03-29T23:08:07.113

3

APL (Dyalog Extended), 20 15 bytesSBCS

Tacit prefix function inspired by Galen Ivanov's J answer.

⊢(⊃⍋⍤|⍤-⊇⊢)¯2⍭⍳

Try it online!

ɩndices one through the argument.

¯2⍭ nth primes of that

⊢() apply the following tacit function to that, with the original argument as left argument:

 the primes

 indexed by:

   the ascending grade (indices which would sort ascending)
   of
  | the magnitude (absolute value)
   of
  - the differences

 pick the first one (i.e. the one with smallest difference)

Adám

Posted 2019-03-27T15:16:02.610

Reputation: 37 779

3

C, 122 121 104 bytes

p(a,i){for(i=1;++i<a;)if(a%i<1)return 0;return a>1;}c(a,b){for(b=a;;b++)if(p(--a)|p(b))return p(b)?b:a;}

Use it calling function c() and passing as argument the number; it should return the closest prime.

Thanks to Embodiment of Ignorance for 1 byte saved a big improvement.

Try it online!

Lince Assassino

Posted 2019-03-27T15:16:02.610

Reputation: 111

But c() receives two parameters... Also, you can probably shorten the while(1) to for(;;) (untested, since I don't get how to run your code – Embodiment of Ignorance – 2019-03-28T05:03:30.513

@EmbodimentofIgnorance I wrote it and tested it all on an online c compiler, I could call c() passing only the first parameter. And you are right, for(;;) saves me a byte, only 117 left to get first place :)

– Lince Assassino – 2019-03-28T11:30:33.653

110 bytes: #define r return p(a,i){i=1;while(++i<a)if(a%i<1)r 0;r a>1;}c(a,b){b=a;for(;;b++){if(p(--a))r a;if(p(b))r b;}}. Here is a TIO link: https://tio.run/##TU5BTsQwDLznFdaiSomaSi0IBHK7F54Be3DaBCwtoUqLOFR5e3HKZX0Ye@wZ22MzXil@7Pvd5ANHDwmSX39SVLMmy2bjocPfT756Xdfck@GgqeK@MwlaTEDnDvMoUmc2NxCG76QRXV2LM@hZNw0ZkRIezJXaYc674rjCF3HURm0KJEpj9cv6Sotf3i4wwAbPrYWuFXi08CL4cC8cMqrDUW4VF4u2RUk9PCHIm@YY/68tMSeRBX2qJmjOUE3v8WRvbvHFwqhvuTF4mLPK@x8

– Embodiment of Ignorance – 2019-03-28T21:06:48.587

The 101 bytes version doesn't seem to be working, according to the test cases. And I couldn't get my head around the new p() function to try and fix it. – Lince Assassino – 2019-03-29T17:16:47.220

102 bytes – ceilingcat – 2019-04-02T02:22:55.047

3

Tidy, 43 bytes

{x:(prime↦splice(]x,-1,-∞],[x,∞]))@0}

Try it online!

Explanation

This is a lambda with parameter x. This works by creating the following sequence:

[x - 1, x, x - 2, x + 1, x - 3, x + 2, x - 4, x + 3, ...]

This is splicing together the two sequences ]x, -1, -∞] (left-closed, right-open) and [x, ∞] (both open).

For x = 80, this looks like:

[79, 80, 78, 81, 77, 82, 76, 83, 75, 84, 74, 85, ...]

Then, we use f↦s to select all elements from s satisfying f. In this case, we filter out all composite numbers, leaving only the prime ones. For the same x, this becomes:

[79, 83, 73, 71, 89, 67, 97, 61, 59, 101, 103, 53, ...]

Then, we use (...)@0 to select the first member of this sequence. Since the lower of the two needs to be selected, the sequence which starts with x - 1 is spliced in first.

Note: Only one of x and x - 1 can be prime, so it is okay that the spliced sequence starts with x - 1. Though the sequence could be open on both sides ([x,-1,-∞]), this would needlessly include x twice in the sequence. So, for sake of "efficiency", I chose the left-closed version (also because I like to show off Tidy).

Conor O'Brien

Posted 2019-03-27T15:16:02.610

Reputation: 36 228

3

Factor, 91 bytes

: p ( x -- x ) [ nprimes ] keep dupd [ - abs ] curry map swap zip natural-sort first last ;

Try it online!

Galen Ivanov

Posted 2019-03-27T15:16:02.610

Reputation: 13 815

3

Perl 6, 35 bytes

{$_+=($*=-1)*$++until .is-prime;$_}

Try it online!

This uses Veitcel's technique for generating the list of 0, -1, 2, -3 but simplifies it greatly to ($*=-1)*$++ using the anonymous state variables available in P6 (I originally had -1 ** $++ * $++, but when golfed the negative loses precedence). There's a built in prime checker but unfortunately the until prevents the automagically returned value so there's an extra $_ hanging around.

user0721090601

Posted 2019-03-27T15:16:02.610

Reputation: 928

I'd usually use a sequence operator approach to something like this, but comes out to one byte longer, so nice work finding a shorter method

– Jo King – 2019-03-29T00:39:20.007

@JoKing good catch. The things that happen when I golf too quickly after getting a working solution. I had a similar one but the damned lack of [-1] haha

– user0721090601 – 2019-03-29T00:49:17.873

2

Python 2 (Cython), 96 bytes

l=lambda p:min(filter(lambda p:all(p%n for n in range(2,p)),range(2,p*3)),key=lambda x:abs(x-p))

Try it online!

Snaddyvitch Dispenser

Posted 2019-03-27T15:16:02.610

Reputation: 101

Might be able to save a couple bytes via r=range;... – Skyler – 2019-03-28T20:33:46.897

1@Arnauld, it now works for x=1 – Snaddyvitch Dispenser – 2019-03-29T08:20:36.233

2

VDM-SL, 161 bytes

f(i)==(lambda p:set of nat1&let z in set p be st forall m in set p&abs(m-i)>=abs(z-i)in z)({x|x in set{1,...,9**7}&forall y in set{2,...,1003}&y<>x=>x mod y<>0})

A full program to run might look like this - it's worth noting that the bounds of the set of primes used should probably be changed if you actually want to run this, since it will take a long time to run for 1 million:

functions
f:nat1+>nat1
f(i)==(lambda p:set of nat1&let z in set p be st forall m in set p&abs(m-i)>=abs(z-i)in z)({x|x in set{1,...,9**7}&forall y in set{2,...,1003}&y<>x=>x mod y<>0})

Explanation:

f(i)==                                        /* f is a function which takes a nat1 (natural number not including 0)*/
(lambda p:set of nat1                         /* define a lambda which takes a set of nat1*/
&let z in set p be st                         /* which has an element z in the set such that */
forall m in set p                             /* for every element in the set*/
&abs(m-i)                                     /* the difference between the element m and the input*/
>=abs(z-i)                                    /* is greater than or equal to the difference between the element z and the input */
in z)                                         /* and return z from the lambda */
(                                             /* apply this lambda to... */
{                                             /* a set defined by comprehension as.. */
x|                                            /* all elements x such that.. */ 
x in set{1,...,9**7}                          /* x is between 1 and 9^7 */
&forall y in set{2,...,1003}                  /* and for all values between 2 and 1003*/
&y<>x=>x mod y<>0                             /* y is not x implies x is not divisible by y*/
} 
)

Expired Data

Posted 2019-03-27T15:16:02.610

Reputation: 3 129

2

APL(NARS), 38 chars, 76 bytes

{⍵≤1:2⋄0π⍵:⍵⋄d←1π⍵⋄(d-⍵)≥⍵-s←¯1π⍵:s⋄d}

0π is the test for prime, ¯1π the prev prime, 1π is the next prime; test:

  f←{⍵≤1:2⋄0π⍵:⍵⋄d←1π⍵⋄(d-⍵)≥⍵-s←¯1π⍵:s⋄d}
  f¨80 100 5 9 532 1
79 101 5 7 523 2 

RosLuP

Posted 2019-03-27T15:16:02.610

Reputation: 3 036

2

J, 19 15 bytes

(0{]/:|@-)p:@i.

Try it online!

Galen Ivanov

Posted 2019-03-27T15:16:02.610

Reputation: 13 815

2

Perl 5, 59 bytes

$a=0;while((1x$_)=~/^.?$|^(..+?)\1+$/){$_+=(-1)**$a*($a++)}

Try it online!

/^.?$|^(..+?)\1+$/ is tricky regexp to check prime

(-1)**$a*($a++) generate sequence 0,-1, 2,-3 ...

Veitcel

Posted 2019-03-27T15:16:02.610

Reputation: 61

2

MathGolf, 10 bytes

∞╒g¶áÅ-±├Þ

Try it online.

Explanation:

∞            # Double the (implicit) input-integer
 ╒           # Create a list in the range [1, 2*n]
  g¶         # Filter so only the prime numbers remain
    áÅ       # Sort this list using the next two character:
      -±     #  The absolute difference with the (implicit) input-integer
        ├    # Push the first item of the list
             # (unfortunately without popping the list itself, so:)
         Þ   # Discard everything from the stack except for the top
             # (which is output implicitly as result)

Kevin Cruijssen

Posted 2019-03-27T15:16:02.610

Reputation: 67 575

@JoKing Thanks! I knew Max thought about changing it, but didn't knew he actually did. The docs still state the old one. – Kevin Cruijssen – 2019-03-28T08:53:16.577

Ah, I use the mathgolf.txt file as reference, since it seems to be more up to date

– Jo King – 2019-03-28T23:21:14.947

@JoKing Yeah, he told me yesterday about that file as well. Will use it from now on. :) – Kevin Cruijssen – 2019-03-29T07:23:35.597

2

C# (Visual C# Interactive Compiler), 104 100 bytes

n=>{int r=0,t=0,m=n;while(r!=2){n+=(n<m)?t:-t;t++;r=0;for(int i=1;i<=n;i++)if(n%i==0)r++;}return n;}

Try it online!

Explanation:

int f(int n)
{
    int r = 0; //stores the amount of factors of "n"
    int t = 0; //increment used to cover all the integers surrounding "n"
    int m = n; //placeholder to toggle between adding or substracting "t" to "n"

    while (r != 2) //while the amount of factors found for "n" is different to 2 ("1" + itself)
    {
        n += (n < m) ? t : -t; //increment/decrement "n" by "t" (-0, -1, +2, -3, +4, -5,...)
        t++;
        r = 0;
        for (int i = 1; i <= n; i++) //foreach number between "1" and "n" increment "r" if the remainder of its division with "n" is 0 (thus being a factor)
            if (n % i == 0) r++; 
    }
    return n;
}

Console.WriteLine(f(80)); //79

Innat3

Posted 2019-03-27T15:16:02.610

Reputation: 791

2

Haskell, 79 74 bytes (thanks to Laikoni)

72 bytes as annonymus function (the initial "f=" could be removed in this case).

f=(!)(-1);n!x|x>1,all((>0).mod x)[2..x-1]=x|y<-x+n=last(-n+1:[-n-1|n>0])!y

Try it online!


original code:

f=(!)(-1);n!x|x>1&&all((>0).mod x)[2..x-1]=x|1>0=(last$(-n+1):[-n-1|n>0])!(x+n)

Try it online!

Explanation:

f x = (-1)!x

isPrime x = x > 1 && all (\k -> x `mod` k /= 0)[2..x-1]
n!x | isPrime x = x            -- return the first prime found
    | n>0       = (-n-1)!(x+n) -- x is no prime, continue with x+n where n takes the 
    | otherwise = (-n+1)!(x+n) -- values -1,2,-3,4 .. in subsequent calls of (!)

Sachera

Posted 2019-03-27T15:16:02.610

Reputation: 51

1Inside a guard you can use , instead of &&. (last$ ...) can be last(...), and the second guard 1>0 can be used for a binding to save parenthesis, e.g. y<-x+n. – Laikoni – 2019-03-30T10:57:10.673

Anonymous functions are generally allowed, so the initial f= does not need to be counted. Also the parenthesis enclosing (-1+n) can be dropped. – Laikoni – 2019-03-30T11:22:39.303

Thanks for the suggestions. I didn't know "," and bindings are allowed in function guards! But i don't really like the idea of an annonymous function as an answer. It doesn't feel right in my opinion. – Sachera – 2019-03-31T02:58:58.720

You can find more tips in our collection of tips for golfing in Haskell. There is also a Guide to Golfing Rules in Haskell and dedicated chat room: Of Monads and Men.

– Laikoni – 2019-03-31T22:13:42.813

2

Java (JDK), 103 bytes

n->{int p=0,x=0,z=n,d;for(;p<1;p=p>0?z:0,z=z==n+x?n-++x:z+1)for(p=z/2,d=1;++d<z;)p=z%d<1?0:p;return p;}

Try it online!

Olivier Grégoire

Posted 2019-03-27T15:16:02.610

Reputation: 10 647

Umm.. I had already create a port of his answer.. ;) Although yours is 1 byte shorter, so something is different. EDIT: Ah, I have a result-integer outside the loop, and you modify the input inside the loop, hence the -1 byte for ;. :) Do you want me to delete my answer?.. Feel free to copy the explanation.

– Kevin Cruijssen – 2019-03-29T12:50:58.177

@KevinCruijssen Oops, rollbacked! – Olivier Grégoire – 2019-03-29T12:59:03.793

Sorry about that (and thanks for the -1 byte). I like your version as well, though. Already upvoted before I saw NaturalNumberGuy's answer. – Kevin Cruijssen – 2019-03-29T12:59:40.247

2

Java 8, 88 87 bytes

n->{for(int c=0,s=0,d,N=n;c!=2;s++)for(c=d=1,n+=n<N?s:-s;d<n;)if(n%++d<1)c++;return n;}

Port of @NaturalNumberGuy's (first) C answer, so make sure to upvote him!!
-1 byte thanks to @OlivierGrégoire.

Try it online.

Explanation:

n->{               // Method with integer as both parameter and return-type
  for(int c=0,     //  Counter-integer, starting at 0
          s=0,     //  Step-integer, starting at 0 as well
          d,       //  Divisor-integer, uninitialized
          N=n;     //  Copy of the input-integer
      c!=2;        //  Loop as long as the counter is not exactly 2 yet:
      s++)         //    After every iteration: increase the step-integer by 1
    for(c=d=1,     //   (Re)set both the counter and divisor to 1
        n+=n<N?    //   If the input is smaller than the input-copy:
            s      //    Increase the input by the step-integer
           :       //   Else:
            -s;    //    Decrease the input by the step-integer
        d<n;)      //   Inner loop as long as the divisor is smaller than the input
      if(n%++d     //    Increase the divisor by 1 first with `++d`
              <1)  //    And if the input is evenly divisible by the divisor:
        c++;       //     Increase the counter-integer by 1
  return n;}       //  Return the now modified input-integer as result

Kevin Cruijssen

Posted 2019-03-27T15:16:02.610

Reputation: 67 575

2

MATL, 6 bytes

t:YqYk

Try it online!

List the first n primes and find the one closest to n.

Sanchises

Posted 2019-03-27T15:16:02.610

Reputation: 8 530

1

C# (Visual C# Interactive Compiler), 112 bytes

g=>Enumerable.Range(2,2<<20).Where(x=>Enumerable.Range(1,x).Count(y=>x%y<1)<3).OrderBy(x=>Math.Abs(x-g)).First()

Try it online!

Left shifts by 20 in submission but 10 in TIO so that TIO terminates for test cases.

Expired Data

Posted 2019-03-27T15:16:02.610

Reputation: 3 129

1

Swift, 186 bytes

func p(a:Int){let b=q(a:a,b:-1),c=q(a:a,b:1);print(a-b<=c-a ? b:c)}
func q(a:Int,b:Int)->Int{var k=max(a,2),c=2;while k>c && c != a/2{if k%c==0{k+=b;c=2}else{c=c==2 ? c+1:c+2}};return k}

Try it online!

onnoweb

Posted 2019-03-27T15:16:02.610

Reputation: 211

1

Jelly, 14 bytes

ÆpæRÆnạÞƲ2>?2Ḣ

Try it online!

Erik the Outgolfer

Posted 2019-03-27T15:16:02.610

Reputation: 38 134

1

C# (Visual C# Interactive Compiler), 87 bytes

n=>{int i=0;for(;n<2||Enumerable.Range(2,n-2).Any(x=>n%x<1);n+=++i%2<1?-i:i);return n;}

Try it online!

Embodiment of Ignorance

Posted 2019-03-27T15:16:02.610

Reputation: 7 014

1

Python 2, 93 bytes

lambda n:sorted(range(1,3*n),key=lambda x:abs(x-n)if all(x%k for k in range(2,x))else 2*n)[0]

deustice

Posted 2019-03-27T15:16:02.610

Reputation: 61

1You don't need the f= in the start – Embodiment of Ignorance – 2019-03-27T20:46:34.530

@EmbodimentofIgnorance Thanks, fixed that along with the range and non-prime penalty criteria that was causing n=1 to fail – deustice – 2019-03-27T21:00:40.607

1The primality check doesn't work for Fermat pseudoprimes such as 341=31*11 which it calls prime. – xnor – 2019-03-27T21:16:46.313

1

Zsh, 101 92 91 90 bytes

-9 by collapsing the body into the head of p's loop, -1 from using i=j instead of i=$1 in main loop, -1 by replacing a && with a ,.

p(){for ((n=2;n<$1&&$1%n++;)):
(($1==n))&&<<<$1}
j=$1
for ((i=j;;++j,--i))p $i||p $j&&exit

Try it online! Try it online! Try it online!

57 48 bytes to the prime testing function, 43 41 bytes to the main loop (1 byte to the newline between them):

p(){  # prime function: takes one input, outputs via return code
for (( n = 2; n < $1 && $1 % n++; ))   # divisibility check in loop header
    :                 # no-op loop body
(( $1 == n )) &&      # if we looped up to $1:
    <<< $1            #     echo out $1. Otherwise, this will return false
}

For the last condition, we can't use the shorter (($1-n))||, because we need to return false to the main loop if we didn't find a prime. We print in the function to avoid complexity in the main loop.

j=$1                          # set i = j = $1. Doing one in and one out is smallest
for (( i = j; ; ++j , --i )) # loop indefinitely, increment and decrement
    p $i || p $j && exit      # if either $i or $j was a prime, exit

Conditionals are left-associative, which we take advantage of here. We do test the starting number twice to make the decrement logic simpler.

GammaFunction

Posted 2019-03-27T15:16:02.610

Reputation: 2 838

1

TSQL query, 155 bytes

USE master
DECLARE @ INT=1000000;

WITH C as(SELECT abs(number-500+@)r,abs(number)+2s
FROM spt_values)SELECT top 1r FROM c
WHERE 0not in(SELECT c.r%s FROM c d
WHERE c.r>s)ORDER BY abs(r-@),r

Try it online

t-clausen.dk

Posted 2019-03-27T15:16:02.610

Reputation: 2 874

@TobySpeight thanks for improving my answer. Can you please explain what this <!-- language-all: lang-sql --> does? Is it something I should include in all my answers ? – t-clausen.dk – 2019-03-28T19:24:24.760

1

That's a prettify hint; you can find out about it near the end of Editing Help.

– Toby Speight – 2019-03-28T22:18:04.623

1

Ruby, 67 bytes

def p n;n.prime?;end;def a b,c=0;p(b-c)?b-c:p(b+c)?b+c:a(b,c+1);end

Try it online!

Avilyn

Posted 2019-03-27T15:16:02.610

Reputation: 121

1

C (gcc), 78 65 bytes

f(n,i,j){for(i=j=0;j-1;i++)for(j=n+=i%2?-i:i;--j,n-1&&n%j;);i=n;}

Try it online!

f(n,i,j){
    for(i=j=0;j-1;i++)      //while j!=1
        for(j=n+=i%2?-i:i;  // step to next closest value to original input n
            --j,n-1&&n%j;); // find greatest factor which is less than j
    i=n;                    //return
}

attinat

Posted 2019-03-27T15:16:02.610

Reputation: 3 495

@ceilingcat division by 0 when n=1 – attinat – 2019-08-26T22:32:29.050

1

Ruby -rprime, 39 bytes

Relies on the idea that for any positive integer \$n\$, the \$n\$th prime is always larger than \$n\$.

->n{Prime.take(n).min_by{|i|(i-n).abs}}

Try it online!

Value Ink

Posted 2019-03-27T15:16:02.610

Reputation: 10 608

1

Wolfram Language (Mathematica), 22 bytes

RiemannR/*Round/*Prime

Try it online!

This is an approximate solution that by chance works for all of the given test cases, but gives a slightly wrong result for other inputs. The Riemann R function is an approximation of the prime-counting function, which we round to the nearest integer and then request the prime number of that index.

Roman

Posted 2019-03-27T15:16:02.610

Reputation: 1 190

1

TI-BASIC (TI-84+), 74 Bytes

Ans→A:{2,3→A:For(P,5,2A,2:If min(remainder(P,seq(X,X,3,1+√(P),2:P→∟A(1+dim(∟A:End:abs(A-∟A:∟A(1+sum(not(cumSum(Ans=min(Ans

Hexdump:
(Token hex-values found here.)

72 04 41 3E 08 32 2B 33 04 41 3E D3 50 2B 35 2B | Ans→A:{2,3→A:For(P,5,
32 41 2B 32 3E CE 1A EF 32 50 2B 23 58 2B 58 2B | 2A,2:If min(remainder(P,seq(X,X,
33 2B 31 70 BC 50 11 2B 32 3E 50 04 EB 41 10 31 | 3,1+√(P),2:P→∟A(1
70 B5 EB 41 3E D4 EE B2 41 71 EB 41 3E EB 41 10 | +dim(∟A:End:abs(A-∟A:∟A(
31 70 B6 B8 BB 29 72 6A 1A 72                   | 1+sum(not(cumSum(Ans=min(Ans

Input is an integer in Ans. Output is printed implicitly.
Note: due to limitations on how large lists can be, \$A\$ is limited to \$0 \le A \le 3953\$

Explanation:

Ans→A                                  ;store the input in a variable called "A"
{2,3→A                                 ;store the list {2 3} into a list called "A"
For(P,5,2A,2                           ;loop from 5 to two times the input using a step
                                       ; of 2
                   seq(X,X,3,1+√(P),2  ;generate a list of integers from 3 to 1 + the
                                       ; square root of the loop counter using a step of 2
                                       ; (e.g. P=21, list={3 5})
       remainder(P,                    ;then take the loop counter modulo each element
                                       ; (e.g. P=21, list={0 1})
If min(                                ;if all of the resulting elements are non-zero,
                                       ; then
P→∟A(1+dim(∟A                          ;add the loop counter's value to the list "A", the
                                       ; list of primes
End
abs(A-∟A                               ;subtract the input from the primes list and take
                                       ; the absolute value of each element (distance to
                                       ; each prime)
   1+sum(not(cumSum(Ans=min(Ans        ;find the first index of the minimum value
∟A(                                    ;then use that index to get the value in the primes
                                       ; list at that index
                                       ;implicit output

Examples:

100:prgmCDGF1F
             101
5:prgmCDGF1F
               5
80:prgmCDGF1F
              79

Tau

Posted 2019-03-27T15:16:02.610

Reputation: 1 935