Zwróć najbliższą liczbę pierwszą


33

Wyzwanie

To jest proste: biorąc pod uwagę dodatnią liczbę całkowitą do 1 000 000, zwróć najbliższą liczbę pierwszą.

Jeśli sama liczba jest liczbą pierwszą, powinieneś ją zwrócić; jeśli dwie liczby pierwsze są jednakowo zbliżone do podanej liczby, zwróć niższą z dwóch.

Dane wejściowe mają postać pojedynczej liczby całkowitej, a dane wyjściowe również powinny mieć postać liczb całkowitych.

Nie obchodzi mnie, jak odbierasz dane wejściowe (funkcja, STDIN itp.) Lub wyświetlasz dane wyjściowe (funkcja, STDOUT itp.), O ile działa.

To jest golf golfowy, więc obowiązują standardowe zasady - wygrywa program z najmniejszą liczbą bajtów!

Przypadki testowe

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

5
Cześć i witamy w PPCG !. Aby uniknąć głosowania z powodu braku jakości, sugeruję najpierw opublikowanie go w piaskownicy, a po kilku dniach tutaj
Luis felipe De jesus Munoz

Jest to jeden z wyników wymaganych w tym wyzwaniu .
Arnauld

Bardzo blisko spokrewnione, ale niezupełnie identyczne.
Giuseppe

@Arnauld Widziałem to, ale pomyślałem, że były wystarczająco różne, aby uzasadnić nowe pytanie.
Nathan Dimmer

2
Zobacz także OEIS A051697 .
Eric Towers

Odpowiedzi:


9

Gaia , 3 bajty

ṅD⌡

Wypróbuj online!

Raczej wolny dla dużych wejść, ale działa z wystarczającą ilością pamięci / czasu.

Nie jestem pewien, dlaczego D⌡niejawnie popycha zponownie, ale sprawia, że ​​jest to niezwykle krótka odpowiedź!

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

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

Wypróbuj online!

Skomentował

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

Oktawa , 40 bajtów

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

Wypróbuj online!

Wykorzystuje to fakt, że zawsze występuje liczba pierwsza pomiędzy ni 2*n( twierdzenie Bertranda – Czebyszewa ).

Jak to działa

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



5

Wolfram Language (Mathematica) , 31 bajtów

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

Wypróbuj online!

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

1000003 jest 78499-tą liczbą pierwszą. Nearestokreśla priorytety wartości, które pojawiają się wcześniej na liście (które są niższe).


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

5

Brachylog , 7 5 bajtów

;I≜-ṗ

Wypróbuj online!

Zaoszczędź 2 bajty dzięki @DLosc.

Wyjaśnienie

;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 Głównie dlatego, że jestem głupia. Dzięki.
Fatalize

Myślę, że podeszliśmy do tego z różnych kierunków. Zakładam, że myślałeś od samego początku, podczas gdy myślałem o parowaniu i odejmowaniu i dopiero później zdałem sobie sprawę, że muszę sprawić, by działało. :)
DLosc

4

Pyth, 10 bajtów

haDQfP_TSy

Spróbuj go online tutaj , lub sprawdzić wszystkie przypadki testowe od razu tutaj .

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

Galaretka , 9 7 bajtów

ḤÆRạÞµḢ

Wypróbuj online!

Wolny dla większych danych wejściowych, ale działa dobrze dla żądanego zakresu. Dzięki @EriktheOutgolfer za zapisanie 2 bajtów!


Hej, to sprytne! Zaoszczędzić dwa podstawiając _A¥z (różnica bezwzględna). Och, i naprawdę może być .
Erik the Outgolfer

@EriktheOutgolfer dzięki. Z pewnością używanie nie zawsze działa? Oznacza to, że zostaną znalezione tylko liczby pierwsze do n + 1, a najbliższym może być n + 2.
Nick Kennedy

Hm, to problem.
Erik the Outgolfer

4

Python 2 , 71 bajtów

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

Wypróbuj online!

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

