En Yakın Asal Numarayı Gönder


33

Meydan okuma

Bu basit bir tanesidir: 1.000.000'e kadar olan pozitif bir tamsayı verildiğinde en yakın asal sayıyı döndürün.

Sayının kendisi asal ise, o sayıyı döndürmelisiniz; Sağlanan sayıya eşit derecede yakın iki primer varsa, ikisinin altını döndürün.

Giriş, tek bir tamsayı biçimindedir ve çıktı da bir tamsayı biçiminde olmalıdır.

Girişe (fonksiyon, STDIN, vb.) Nasıl girdiğiniz veya çıktısını (fonksiyon, STDOUT, vb.) Çalıştığı sürece nasıl gösterdiğiniz umrumda değil .

Bu kod golf, yani standart kurallar geçerli - en az baytlık program kazanıyor!

Test Kılıfları

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

5
Merhaba ve PPCG'ye hoş geldiniz !. Nedeniyle kalite eksikliği oylama aşağı önlemek için ben size göndermeye önermek Sandbox birinci ve birkaç gün sonra burada yazılan
Luis Felipe De isa Munoz

Bu, bu mücadelede istenen çıktılardan biridir .
Arnauld,


@Bunu gördüm, ama yeni bir soru alabilecek kadar farklı olduklarını düşündüm.
Nathan Dimmer

2
Ayrıca bakınız, OEIS A051697 .
Eric Towers

Yanıtlar:


9

Gaia , 3 bayt

ṅD⌡

Çevrimiçi deneyin!

Büyük girişler için oldukça yavaş, ancak yeterli bellek / zaman verilen işler.

Neden D⌡dolaylı olarak ztekrar zorladığımızdan emin değilim , ancak bunu oldukça kısa bir cevap haline getiriyor!

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

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

Çevrimiçi deneyin!

Yorumlananlar

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

Oktav , 40 bayt

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

Çevrimiçi deneyin!

Bu, nve 2*n( Bertrand – Chebyshev teoremi ) arasında daima bir asalet olduğu gerçeğini kullanır .

Nasıl çalışır

@(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 Dili (Mathematica) , 31 bayt

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

Çevrimiçi deneyin!

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

1000003, 78499. asaldır. NearestListede daha önce beliren değerleri (daha düşük olan) önceliklendirir.


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

5

Brachylog , 7 5 bayt

;I≜-ṗ

Çevrimiçi deneyin!

@DLosc sayesinde 2 bayt kaydedildi.

açıklama

;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 Çoğunlukla aptalım. Teşekkürler.
Mart’ta

Sanırım az önce farklı yönlerden yaklaştık. Baştan beri düşünüyordum , sanırım eşleştirme ve çıkarma işlemlerini düşünüyordum, ancak daha sonra çalışmasını sağlamak için ihtiyacım olduğunu anladım . :)
DLosc

4

Pyth, 10 bayt

haDQfP_TSy

Online Deneyin burada ya bir kerede tüm test durumları doğrulamak burada .

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

Jöle , 9 7 bayt

ḤÆRạÞµḢ

Çevrimiçi deneyin!

Daha büyük girdiler için yavaş, ancak istenen aralık için düzgün çalışır. 2 bayt kaydettiğiniz için @EriktheOutgolfer'a teşekkürler!


Hey, bu akıllıca! İki ile tasarruf _A¥edin (mutlak fark). Oh, ve gerçekten olabilir .
Outgolfer Erik

@EriktheOutgolfer teşekkürler. Elbette kullanmak her zaman işe yaramayacak mı? En yakın n + 2 olabilirken, sadece n + 1 değerine kadar olan primerlerin bulunacağı anlamına gelir.
Nick Kennedy

Hm, bu bir endişe.
Outgolfer Erik

4

Python 2 , 71 bayt

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

Çevrimiçi deneyin!

p(k-1)!2 , p%kprimerler için 1 ve primerler için 0'dır. abs(k-n)Farklı astarları karşılaştırmayı kolaylaştırmak için sonucu elde etmek için geri ekleyerek ksaklar k-nve karşılaştırırız .absnk

