Bir sonraki asal sayıyı bulan program


15

tanıtım:


Zaman akışını eğlenmek için yaptığınız, zaman makinesi olduğu ortaya çıkan bir cihazla yanlışlıkla bozdunuz. Sonuç olarak, uzak geleceğe doğru itildiniz. Bilgi işlem, işlem gücü ve bilgisayarların büyük miktarda, kesin olarak sonsuz miktarda geliştiğini fark ettiniz . Böylece kendinizi sonsuz bellek ve işlem gücüne sahip bir bilgisayar alırsınız. Sonsuz belleğe ve sonsuz işlem gücüne sahip olabileceği hakkında hiçbir fikriniz yok, ancak sadece kabul edip günümüze dönüyorsunuz.

Meydan okuma:


Şu anda en büyük primi keşfeden kişiye 2^74,207,281 − 1100.000 dolar ödendiğini duydunuz . Bilgisayar için harcadığınız parayı geri almak istediğinizden, bir sonraki başbakanı bulan bir program yapmaya karar verdiniz. Bir sayının girdisini alan ve bir sonraki asal sayıyı bruteforcing veya başka bir yöntemle bulan bir numara oluşturursunuz.

Açıklamalar: Sonsuz hafıza ve işleme gücüne sahip varsayımsal bir makineniz var. Programınız ZORUNLU OLMAMALIDIR (örn: C # 's int's from -2,147,483,648to saklayabilir 2,147,483,647), iyi program saklamak ve herhangi bir boyutta herhangi bir sayı ile çalışabilmelidir. Sonsuz kaynaklarınız var, bu yüzden izin verdiyseniz belleğinizin bitip bitmeyeceğini umursamalısınız.

Örnek G / Ç:
Girdi: Şu anda keşfedilen en büyük başbakan 22,338,618 basamaklı.
Çıktı: Tam olarak bir sonraki asal

Açıkçası, fiziksel bir makinede hesaplamak tonlarca zaman alacağından bunun işe yaradığını kanıtlamanız gerekmez. Ancak programınızı sonsuz işlem gücü / belleğe sahip varsayımsal bir makineye taşıdıysanız, anında hesaplaması gerekir.


Bir sonraki asalı bulmak ve bir sayının asal olup olmadığını kontrol etmek, tamamen farklı iki şeydir


1
Özellikle bir sonraki asal olmalı mı? Büyük asallar için çok sayıda birincil arama algoritması sadece belirli sayı türlerini arar ve bu nedenle bazen asalları
kaçırır

10
Bazı ciddi test senaryoları eklemeniz gerektiğini düşünüyorum.
FlipTack

3
" Programınız sınırlı OLMAMALIDIR " ancak örneğe dayanarak, var olan her dilin hafızayı ele almak için sonlu bir tür kullanmaktan başka bir nedeni yoksa sınırlı sayıldığından şüpheleniyorum.
Peter Taylor


2
@ mbomb007 neden? Yerleşik olanlar dışındaki tüm cevaplar sadece ekstra bir sargı ekledi.
Post Rock Garf Hunter

Yanıtlar:



8

Python 3 , 45 bayt

f=lambda n,k=1,m=1:m%k*k>n or-~f(n,k+1,m*k*k)

Çevrimiçi deneyin!


3
Bunun Wilson'ın kılık değiştirmiş Teoremi olduğuna inanıyorum. k, nihai sonuca eşittir, miçerir (k-1)!^2. Beri (k-1)! = -1 mod k sadece k asal olduğunda geçerlidir (k-1)! (K-1)! = 1 mod k, bu da k ile çarpıldığında k'nin kendisi olacaktır. (K-1) 'in tek istisnasından kurtulmak için kareyi hesaplarsınız! = 0 k = 4 için meydana gelen kompozit k için k mod.
orlp

Evet doğru.
Dennis

Bu atar RecursionError: maximum recursion depth exceeded in comparisoniçinf(1000)
ovs

5
@ovs Soru, sonsuz hafızamız olduğunu söylüyor. Bu nedenle, sonsuz yüksek bir özyineleme derinliği sınırı üstlenebilir ve böylece endişelenmeyiz RecursionError.
FlipTack

6

Python 2, 78 77 76 74 bayt

def f(n):
 while 1:
    n+=1
    if[i for i in range(1,n)if n%i<1]==[1]:return n

@KritixiLithos sayesinde -1 bayt @FlipTack sayesinde -1 bayt @ElPedro
sayesinde
-2 bayt


n%i<1daha kısadırn%i==0
Kritixi Lithos

Bundan sonra boşluklara ihtiyacınız yok if.
FlipTack

Sanırım demek istiyorsun<1
Jonathan Allan

Sanırım ikinci seviye girintileri için 2 boşluk yerine bir sekme kullanabilirsiniz, ancak şu anda test yapamıyorum.
ElPedro

1
@ElPedro haklı. Önündeki n+=1ve önündeki 2 boşluğu ifsekmelere dönüştürebilir ve 2 bayt kaydedebilirsiniz



4

Bash + coreutils, 52 bayt

for((n=$1,n++;`factor $n|wc -w`-2;n++)){ :;};echo $n

Çevrimiçi deneyin!

Bash ve factor belgeleri, işleyebilecekleri maksimum tamsayı değerini belirtmez (uygulamada her uygulamanın bir maksimum tamsayı değeri olmasına rağmen). Muhtemelen, geleceğin GNU'sunda sonsuz büyük makinelerinizde, bash ve faktör sınırsız boyut tam sayılarına sahip olacaktır.


Aslında dokümanlar, gnu mp olmadan oluşturulursa yalnızca tek duyarlıklı desteklendiğini belirten faktörleri belirtir.
Dani_l

1
@Dani_l Peki, bash için man girişi sadece şöyle diyor: "Değerlendirme, taşma kontrolü olmaksızın sabit genişlikli tamsayılarda yapılır, ancak 0'a bölünme bir hata olarak işaretlenir ve işaretlenir." Genişliği belirtmez. (Hatırladığım gibi, bash'ın makinelerimdeki stok uygulamaları 64 bit işaretli tamsayıları kullanıyor, ancak şu anda kontrol edemiyorum.) Faktör için, kesinlikle güncellenecek: OP'nin sonsuz kaynaklara sahip gelecekteki bilgisayarlarında faktör olacak Sınırsız hassasiyet elde etmek için gnu_up ile derlenmiştir :).
Mitchell Spector

3

Maxima, 10 bayt

next_prime

Bir işlev, argümanından daha büyük olan en küçük prime değerini döndürür.



3

Sympy ile Python, 28 bayt

import sympy
sympy.nextprime

sympy.nextprimeteneke üzerinde söylediklerini yapan bir işlevdir. Tüm şamandıralar için çalışır.

repl.it


Python, 66 59 bayt

Lynn sayesinde -4 bayt (kullanım -~)
FlipTack sayesinde -3 bayt (kullanın andve bir koşula orgeçişine izin verin .)...==1...-1

f=lambda n:sum(-~n%-~i<1for i in range(n))-1and f(n+1)or-~n

repl.it

Bir bölü nbulunana kadar sayılan özyinelemeli işlev, bölene kadar yalnızca bir sayının var n-1olduğunu sınayarak (yani 1). Tüm tamsayılar için çalışır, şamandıralar için bir hata oluşturur.

2.7.8 ve 3.5.2 üzerinde çalışır, 3.3.3 üzerinde çalışmaz ( ==1ve arasındaki boşluk olmaması nedeniyle sözdizimi hatası else)


(n+1)%(i+1)olduğunu -~n%-~i, sanırım.
Lynn

Bu, teşekkürler ... Wilson teoremini kullanarak daha kısa bir tane yapmaya çalışıyordum.
Jonathan Allan

Kısa devre and/ orçalışma gibi f=lambda n:sum(-~n%-~i<1for i in range(n))==1and-~n or f(n+1)mi?
FlipTack

Aslında, bu ^ golf olabilirf=lambda n:sum(-~n%-~i<1for i in range(n))-1and f(n+1)or-~n
FlipTack

@FlipTack Başlangıçta onlardan kaçındım, böylece sıfırdan geçebilirdi, ama işe yarayacak - bu üç baytlık bir tasarruf!
Jonathan Allan

2

Python, 114 83 bayt

def g(b):
 while 1:
  b+=1
  for i in range(2,b):
   if b%i<1:break
  else:return b

Yerleşik olmadan, varsa.

-30 boşlukları kaldırarak ve -1 b%i==0değerini değiştirerekb%i<1


3
Eğer koyarsanız bir sonraki başbakan 1
bulamaz

Şimdi b> 2
sagiksp

Sadece kendi kurallarınızı oluşturamazsınız ... meydan okuma şartnamesine uymanız gerekir. Hiçbir yerde girdinin sınırlarını üstlenemeyeceğiniz söylenemez.
FlipTack

Bu varsayımda bile, bu bile tüm değerli girdiler için başarısız olur.
FlipTack

Ben bir aptalım, yanlış okudum. Onu düzeltti. @FlipTack
sagiksp

2

Perl 6 , 25 bayt

{first *.is-prime,$_^..*}

Nasıl çalışır

{                       }  # A lambda.
                  $_ ..*   # Range from the lambda argument to infinity,
                    ^      # not including the start point.
 first           ,         # Iterate the range and return the first number which
       *.is-prime          # is prime.

Perl 6 , 32 bayt

{first {all $_ X%2..^$_},$_^..*}

Verimsiz özel öncelik testi ile.

Nasıl çalışır

Dış yapı yukarıdakiyle aynıdır, ancak first(verilen bir sayının asal olup olmadığına karar vermek için) verilen yüklem şimdi:

{               }  # A lambda.
     $_            # Lambda argument (number to be tested).
          2..^$_   # Range from 2 to the argument, excluding the end-point.
        X          # Cartesian product of the two,
         %         # with the modulo operator applied to each pair.
 all               # Return True if all the modulo results are truthy (i.e. non-0).

Perl 5 ile daha kısa bir şey almayı umuyordum ama yerleşik bir dövmek zor .is-prime;)
Zaid

