Restituisce il numero primo più vicino


33

Sfida

Questo è semplice: dato un numero intero positivo fino a 1.000.000, restituisce il numero primo più vicino.

Se il numero stesso è primo, è necessario restituire quel numero; se ci sono due numeri primi ugualmente vicini al numero fornito, restituisce il più basso dei due.

L'input ha la forma di un singolo numero intero e anche l'output deve essere nella forma di un numero intero.

Non mi importa come prendi l'input (funzione, STDIN, ecc.) O visualizzi l'uscita (funzione, STDOUT, ecc.), Purché funzioni.

Questo è il golf del codice, quindi si applicano le regole standard: vince il programma con il minor numero di byte!

Casi test

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

5
Ciao e benvenuto in PPCG !. Per evitare il voto negativo a causa della mancanza di qualità, ti consiglio di pubblicarlo prima nella sandbox e dopo un paio di giorni pubblicarlo qui
— Luis felipe De jesus Munoz

Questo è uno dei risultati richiesti in questa sfida .
— Arnauld,

Molto strettamente correlati ma non del tutto identici.
— Giuseppe

@Arnauld L'ho visto, ma ho pensato che fossero abbastanza diversi da giustificare una nuova domanda.
— Nathan Dimmer,

2
Vedi anche OEIS A051697 .
— Eric Towers,

Risposte:


9

Gaia , 3 byte

ṅD⌡

Provalo online!

Piuttosto lento per ingressi di grandi dimensioni, ma funziona con sufficiente memoria / tempo.

Non sono sicuro del perché D⌡spinga implicitamente di znuovo, ma rende questa una risposta straordinariamente breve!

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

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

Provalo online!

Commentate

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

Ottava , 40 byte

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

Provalo online!

Questo usa il fatto che c'è sempre un primo tra ne 2*n( teorema di Bertrand – Chebyshev ).

Come funziona

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

_j}cU

Provalo o esegui tutti i casi di 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 byte

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

Provalo online!

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

1000003 è il 78499esimo numero primo. Nearestdà la priorità ai valori che appaiono in precedenza nell'elenco (che sono più bassi).


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

5

Brachylog , 7 5 byte

;I≜-ṗ

Provalo online!

Salvato 2 byte grazie a @DLosc.

Spiegazione

;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 Principalmente perché sono stupido. Grazie.
— Fatalizza il

Penso che ci siamo appena avvicinati da diverse direzioni. Pensavi ≜fin dall'inizio, suppongo, mentre pensavo di accoppiare e sottrarre e solo in seguito ho capito che avrei ≜dovuto farlo funzionare. :)
— DLosc

4

Pyth, 10 byte

haDQfP_TSy

Provalo online qui o verifica tutti i casi di test contemporaneamente qui .

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

Gelatina , 9 7 byte

ḤÆRạÞµḢ

Provalo online!

Lento per input più grandi, ma funziona bene per l'intervallo richiesto. Grazie a @EriktheOutgolfer per aver salvato 2 byte!


Ehi, è intelligente! Salva due sostituendo _A¥con ạ(differenza assoluta). Oh, e Ḥpuò davvero essere ‘.
— Erik the Outgolfer,

@EriktheOutgolfer grazie. Sicuramente l'utilizzo ‘non funzionerà sempre? Significa che verranno trovati solo numeri primi fino a n + 1, mentre il più vicino potrebbe essere n + 2.
— Nick Kennedy,

Hm, questa è una preoccupazione.
— Erik the Outgolfer,

4

Python 2 , 71 byte

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

Provalo online!

p(K-1)!2p%kabs(k-n)kk-nabsnk

L'espressione k+n-p%k*2*nè progettata per dare k-nsu numeri primi (dove p%k=1), e altrimenti un valore "cattivo" k+nche è sempre maggiore in valore assoluto e quindi non influisce sul minimo, in modo che i non numeri primi vengano passati.



3

Ordinato , 43 byte

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

Provalo online!

Spiegazione

Questa è una lambda con parametro x. Funziona creando la seguente sequenza:

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

Questo è unire le due sequenze ]x, -1, -∞](sinistra-chiusa, destra-aperta) e [x, ∞](entrambe aperte).

Per x = 80, questo sembra:

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

Quindi, usiamo f↦sper selezionare tutti gli elementi ssoddisfacenti f. In questo caso, filtriamo tutti i numeri compositi, lasciando solo i numeri primi. Per lo stesso x, questo diventa:

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

