Renvoyer le nombre premier le plus proche


33

Défi

C’est simple: avec un entier positif pouvant aller jusqu’à 1 000 000, retourne le nombre premier le plus proche.

Si le nombre lui-même est premier, vous devez alors le renvoyer; s'il y a deux nombres premiers proches du nombre fourni, renvoie le plus bas des deux.

L'entrée est sous la forme d'un entier unique, et la sortie doit également être sous la forme d'un entier.

Je me moque de la façon dont vous prenez en entrée (fonction, STDIN, etc.) ou affichez la sortie (fonction, STDOUT, etc.), tant que cela fonctionne.

Ceci est un code de golf, donc les règles standard s'appliquent - le programme avec le moins d'octets gagne!

Cas de test

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

5
Bonjour et bienvenue sur PPCG!. Pour éviter les votes négatifs en raison d'un manque de qualité, je vous suggère de le poster dans le bac à sable, puis après quelques jours, ici
Luis felipe De jesus Munoz

C'est l'un des résultats attendus dans ce défi .
Arnauld

Très étroitement lié mais pas tout à fait identique.
Giuseppe

@Arnauld, j'ai vu cela, mais je pensais qu'ils étaient suffisamment différents pour justifier une nouvelle question.
Nathan Dimmer

2
Voir aussi OEIS A051697 .
Eric Towers

Réponses:


9

Gaia , 3 octets

ṅD⌡

Essayez-le en ligne!

Plutôt lent pour les entrées volumineuses, mais fonctionne avec suffisamment de mémoire / temps.

Je ne sais pas pourquoi, D⌡implicitement, pousse à znouveau, mais cela rend la réponse remarquablement courte!

ṅ	| 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

13

JavaScript (ES6), 53 octets

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

Essayez-le en ligne!

Commenté

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)


7

Octave , 40 octets

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

Essayez-le en ligne!

Ceci utilise le fait qu’il existe toujours un nombre premier entre net 2*n( théorème de Bertrand – Chebyshev ).

Comment ça marche

@(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

6

Japt , 5 octets

_j}cU

Essayez-le ou lancez tous les cas de test

_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


5

Wolfram Language (Mathematica) , 31 octets

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

Essayez-le en ligne!

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

1000003 est le 78499ème nombre premier. Nearestdonne la priorité aux valeurs qui apparaissent plus tôt dans la liste (qui sont plus basses).


5
Nearest[Prime@Range@#,#,1]&pour 27
Ben

5

Brachylog , 7 5 octets

;I≜-ṗ

Essayez-le en ligne!

2 octets sauvés grâce à @DLosc.

Explication

;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

@DLosc Principalement parce que je suis stupide. Merci.
Fataliser

Je pense que nous venons de l'aborder dans différentes directions. Je pensais que vous y pensiez dès le début, alors que je pensais au couplage et à la soustraction et que je ne réalisais que plus tard que j’avais besoin que cela fonctionne. :)
DLosc

4

Pyth, 10 octets

haDQfP_TSy

Essayez-le en ligne ici ou vérifiez tous les cas de test en même temps ici .

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

4

Gelée , 9 7 octets

ḤÆRạÞµḢ

Essayez-le en ligne!

Lent pour une entrée plus importante, mais fonctionne correctement pour la plage demandée. Merci à @EriktheOutgolfer pour la sauvegarde de 2 octets!


Hé, c'est intelligent! Économisez deux en remplaçant _A¥par (différence absolue). Oh, et peut vraiment l'être .
Erik the Outgolfer

@EriktheOutgolfer merci. Utiliser ne fonctionnera pas toujours? Cela signifie que seuls les nombres premiers jusqu'à n + 1 seront trouvés, alors que le plus proche pourrait être n + 2.
Nick Kennedy

Hm, c'est une préoccupation.
Erik l'Outgolfer

4

Python 2 , 71 octets

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

Essayez-le en ligne!

Une fonction récursive qui utilise le générateur de prime du théorème de Wilson . Les ppistes du produit(k-1)!2, et p%kvaut 1 pour les nombres premiers et 0 pour les non premiers. Pour faciliter la comparaison abs(k-n)de différents nombres premiers k, nous enregistrons k-net comparons via abs, en ajoutant npour obtenir le résultat.k .

L'expression k+n-p%k*2*nest conçue pour donner des k-nnombres premiers (où p%k=1), et sinon une "mauvaise" valeur k+ntoujours plus grande en valeur absolue et n'affectant donc pas le minimum, de sorte que les non-premiers soient ignorés.



3

Bien rangé , 43 octets

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

Essayez-le en ligne!

Explication

C'est un lambda avec paramètre x. Cela fonctionne en créant la séquence suivante:

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

C’est la fusion des deux séquences ]x, -1, -∞](gauche fermée, droite ouverte) et[x, ∞] (toutes deux ouvertes).

