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.