2

Pyke, 8 7 bayt

~p#Q>)h

Burada deneyin!

4 bayt, rakipsiz

(Tercüme, yayınlandığından beri güncellendi)

~p<h

Burada deneyin!

~p   -   primes_iterator()
  <  -  filter(^, input() < i)
   h - ^[0]

Neden ikinci rakipsiz? Yeterince anlamıyorum.
theonlygusti

@theonlygusti: Genellikle, burada olmayan bir gönderimi işaretlemenin tek meşru nedeni (hiç göndermemenin aksine), bir hatayı düzeltmeniz veya programın yazıldığı dilde bir özellik eklemeniz ve bu size meydan okumayla yardımcı olmanızdır. . (Daha açık olmak için "dil postdates meydan okuma" olarak yazma eğilimindedir.)

@theonlygusti açıkladı
Blue


1

05AB1E , 16 13 bayt (Emigna @ -3 bayt)

2•7£?ÿ•o[>Dp#

Çevrimiçi deneyin!

2•7£?ÿ•o        # Push current largest prime.
        [   #    # Until true..
         >Dp    # Increment by 1, store, check primality.
                # After infinite loop, implicitly return next prime.

Çalışmaz mıydı [>Dp#?
Emigna

Programın giriş olarak bir sonraki asalı alması ve bir sonraki asaltı çıkarması gerektiğinden 8 bayt daha kesebilirsiniz.
Emigna

@Emigna o zaman bu soru yineleniyor.
Sihirli Ahtapot Urn

Muhtemelen evet.
Emigna

1

Perl, 30 bayt (için 29 +1 -p):

(1x++$_)=~/^(11+?)\1+$/&&redo

kullanım

Dönüş düğmesine bastıktan sonra numarayı girin (aşağıdaki örnekte 12345 girişi, çıkış 12347):

$ perl -pe '(1x++$_)=~/^(11+?)\1+$/&&redo'
12345
12347

Nasıl çalışır

  • Bir dizi tanımlayın 1uzunluğa sahiptir s' ++$_,$_ başlangıçta giriş değeridir
  • Normal ifade, 1s dizesinin asal olmayan uzunluk olup olmadığını kontrol eder ( burada açıklanmıştır) ).
  • Dize uzunluğu asal değilse, denetim bir sonraki tamsayı için yeniden değerlendirilir (++$_ )
  • Dize uzunluğu asalsa, örtülü whiledöngü çıkar ve-p baskılar değeri$_
  • Not: "1"uzunluk 1'in kenar kasasını işlemeye gerek yoktur, çünkü 1şartname uyarınca asla daha küçük değerler için kullanılmaz .

1

Java 7, 373 343 334 303 268 bayt

import java.math.*;class M{public static void main(String[]a){BigInteger n,i,o,r=new BigInteger(a[0]);for(r=r.add(o=r.ONE);;r=r.add(o)){for(n=r,i=o.add(o);i.compareTo(n)<0;n=n.mod(i).compareTo(o)<0?r.ZERO:n,i=i.add(o));if(n.compareTo(o)>0)break;}System.out.print(r);}}

-75 bayt teşekkürler @Poke

Ungolfed:

import java.math.*;
class M{
  public static void main(String[] a){
    BigInteger n,
               i,
               o,
               r = new BigInteger(a[0]);
    for(r = r.add(o = r.ONE); ; r = r.add(o)){
      for(n = r, i = o.add(o); i.compareTo(n) < 0; n = n.mod(i).compareTo(o)< 0
                                                        ? r.ZERO
                                                        : n,
                                                   i = i.add(o));
      if(n.compareTo(o) > 0){
        break;
      }
    }
    System.out.print(r);
  }
}

Burada deneyin.

Bazı örnek giriş / çıkışlar:

7 -> 11
1609 -> 1613
104723 -> 104729

@Poke staticAlan ve yöntem ekleyerek p, ancak yöntem cve pparametresini kaldırarak başka bir 31 bayt golf .
Kevin Cruijssen

0

QBIC , 34 bayt

:{a=a+1[2,a/2|~a%b=0|b=a]]~a<b|_Xa

Bu QBIC öncelik testine dayanmaktadır . Açıklama:

:{a=a+1    Read 'a' from the command line, start an infinite loop 
           and at the start of each iteration increment 'a'
[2,a/2|    FOR b = 2, b <= a/2, b++
~a%b=0|    IF b cleanly divides a, we're no prime
b=a]]      so, break out of the FOR loop ( ]] = End if, NEXT )
~a<b|      If the FOR loop completed without breaking
_Xa        then quit, printing the currently tested (prime) number
           The second IF and the DO-loop are implicitly closed by QBIC.