Pour x = 80, cela ressemble à:

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

Ensuite, nous utilisons f↦spour sélectionner tous les éléments de ssatisfaire f. Dans ce cas, nous filtrons tous les nombres composés, ne laissant que les premiers. Pour le même x, cela devient:

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

Ensuite, nous utilisons (...)@0pour sélectionner le premier membre de cette séquence. Étant donné que le plus bas des deux doit être sélectionné, la séquence qui commence par x - 1est épissée en premier.

Remarque: Un seul élément sur xet x - 1peut être premier, il est donc normal que la séquence épissée commence par x - 1. Bien que la séquence puisse être ouverte des deux côtés ( [x,-1,-∞]), cela inclurait inutilement xdeux fois la séquence. Alors, par souci d'efficacité, j'ai choisi la version fermée à gauche (aussi parce que j'aime montrer Tidy).



3

APL (Dyalog Extended) , 20 SBCS de 15 octets

Fonction de préfixe tacite inspirée de la réponse de Galen Ivanov .

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

Essayez-le en ligne!

ɩ ndices un à l'argument.

¯2⍭ nièmes premiers de cela

⊢() Applique la fonction tacite suivante à celle-ci, avec l'argument d'origine en tant qu'argument de gauche:

 les primes

 indexé par:

   la note ascendante (indices triés par ordre croissant)
   de
  | la magnitude (valeur absolue)
   des
  - différences

 choisissez le premier (c'est-à-dire celui qui présente la plus petite différence)


3

Perl 6 , 35 octets

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

Essayez-le en ligne!

Cela fait appel à la technique de Veitcel pour générer la liste 0, -1, 2, -3mais simplifie grandement l’ ($*=-1)*$++utilisation des variables d’état anonymes disponibles dans P6 (je l’avais à l’origine -1 ** $++ * $++mais j’ai perdu la priorité lorsqu’il est négatif). Il existe un vérificateur principal intégré, mais malheureusement, il untilempêche la valeur renvoyée automatiquement, de sorte qu'il y a une attente supplémentaire $_.


J'utilisais généralement une approche d'opérateur de séquence pour quelque chose comme ceci, mais je décrivais un octet plus long , un travail si agréable pour trouver une méthode plus courte
Jo King

@JoKing bonne prise. Ce qui arrive quand je joue trop rapidement après avoir trouvé une solution efficace. J'avais un pareil mais le maudit manque de [-1] haha
user0721090601

3

C, 122 121 104 octets

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;}

Utilisez-la en appelant la fonction c()et en passant comme argument le nombre; il devrait retourner le nombre premier le plus proche.

Merci à Incarnation of Ignorance pour 1 octet enregistré une grande amélioration.

Essayez-le en ligne!


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

@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

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: tio.run/…
Embodiment of Ignorance




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 


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 ...


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)

@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

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

@JoKing Yeah, he told me yesterday about that file as well. Will use it from now on. :)
Kevin Cruijssen


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

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

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!


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

@KevinCruijssen Oops, rollbacked!
Olivier Grégoire

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

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

1
Inside 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

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

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

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

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*/
} 
)


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.