Wyrażenie k+n-p%k*2*nma na celu podanie k-nliczb pierwszych (gdzie p%k=1), a poza tym „zła” wartość, k+nktóra zawsze jest większa w wartości bezwzględnej, a zatem nie wpływa na minimum, tak że pomijane są liczby niepierwotne.



3

Tidy , 43 bajty

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

Wypróbuj online!

Wyjaśnienie

To jest lambda z parametrem x. Działa to poprzez utworzenie następującej sekwencji:

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

Jest to splatanie razem dwóch sekwencji ]x, -1, -∞](lewy-zamknięty, prawy-otwarty) i [x, ∞](obie otwarte).

Dla x = 80, to wygląda:

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

Następnie f↦swybieramy wszystkie elementy z ssatysfakcjonujących f. W takim przypadku odfiltrowujemy wszystkie liczby złożone, pozostawiając tylko liczby pierwsze. Z tego samego powodu xstaje się to:

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

Następnie (...)@0wybieramy pierwszego członka tej sekwencji. Ponieważ należy wybrać niższą z dwóch, x - 1najpierw rozpoczyna się sekwencja rozpoczynająca się od .

Uwaga: Tylko jeden xi x - 1może być pierwsza, więc jest to w porządku, że łączone sekwencja rozpoczyna się x - 1. Chociaż sekwencja może być otwarta po obu stronach ( [x,-1,-∞]), niepotrzebnie obejmowałaby ona xdwukrotnie sekwencję. Tak więc ze względu na „wydajność” wybrałem wersję lewostronnie zamkniętą (również dlatego, że lubię pochwalić się Tidy).



3

APL (Dyalog Extended) , 20 15 bajtów SBCS

Milcząca funkcja przedrostka inspirowana odpowiedzią J Galena Iwanowa .

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

Wypróbuj online!

Omawia jeden z argumentów.

¯2⍭ n-te liczby pierwsze

⊢() Zastosuj do tego następującą ukrytą funkcję, z oryginalnym argumentem jako lewym argumentem:

 liczby pierwsze

 indeksowane przez:

   gatunek rosnące (indeksy, które sortowania rosnąco)
   od
  | tej (wartość bezwzględna) wielkości
   od
  - różnic

 wybierz pierwszy (tj. ten z najmniejszą różnicą)


3

Perl 6 , 35 bajtów

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

Wypróbuj online!

Wykorzystuje technikę Veitcela do generowania listy, 0, -1, 2, -3ale znacznie upraszcza ją do ($*=-1)*$++korzystania z anonimowych zmiennych stanu dostępnych w P6 (pierwotnie miałem -1 ** $++ * $++, ale kiedy grałem w golfa, ujemne traci pierwszeństwo). Jest wbudowany moduł sprawdzania liczby pierwszych, ale niestety untilzapobiega automatycznemu zwracaniu wartości, więc jest dodatkowe $_zawieszanie się.


Zwykle stosuję podejście operatora sekwencji do czegoś takiego, ale wychodzi na jeden bajt dłużej , więc miło jest znaleźć krótszą metodę
Jo King

@JoKing good catch. Rzeczy, które zdarzają się, gdy zbyt szybko gram w golfa po znalezieniu działającego rozwiązania. Miałem podobny, ale cholerny brak [-1] haha
user0721090601

3

C, 122 121 104 bajtów

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

Użyj go, wywołując funkcję c()i przekazując jako argument liczbę; powinien zwrócić najbliższą liczbę pierwszą.

Dzięki Embodiment of Ignorance na 1 bajt zaoszczędzono dużą poprawę.

Wypróbuj online!


Ale c()otrzymuje dwa parametry ... Ponadto, prawdopodobnie można skrócić while(1)do for(;;)(niesprawdzone, ponieważ nie rozumiem, jak uruchomić swój kod
wykonaniu Ignorance

@EmbodimentofIgnorance Napisałem i przetestowałem to wszystko na internetowym kompilatorze c , mogłem wywołać c()przekazanie tylko pierwszego parametru. I masz rację, for(;;)oszczędza mi bajt, zostało tylko 117, aby zdobyć pierwsze miejsce :)
Lince Assassino