İfade k+n-p%k*2*n, k-nasallar (nerede p%k=1) vermek üzere tasarlanmıştır , aksi takdirde k+nmutlak değerde her zaman daha büyük olan ve asgari olanı etkilemez, böylece asal olmayanların geçilmesi için.



3

Düzenli , 43 bayt

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

Çevrimiçi deneyin!

açıklama

Bu parametre ile bir lambda x. Bu, aşağıdaki sıralamayı oluşturarak çalışır:

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

Bu iki dizi ]x, -1, -∞](sol kapalı, sağ açık) ve [x, ∞](her ikisi de açık) birleştiriyor.

Çünkü x = 80, bu gibi görünüyor:

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

Ardından, f↦stüm öğeleri statmin edici olarak seçmek için kullanırız f. Bu durumda, yalnızca asal olanları bırakarak tüm bileşik sayıları filtreleriz. Aynı şekilde x, bu olur:

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

Sonra kullanırız (...)@0 bu dizinin ilk üyesini seçmek için . İkisinin alt kısmının seçilmesi gerektiğinden, x - 1ilk başlayan sırayla eklenir.

Not: Yalnızca biri xve x - 1asal olabilir, bu yüzden eklenmiş dizinin başlaması tamam x - 1. Dizi her iki tarafta da açık olabilmesine rağmen ( [x,-1,-∞]), xsıraya iki kez dahil etmek gerekir. Bu yüzden, "verimlilik" uğruna, sol kapalı versiyonu seçtim (ayrıca Tidy'i göstermeyi sevdiğim için).



3

APL (Dyalog Genişletilmiş) , 20 15 bayt SBCS

Tacit önek işlevi, Galen Ivanov'un J cevabından ilham aldı .

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

Çevrimiçi deneyin!

ɩ argümanla genişletir.

¯2⍭ bunun ilkleri

⊢() Asıl argüman olarak orijinal argümanla, aşağıdaki tacit işlevini uygulayın:

 asallar

 Dizin:

   artan derece (artan sırada olur endeksleri)
   ve
  | büyüklüğü (mutlak değer)
   arasında
  - farklar

 ilkini seç (yani en küçük farkı olanı)


3

Perl 6 , 35 bayt

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

Çevrimiçi deneyin!

Bu, Veitcel'in listesini üretmek için tekniğini kullanır, 0, -1, 2, -3ancak P6'da ($*=-1)*$++bulunan adsız durum değişkenlerini kullanmayı büyük ölçüde basitleştirir (başlangıçta vardı -1 ** $++ * $++, ancak golf oynarken olumsuzlukları kaybeder). Yerleşik bir kontrolcü var ama maalesef otomatik olarak untildöndürülen değeri önlüyor, bu yüzden $_etrafta fazladan takılmak var.


Genelde böyle bir şeye bir dizi operatörü yaklaşımı kullanırdım, ancak bir bayta daha uzun çıkıyor , çok daha kısa bir yöntem buluyor güzel iş
Jo King

@JoKing iyi yakalamak. Çalışan bir çözüm bulduktan sonra çok hızlı golf oynadığımda olan şeyler. Benzer bir şey vardı ama lanet olası [-1] haha ​​eksikliği
user0721090601 0

3

C, 122 121 104 bayt

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

Çağıran işlevi kullanın c()ve sayıyı argüman olarak iletin; en yakın prime geri dönmesi gerekir.

Ignorance uygulaması 1 byte sayesinde büyük bir gelişme kaydetti .

Çevrimiçi deneyin!


Ama c()muhtemelen kısaltabilir, Ayrıca ... iki parametre alır while(1)için for(;;)senin kod çalıştırmasına nasıl alamadım çünkü, denenmemiş (
Cehalet Düzenleme

@EmbodimentofIgnorance Yazmıştım ve hepsini bir online c derleyicide test ettim , c()sadece ilk parametreyi geçerek arayabilirdim . Ve haklısın, for(;;)beni bir bayt kurtarıyor, ilk sırayı almak için sadece 117 tane kaldı :)
Lince Assassino

110 bayt: #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;}}. İşte bir TIO bağlantısı: tio.run/…
Ignorance'ın




2

APL (NARS), 38 karakter, 76 bayt

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

0π asallık testidir, ¯1π önceki asal, 1π sonraki asaldır; Ölçek:

  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 bayt

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

Çevrimiçi deneyin!

/^.?$|^(..+?)\1+$/ asal kontrol etmek zor regexp olduğunu

(-1)**$a*($a++) 0, -1, 2, -3 ... dizilerini oluşturur


2

MathGolf , 10 bayt

∞╒g¶áÅ-±├Þ

Çevrimiçi deneyin.

Açıklama:

            # 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 Teşekkürler! Max'in onu değiştirmeyi düşündüğünü biliyordum ama gerçekten yaptığını bilmiyordum. Doktorlar hala eskisini ifade ediyor.
Kevin Cruijssen

Ah, mathgolf.txt dosyasını referans olarak kullanıyorum, çünkü daha güncel görünüyor
Jo King

@JoKing Evet, dün o dosyayı da anlattı. Bundan sonra kullanacak. :)
Kevin Cruijssen