Quindi, usiamo (...)@0per selezionare il primo membro di questa sequenza. Poiché è necessario selezionare la parte inferiore delle due, la sequenza che inizia con x - 1viene prima unita.

Nota: solo uno di xe x - 1può essere primo, quindi va bene che la sequenza di giunzione inizi con x - 1. Sebbene la sequenza possa essere aperta su entrambi i lati ( [x,-1,-∞]), ciò includerebbe inutilmente xdue volte nella sequenza. Quindi, per "efficienza", ho scelto la versione con chiusura a sinistra (anche perché mi piace mostrare Tidy).



3

APL (Dyalog Extended) , 20 15 byte SBCS

Tacita funzione del prefisso ispirata alla risposta J di Galen Ivanov .

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

Provalo online!

⍳ Dice uno attraverso l'argomento.

¯2⍭ ennesimi numeri primi

⊢(... ) applica la seguente funzione tacita, con l'argomento originale come argomento sinistro:

 ⊢ i numeri primi

 ⊇ indicizzato da:

  ⍋ il grado crescente (indici che ordinerebbero in ordine crescente)
  ⍤ della
  | grandezza (valore assoluto)
  ⍤ delle
  - differenze

 ⊃ scegli il primo (cioè quello con la differenza più piccola)


3

Perl 6 , 35 byte

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

Provalo online!

Questo utilizza la tecnica di Veitcel per generare l'elenco di 0, -1, 2, -3ma semplifica notevolmente l' ($*=-1)*$++utilizzo delle variabili di stato anonime disponibili in P6 (in origine avevo -1 ** $++ * $++, ma quando il golf perdeva la precedenza). C'è un checker incorporato ma sfortunatamente untilimpedisce il valore restituito automagicamente, quindi c'è un extra in $_giro.


Di solito userei un approccio con l'operatore di sequenza a qualcosa del genere, ma esce a un byte in più , quindi un bel lavoro per trovare un metodo più breve
— Jo King

@JoKing buona cattura. Le cose che accadono quando gioco a golf troppo velocemente dopo aver trovato una soluzione funzionante. Ne avevo uno simile ma la dannata mancanza di [-1] haha
— user0721090601

3

C, 122 121 104 byte

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

Usalo chiamando la funzione c()e passando come argomento il numero; dovrebbe restituire il numero primo più vicino.

Grazie a Embodiment of Ignorance per 1 byte risparmiato un grande miglioramento.

Provalo online!


Ma c()riceve due parametri ... Inoltre, probabilmente si può accorciare la while(1)a for(;;)(non testato, dal momento che non ho ricevuto come eseguire il codice
— incarnazione di ignoranza

@EmbodimentofIgnorance L'ho scritto e testato tutto su un compilatore c online , potrei chiamare c()passando solo il primo parametro. E hai ragione, for(;;)mi fa risparmiare un byte, restano solo 117 per ottenere il primo posto :)
— Lince Assassino,

110 byte: #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;}}. Ecco un link TIO: tio.run/…
— Incarnazione dell'ignoranza il




2

APL (NARS), 38 caratteri, 76 byte

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

0π è il test per il primo, ¯1π il primo primo, 1π è il primo successivo; 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 byte

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

Provalo online!

/^.?$|^(..+?)\1+$/ è difficile regexp per controllare prime

(-1)**$a*($a++) genera sequenza 0, -1, 2, -3 ...


2

MathGolf , 10 byte

∞╒g¶áÅ-±├Þ

Provalo online.

Spiegazione:

∞            # 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 Grazie! Sapevo che Max aveva pensato di cambiarlo, ma non sapevo che lo facesse davvero. I documenti dichiarano ancora quello vecchio.
— Kevin Cruijssen,

Ah, io uso il file mathgolf.txt come riferimento, poiché sembra essere più aggiornato
— Jo King

@JoKing Sì, ieri mi ha parlato anche di quel file. Lo userò d'ora in poi. :)
— Kevin Cruijssen il


2

C # (compilatore interattivo Visual C #) , 104 100 byte

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

Provalo online!

Spiegazione:

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 byte

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

La risposta di Port of @NaturalNumberGuy (prima) in C , quindi assicurati di votarlo !!
-1 byte grazie a @ OlivierGrégoire .

Provalo online.

Spiegazione:

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.