0

JavaScript (ES7), 61 bayt

a=>{for(;a++;){for(c=0,b=2;b<a;b++)a%b||c++;if(!c)return a;}}

kullanım

f=a=>{for(;a++;){for(c=0,b=2;b<a;b++)a%b||c++;if(!c)return a;}}
f(2)

Çıktı

3

Güzel, ama JavaScript'in kendisi (bilgisayar değil) sadece 2 ^ 53'ten sonra hassasiyetini kaybedeceğinden bunun işe yarayacağını sanmıyorum.
ETHproductions

Haklısınız, ancak sayıyı bir dizideki 32 bit'lik bölümlere ayırsak bile, bu sınırın önlenebileceğini düşünmüyorum, çünkü sonunda sayının bir bütün olarak işlenmesi gerekiyor. Bunu nasıl çözeceğiniz hakkında bir fikriniz varsa, lütfen bana bildirin.
Luke

1
Keyfi hassasiyetli matematik için JS kütüphaneleri var - bir noktada bir tane bile inşa ettim - bu yüzden eminim. Bilgisayarımda bir dahaki sefere gideceğim
ETHproductions

Biraz googling yaptım ve ilginç görünüyor. Ben de bir şansım olacak.
Luke

0

MATL, 3 bayt

_Yq 

Fonksiyon Yqörtük girişi kapmak böylece girdi negatifse o (boşa, girişin mutlak değerinin sonraki asal döndürür _) ve kullanarak bir sonraki asal bulmak Yq.