110 bajtów: #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;}}. Oto link do TIO: tio.run/…
of Ignorance




2

APL (NARS), 38 znaków, 76 bajtów

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

0π jest testem liczby pierwszej, ¯1π poprzednią liczbą pierwszą, 1π jest kolejną liczbą pierwszą; 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 bajtów

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

Wypróbuj online!

/^.?$|^(..+?)\1+$/ jest trudne wyrażenie regularne, aby sprawdzić liczbę pierwszą

(-1)**$a*($a++) generuj sekwencję 0, -1, 2, -3 ...


2

MathGolf , 10 bajtów

∞╒g¶áÅ-±├Þ

Wypróbuj online.

Wyjaśnienie:

            # 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! Wiedziałem, że Max pomyślał o zmianie, ale nie wiedziałem, że to zrobił. Dokumenty wciąż mówią o starym.
Kevin Cruijssen

Ach, używam pliku mathgolf.txt jako odniesienia, ponieważ wydaje się być bardziej aktualny
Jo King

@JoKing Tak, powiedział mi także wczoraj o tym pliku. Użyje go od teraz. :)
Kevin Cruijssen


2

C # (interaktywny kompilator Visual C #) , 104 100 bajtów

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

Wypróbuj online!

Wyjaśnienie:

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 bajtów

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 @NaturalNumberGuy 's (pierwsza) odpowiedź C , więc pamiętaj, aby go zagłosować !!
-1 bajt dzięki @ OlivierGrégoire .

Wypróbuj online.

Wyjaśnienie:

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 bajty

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

Wypróbuj online!


Umm .. Stworzyłem już port jego odpowiedzi .. ;) Chociaż twój jest o 1 bajt krótszy, więc coś jest inne. EDYCJA: Ach, mam wynikową liczbę całkowitą poza pętlą, a ty modyfikujesz dane wejściowe wewnątrz pętli, stąd bajt -1 dla ;. :) Czy chcesz, żebym usunął moją odpowiedź? .. Skopiuj wyjaśnienie.
Kevin Cruijssen

@KevinCruijssen Ups, wycofano!
Olivier Grégoire

Przepraszam za to (i dziękuję za bajt -1). Jednak podoba mi się również twoja wersja. Już głosowałem, zanim zobaczyłem odpowiedź NaturalNumberGuy.
Kevin Cruijssen

2

Haskell , 79 74 bajtów (dzięki Laikoni)

72 bajty jako funkcja annonymus (w tym przypadku można usunąć początkowe „f =”).

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

Wypróbuj online!


oryginalny kod:

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)

Wypróbuj online!

Wyjaśnienie:

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
Wewnątrz osłony możesz użyć ,zamiast &&. (last$ ...)może być last(...), a druga osłona 1>0może być użyta do wiązania, aby zapisać nawias, np y<-x+n.
Laikoni

Funkcje anonimowe są na ogół dozwolone, więc inicjały f=nie muszą być liczone. Również nawias zamykający (-1+n)można usunąć.
Laikoni

Dziękuję za sugestie. Nie wiedziałem „,” i wiązania są dozwolone w osłonach funkcji! Ale tak naprawdę nie podoba mi się pomysł anonimowej funkcji jako odpowiedzi. Moim zdaniem nie wydaje się to właściwe.
Sachera

Więcej wskazówek znajdziesz w naszej kolekcji wskazówek dotyczących gry w golfa w Haskell . W Haskell znajduje się także Przewodnik po regułach gry w golfa oraz dedykowany czat: Monady i mężczyźni .
Laikoni

2

VDM-SL , 161 bajtów

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

Pełny program do uruchomienia może wyglądać tak - warto zauważyć, że granice zestawu liczb pierwszych powinny być prawdopodobnie zmienione, jeśli naprawdę chcesz to uruchomić, ponieważ uruchomienie go zajmie dużo czasu dla 1 miliona:

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

Wyjaśnienie:

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


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.