2

C # (Visual C # Etkileşimli Derleyici) , 104 100 bayt

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

Çevrimiçi deneyin!

Açıklama:

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 bayt

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

@NaturalNumberGuy 'in Limanı (ilk) C cevabı , bu yüzden onu affetmeyi unutma! @ OlivierGrégoire
sayesinde -1 bayt .

Çevrimiçi deneyin.

Açıklama:

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 bayt

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

Çevrimiçi deneyin!


Umm .. Ben zaten cevabının bir portunu yaratmıştım .. ;) Sizinkinin 1 byte daha kısa olmasına rağmen, bir şeyler farklı. EDIT: Ah, döngünün dışında bir sonuç tamsayıya sahibim ve döngü içindeki girişi değiştiriyorsunuz, yani -1 bayt ;. :) Cevabımı silmemi ister misiniz? .. Açıklamayı kopyalamaktan çekinmeyin.
Kevin Cruijssen

@KevinCruijssen Oops, geri alındı!
Olivier Grégoire

Bunun için üzgünüm (ve -1 bayt için teşekkürler). Yine de versiyonunu beğendim. NaturalNumberGuy'un cevabını görmeden önce çoktan oy verildi.
Kevin Cruijssen

2

Haskell , 79 74 bayt (Laikoni sayesinde)

Annonymus işlevi olarak 72 bayt (bu durumda ilk "f =" kaldırılabilir).

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

Çevrimiçi deneyin!


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

Çevrimiçi deneyin!

Açıklama:

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
Bir bekçi içinde ,yerine kullanabilirsiniz &&. (last$ ...)olabilir last(...)ve ikinci muhafız 1>0, örneğin parantez kurtarmak için bağlayıcı bir kullanılabilir y<-x+n.
Laikoni

Adsız işlevlere genellikle izin verilir, bu nedenle ilk f=sayım yapılması gerekmez. Ayrıca parantez içine alınmış parantezler (-1+n)bırakılabilir.
Laikoni

Önerileriniz için teşekkürler. Bilmiyordum "," ve fonksiyon görevlilerinde ciltlemelere izin verilir! Fakat cevap olarak, isimsiz bir fonksiyon fikri hoşuma gitmiyor. Bence doğru gelmiyor.
Sachera

Haskell'de golf için ipuçları koleksiyonumuzda daha fazla ipucu bulabilirsiniz . Ayrıca Haskell'de Golf Kuralları Kılavuzu ve özel sohbet odası: Monads and Men .
Laikoni

2

VDM-SL , 161 bayt

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

Çalıştırmak için tam bir program bu şekilde görünebilir - gerçekten kullanmak istiyorsanız, kullanılan primer setinin sınırlarının muhtemelen değiştirilmesi gerektiğine dikkat çekmek önemlidir, çünkü 1 milyona kadar çalıştırmak uzun zaman alacaktır:

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

Açıklama:

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


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.