Çevrimiçi deneyin!


0

Haskell, 42 46 43 bayt

f n=[i|i<-[n..],all((>0).rem i)[2..i-1]]!!1

kaba kuvvet için olağan kod.

Tabii ki bu sonraki en küçük asal sayıyı bulur n. En büyük asal yok.

N > 0 için çalışır .

edit: Varsayım nasal. @Laikoni'nin yorumlarındaki tavsiyesi sayesinde .


Sen değiştirerek byte kaydedebilirsiniz head[...]ile [...]!!0. Ancak bence bunun nasal olduğunu varsayabiliriz, [n..]bunun yerine [n+1..]ikinci öğeyi yerine kullanabilir ve sonra kullanabilirsiniz [...]!!1.
Laikoni

0

SimpleTemplate, 132 bayt

Algoritma korkunç, çünkü bir sayının asal olup olmadığını kontrol etmek için kendi kodumu yapmak zorundayım.
Korkunç olduğunu kanıtladı, ama işe yarıyor.

{@setY argv.0}{@setX 1}{@whileX}{@setX}{@set+T Y,-1}{@for_ from2 toT}{@ifY is multiple_}{@incX}{@/}{@/}{@ifX}{@incY}{@/}{@/}{@echoY}

Sayıyı çıktı olarak ilk bağımsız değişken olarak alır.


Ungolfed:

{@set number argv.0}
{@set remainder 1}
{@while remainder}
    {@set remainder 0}
    {@set+ tmp number, -1}
    {@for divisor from 2 to tmp}
        {@if number is multiple divisor}
            {@inc by 1 remainder}
        {@/}
    {@/}
    {@if remainder}
        {@inc by 1 number}
    {@/}
{@/}
{@echo number}

En son nasıl kaldırılacağına dair ipucu var @ifmı?


0

Lua, 876 Bayt

function I(a)a.s=a.s:gsub("(%d)(9*)$",function(n,k)return tostring(tonumber(n)+1)..("0"):rep(#k)end)end function D(a)a.s=a.s:gsub("(%d)(0*)$",function(n,k)return tostring(tonumber(n)-1)..("9"):rep(#k)end):gsub("^0+(%d)","%1")end function m(a,b)local A=K(a)local B=K(b)while V(0,B)do D(A)D(B)end return A end function M(a,b)local A=K(a)local B=K(b)while V(m(B,1),A)do A=m(A,B)end return A end function l(n)return#n.s end function p(a)local A=K(a)local i=K(2)while V(i,A)do if V(M(A,i),1)then return false end I(i)end return true end function V(b,a)A=K(a)B=K(b)if l(A)>l(B)then return true end if l(B)>l(A)then return false end for i=1,l(A)do c=A.s:sub(i,i)j=B.s:sub(i,i)if c>j then return true elseif c<j then return false end end return false end function K(n)if(type(n)=='table')then return{s=n.s}end return{s=tostring(n)}end P=K(io.read("*n"))repeat I(P)until p(P)print(P.s)

Lua, diğer bazı dillerden farklı olarak, Maksimum Tamsayı Boyutuna sahiptir. Bir sayı 2 32'den büyük olduğunda , işler düzgün çalışmayı durdurur ve Lua kesin değerler yerine tahmin yapmaya çalışır.

Bu nedenle, sayıları depolamak için yeni bir yöntem uygulamak zorunda kaldım, özellikle de bunları Base10 dizeleri olarak sakladım, çünkü Lua'nın Dizeler'de belleğin boyutu dışında bir boyut sınırı yok.

Bu cevabın, sorunun Ruhu için çok daha fazla olduğunu hissediyorum, çünkü bir keyfi testin yanı sıra keyfi hassasiyet tamsayıları uygulamak zorunda.

Açıklaması

-- String Math
_num = {}

_num.__index = _num

-- Increase a by one.
-- This works by grabbing ([0-9])999...$ from the string.
-- Then, increases the first digit in that match, and changes all the nines to zero.
-- "13", only the "3" is matched, and it increases to 1.
-- "19", firstly the 1 is turned to a 2, and then the 9 is changed to a 0.
-- "9" however, the 9 is the last digit matched, so it changes to "10"
function _num.inc(a)
    a.str = a.str:gsub("(%d)(9*)$",function(num,nines)
            return tostring(tonumber(num)+1)..("0"):rep(#nines)
        end)
end


-- Decrease a by one
-- Much like inc, however, uses ([0-9])0...$ instead.
-- Decrements ([0-9]) by one and sets 0... to 9...
-- "13" only the "3" is matched, and it decreases by one.
-- "10", the "1" is matched by the ([0-9]), and the 0 is matched by the 0..., which gives 09, which is clipped to 9.
function _num.dec(a)
    a.str = a.str:gsub("(%d)(0*)$",function(num,zeros)
        return tostring(tonumber(num)-1)..("9"):rep(#zeros)
    end)         :gsub("^0+(%d)","%1")
end

-- Adds a and b
-- Makes A and B, so that the original values aren't modified.
-- B is then decremented until it hits 0, and A is incremented.
-- A is then returned.
function _num.__add(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while B > 0 do
        A:inc()
        B:dec()
    end
    return A
end

-- Subs b from a
-- Works just like Addition, yet Dec's A instead of Incs.
function _num.__sub(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while B > 0 do
        A:dec()
        B:dec()
    end
    return A
end

-- A % B
-- Makes A and B from a and b
-- Constantly subtracts B from A until A is less than B
function _num.__mod(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while A >= B do
        A = A - B
    end
    return A
end

-- #a
-- Useful for golfiness
function _num.__len(n)
    return #n.str
end

-- Primacy Testing
-- Generates A from a and i from 2.
-- Whilst i is less than A, i is incremented by one, and if A % i == 0, then it's not a prime, and we return false.
-- Once that finishes, we return true.
function _num.isprime(a)
    local A = str_num(a)
    local i = str_num(2)
    while i < A do
        if A%i < 1 then
            return false
        end
        i:inc()
    end
    return true
end

-- b < a
-- A and B are generated from a and b
-- Fristly, if the length of A and B aren't equal, then that result is output.
-- Otherwise, each character is searched from left to right, the moment they are unequal, the difference is output.
-- If all the characters match, then it's equal. Return false.
function _num.__lt(b,a)
    A=str_num(a)
    B=str_num(b)
    if #A > #B then
        return true
    end
    if #B > #A then
        return false
    end
    for i=1, #A.str do
        As = A.str:sub(i,i)
        Bs = B.str:sub(i,i)
        if As > Bs then
            return true
        elseif As < Bs then
            return false
        end
    end
    return false
end


-- b <= a
-- Same as b < a, but returns true on equality.
function _num.__le(b,a)
    A=str_num(a)
    B=str_num(b)
    if #A > #B then
        return true
    end
    if #B > #A then
        return false
    end
    for i=1, #A.str do
        As = A.str:sub(i,i)
        Bs = B.str:sub(i,i)
        if As > Bs then
            return true
        elseif As < Bs then
            return false
        end
    end
    return true
end

-- Just straight up returns it's string component. Endlessly faster than the int equivalent, mostly because it never is anything _but_ the string form.
function _num.__tostring(a)
    return a.str
end

-- Just set up the metatable...
function str_num(n)
    if(type(n)=='table')then
        return setmetatable({str = n.str}, _num)
    end
    return setmetatable({str = tostring(n)}, _num)
end

-- Generate a new str_num from STDIN
Prime = str_num(io.read("*n"))

-- This is handy, because it will call Prime:inc() atleast once, and stop at the next prime number it finds.
-- Basically, if it weren't for all that overhead of making the math possible, that's all this would be.
repeat
    Prime:inc()
until Prime:isprime()
print(Prime)

Yukarıdakiler Metatables kullanıyor olsa da, gerçek cevap gibi normal işlevler yerine, daha küçük çalıştı.


0

Yakut, 28 + 6 = 34 bayt

-rprimeBayrağı kullanır .

f=->i{i+=1;i.prime??i :f[i]}

31 + 6 = 37 bayt için özyinelemesiz sürüm:

->i{i+=1;i+=1 while i.prime?;i}

0

Python + primefac , 34 32 bayt

Kullanmak kadar kısa değil sympy(başka bir cevap zaten bunu kullanıyor), ama yine de oldukça kısa ve çok daha hızlı.

import primefac as p
p.nextprime

Çevrimiçi deneyin

2**2000Birkaç saniye içinde tamamlamaların girişi .


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.