is_gaussian_prime (z),?


23

Görev

a,bGauss tamsayısını z = a+ib(karmaşık sayı) temsil eden iki tamsayıyı kabul eden bir işlev yazın . Program a+ibbir Gauss Başbakanı olup olmamasına bağlı olarak doğru veya yanlış döndürmelidir .

Tanım:

a + bi yalnızca aşağıdaki koşullardan birini karşılıyorsa, Gauss'un bir başlangıcıdır:

  • ave bhem sıfırdan farklı hem a^2 + b^2de asal
  • asıfır, |b|asal ve|b| = 3 (mod 4)
  • bsıfır, |a|asal ve|a| = 3 (mod 4)

ayrıntılar

Yalnızca bir işlev yazmalısınız. Dilinizde işlevler yoksa, tamsayıların iki değişkente saklandığını varsayabilir ve sonucu yazdırabilir veya bir dosyaya yazabilirsiniz.

Dilinizin yerleşik işlevlerini isprimeveya prime_listveya nthprimeveya gibi kullanamazsınız factor. En düşük bayt sayısı kazanır. Program 32 bit (imzalı) bir tam sayı a,bolduğu yerde çalışmalı a^2+b^2ve 30 saniyeden fazla olmamalıdır.

Ana liste

Noktalar Gauss düzlemindeki asal sayıları temsil eder ( x= gerçek, y= hayali eksen):

enter image description here

Bazı büyük asal sayılar:

(9940, 43833)
(4190, 42741)
(9557, 41412)
(1437, 44090)

2
Faktorizasyon fonksiyonlarını kullanmamıza izin veriliyor mu ( factorBash mfve mFCJam, ...)

Oh hayır, bu çarpanlara ayırma yöntemlerinin var olduğunu unuttum, hayır lütfen değil =) Ve 32bit sınırı bir ^ 2 + b ^ 2 için geçerlidir, aksi takdirde mantıklı olmaz. Girdileriniz için teşekkür ederiz! Soruyu güncelledim.
flawr

2
Gönderiye Gaussian primes tanımını ekledim. Nasıl yaptığımdan hoşlanmıyorsanız, geri almaktan çekinmeyin, ancak tanımı bir yere dahil etmenizi kesinlikle tavsiye ederim.
undergroundmonorail

Bu güzel, aslında insanların yaratıcı olması için ilkelliği nasıl belirleyeceğimi doğrudan belirtmek istemedim =)
flawr

1 1073741857 bana bir Gauss üssü gibi görünmüyor çünkü 1 ^ 2 + 1073741857 ^ 2 bir çift sayıdır ...
RosLuP

Yanıtlar:


4

Haskell - 77/ 108 107 Chars

kullanımı: her iki çözümde de, a + bi'nin bir gauss asalı olup olmadığı konusunda% b yazmak döndürülür.

yönettiğim en düşük, ancak yaratıcılık veya performans yok (77 karakter)

p n=all(\x->rem n x>0)[2..n-1]
a%0=rem a 4==3&&p(abs a)
0%a=a%0
a%b=p$a^2+b^2

bu çözüm sadece asal olup olmadığını kontrol etmek için n altındaki tüm sayılara güç sağlar.

ungolfed sürümü:

isprime = all (\x -> rem n x != 0) [2..n-1] -- none of the numbers between 2 and n-1 divide n.
isGaussianPrime a 0 = rem a 4==3 && isprime (abs a)
isGaussianPrime 0 a = isGaussianPrime a 0   -- the definition is symmetric
isGaussianPrime a b = isprime (a^2 + b^2)

bir sonraki çözümün ekstra bir özelliği var - notlandırma. bir n tamsayısının asal olup olmadığını kontrol ettikten sonra, n'ye eşit veya n'den küçük olan tüm sayıların "öncelikliliğini" yeniden hesaplamanıza gerek yoktur, çünkü bilgisayarda saklanacaktır.

(107 karakter. Yorumlar netlik içindir)

s(p:x)=p:s[n|n<-x,rem n p>0] --the sieve function
l=s[2..]                     --infinite list of primes
p n=n==filter(>=n)l!!0       --check whether n is in the list of primes
a%0=rem a 4==3&&p(abs a)
0%a=a%0
a%b=p$a*a+b*b

ungolfed sürümü:

primes = sieve [2..] where
    sieve (p:xs) = p:filter (\n -> rem n p /= 0) xs
isprime n = n == head (filter (>=n) primes) -- checks if the first prime >= n is equal to n. if it is, n is prime.
isGaussianPrime a 0 = rem a 4==3 && isprime (abs a)
isGaussianPrime 0 a = isGaussianPrime a 0   -- the definition is symmetric
isGaussianPrime a b = isprime (a^2 + b^2)

bu, tüm primerlerin sonsuz bir listesini hesaplamak için Eratosthenes elekini kullanır (koddaki liste için l olarak adlandırılır). (sonsuz listeler, iyi bilinen bir haskell numarasıdır).

Sonsuz bir listeye sahip olmak nasıl mümkün olabilir? programın başında, liste değerlendirilmemiştir ve listeler öğelerini depolamak yerine, bilgisayar bunları hesaplamanın yolunu saklar. ancak program listeye eriştikçe, isteğe göre kendisini kısmen değerlendirir. bu nedenle, program listedeki dördüncü öğeyi isteyecek olsaydı, bilgisayar daha önce değerlendirilmemiş olan tüm ilkleri hesaplar, saklar ve geri kalanı değerlendirilmeden kalır, bir kez hesaplamanın yolu olarak saklanır gerekli.

bunların hepsinin Haskell dilinin tembel doğası tarafından özgürce verildiğini, bunların hiçbirinin kodun kendisinden belirgin olmadığını unutmayın.

programın her iki sürümü de aşırı yüklenmiştir, böylece keyfi boyuttaki verileri işleyebilirler.



yeni satırları saydım, değil mi?
gururlu haskeller

74 normal karakter ve 3 yeni satır
sayıyorum

haklısın, bazı nedenlerden dolayı notepad ++ yeni satırlardan önce karakter ekliyor gibi görünüyor. Teşekkürler!
gururlu haskeller

Bu yüzden yüce kullanıyorum;) yardımcı olmaktan mutluluk duyuyorum!
killmous

9

C, 149118 karakter

Düzenlenmiş sürüm (118 karakter):

int G(int a,int b){a=abs(a);b=abs(b);int n=a*b?a*a+b*b:a+b,
d=2;for(;n/d/d&&n%d;d++);return n/d/d|n<2?0:(a+b&3)>2|a*b;}

Bu tek bir işlevdir:

  • A + bi bir Gauss asalıysa G ( a , b ) sıfırdan farklı (true) , aksi halde sıfır (false) döndürür.

Tamsayı öncelik testini n/d/d|n<2, dönüş değeri hesaplamasında gizlenen bir ifadeye katlar . Bu golfed kod, ayrıca kullanan a*bbir için yedek olarak a&&b(diğer bir deyişle a!=0 && b!=0) ve operatör öncelik ve tamsayı bölümü kapsayan diğer numaralar. Örneğin , taşmanın güvenli bir söylem yöntemi olan ya da özünde , n/d/ddaha kısa bir söylem n/d/d>=1biçimidir .n>=d*dd*d<=nd<=sqrt(n)


Orijinal versiyon (149 karakter):

int Q(int n){int d=2;for(;n/d/d&&n%d;d++);return n/d/d||n<2;}
int G(int a,int b){a=abs(a);b=abs(b);return!((a|b%4<3|Q(b))*(b|a%4<3|Q(a))*Q(a*a+b*b));}

Fonksiyonlar:

  • S ( n ) 0 (false) döndürür , n asal veya 1 (doğru) ise n prime olmayan bir. G ( a , b ) için bir yardımcı işlevdir .

  • G ( a ,A + bi bir Gauss asalıysa b ) 1 (doğru) , aksi takdirde 0 (yanlış) döndürür.

İçin örnek çıktı (% 200 büyütülmüş) | a |, | b | ≤ 128:

Sample128


2
Resim için +1! Ayrıca sadece ilk çeyrekte aynı boyutta bir tane yapabilir misiniz (çünkü simetri), burada gerçekten harika görünüyor =)
flawr

D = 2; (; n / d / d && n% d; d ++) için değiştirerek birkaç karakter kaydedebilirsiniz; ile (d = 2; n / d / d && n% d ++;);
Simyacı

@Alchymist - Bu gerçekten karakterleri kurtarır, ancak yanlış sonuçlar verir. d++Durumun bir parçası olarak gerçekleşmemesi önemlidir , aksi takdirde aşağıdaki mantığı bozar. Ayrıca, döngünün d=2içinin hareket ettirilmesi forkarakter sayısını azaltmaktan ziyade karakter sayısını arttırır, çünkü dyine intde fordöngünün öncesinde bildirilmesi gerekir . Bir şey mi kaçırıyorum?
Todd Lehman

Çok doğru. Buna kodlama ortamından bakmanın ve yeterince yakın olmanın tehlikeleri. Artış, olduğu yerde kalmalı ve başlatma yalnızca orijinal çözümünüze yardımcı olur. Eğer int belirtmeden fonksiyonun dışında n & d bildirirseniz ve for döngüsünde onları başlatırsanız belirgin tasarruflar vardır, ancak gereksinimlerin sıkı bir yorumu olan işlevi kendi kendine kapsadığınızı varsayıyorum.
Simyacı

1
Buradaki ana test döngüsü bazı muhteşem golf! Ancak, dönüş türü ve bağımsız değişkenler için int türü belirteçlerini bırakarak | a | + | b | ve return ifadesini optimize etmek için: G(a,b){int s=abs(a)+abs(b),n=a*b?a*a+b*b:s,d=2;for(;n/d/d&&n%d;d++);return n>1>n/d/d&&s%4/3|a*b;}sadece 97 karakter çıkıyor.
feersum

4

APL (Dyalog Unicode) , 36 47 48 49 47 43 28 bayt

İki tamsayıdan oluşan bir dizi alır a bve ifadenin Boolean değerini döndürür a+bi is a Gaussian integer.

Düzenleme: +11 bayt çünkü bir Gauss Başbakan tanımını yanlış anladım. Cevabı tekrar düzeltmekten +1 byte. Üçüncü bir hata düzeltmesinden +1 bayt. Dfn yerine tren kullanılması nedeniyle -2 bayt. Bir koruma kullanarak ngn sayesinde -4 baytcondition: if_true ⋄ if_false yerineif_true⊣⍣condition⊢if_false . Başka bir durumda tam tren olarak yazmanın tamamen farklı bir yolunu bulması nedeniyle ngn sayesinde -15 bayt.

{2=≢∪⍵∨⍳⍵}|+.×0∘∊⊃|{⍺⍵}3=4||

Çevrimiçi deneyin!

açıklama

{2=≢∪⍵∨⍳⍵}|+.×0∘∊⊃|{⍺⍵}3=4||

                           |   abs(a), abs(b) or abs(list)
                       3=4|    Check if a and b are congruent to 3 (mod 4)
                  |{⍺⍵}        Combine with (abs(a), abs(b))
              0∘∊⊃             Pick out the original abs(list) if both are non-zero
                               Else pick out (if 3 mod 4)
          |+.×                 Dot product with abs(list) returns any of
                               - All zeroes if neither check passed
                               - The zero and the number that IS 3 mod 4
                               - a^2 + b^2
{2=≢∪⍵∨⍳⍵}                     Check if any of the above are prime, and return

3

Haskell - 121 karakter (yeni satır dahil)

İşte herhangi bir harici modül kullanmayan ve alabildiğim kadar golf oynayan nispeten basit bir Haskell çözümü.

a%1=[]
a%n|n`mod`a<1=a:2%(n`div`a)|1>0=(a+1)%n
0#b=2%d==[d]&&d`mod`4==3where d=abs(b)
a#0=0#a
a#b=2%c==[c]where c=a^2+b^2

Olarak çağırın ghci ./gprimes.hsve ardından etkileşimli kabukta kullanabilirsiniz. Not: negatif sayılar titizdir ve parantez içine alınmalıdır. yani

*Main>1#1
True
*Main>(-3)#0
True
*Main>2#2
False

3

Python - 121 120 karakter

def p(x,s=2):
 while s*s<=abs(x):yield x%s;s+=1
f=lambda a,b:(all(p(a*a+b*b))if b else f(b,a))if a else(b%4>2)&all(p(b))

pabs(x)2'den abs(x)**.5(ki sqrt(abs(x))) tüm sayıları yineleyerek asal olup olmadığını kontrol eder . Bunu x % sher biri için üreterek yapar s. alldaha sonra elde edilen tüm değerlerin sıfır olup olmadığını kontrol eder ve bir bölenle karşılaştığında değer üretmeyi durdurur x. In f, @killmous 'Haskell cevabından esinlenen f(b,a)davayı değiştirir .b==0


-1 gelen karakter ve hata düzeltme @PeterTaylor


Sevindim yardımcı olabilirim :)
öldürmek

Sen yerini alabilecek s<abs(x)**.5ile s*s<abs(x)gerçekten kontrol olmalı rağmen 2. bir tasarruf için <=o anda muhtemelen arabası yani.
Peter Taylor

@PeterTaylor Hatayı işaret ettiğiniz için teşekkür ederiz ...
hlt

Arayan f(0,15)verim TypeError: unsupported operand type(s) for &: 'bool' and 'generator'benim tercüman. :(
Falko

f(0,15)verir False(OS X üzerinde) 2.7.6 ve 3.4.1 hem benim için. Hangi versiyondasın?
hlt

3

Python 2.7 , 341 301 253 bayt, hız için optimize

lambda x,y:(x==0and g(y))or(y==0and g(x))or(x*y and p(x*x+y*y))
def p(n,r=[2]):a=lambda n:r+range(r[-1],int(n**.5)+1);r+=[i for i in a(n)if all(i%j for j in a(i))]if n>r[-1]**2else[];return all(n%i for i in r if i*i<n)
g=lambda x:abs(x)%4>2and p(abs(x))

Çevrimiçi deneyin!

#pRimes. need at least one for r[-1]
r=[2]
#list of primes and other to-check-for-primarity numbers 
#(between max(r) and sqrt(n))
a=lambda n:r+list(range(r[-1],int(n**.5)+1))
#is_prime, using a(n)
f=lambda n:all(n%i for i in a(n))
#is_prime, using r
def p(n):
    global r
    #if r is not enough, update r
    if n>r[-1]**2:
        r+=[i for i in a(n) if f(i)]
    return all(n%i for i in r if i*i<n)
#sub-function for testing (0,y) and (x,0)
g=lambda x:abs(x)%4==3 and p(abs(x))
#the testing function
h=lambda x,y:(x==0 and g(y)) or (y==0 and g(x)) or (x and y and p(x*x+y*y))

Teşekkürler: 40 +48 - Jo King'e tüm golf


The f lambda is also uneccesary, along with the list call. 257 bytes without those, plus some whitespace removal. This perhaps isn't as efficient anymore though
Jo King

(15,0) is now true in 257 bytes version and the run time increased too 5.5s, sorry
Alexey Burdin

2

Perl - 110 107 105 chars

I hope I followed the linked definition correctly...

sub f{($a,$b)=map abs,@_;$n=$a**(1+!!$b)+$b**(1+!!$a);(grep{$n%$_<1}2..$n)<2&&($a||$b%4>2)&&($b||$a%4>2)}

Ungolfed:

sub f {
  ($a,$b) = map abs, @_;
  $n = $a**(1+!!$b) + $b**(1+!!$a);
  (grep {$n%$_<1} 2..$n)<2 && ($a || $b%4==3) && ($b || $a%4==3)
}

Birisi sordu çünkü Açıklama: Ben argümanlar (okuma @_) ve onların mutlak değerlerini koymak $a, $bfonksiyon yapar, çünkü onların işareti gerekmez. Kriterleri her biri bir sayı en asallık test gerektirir, ancak bu sayı bağlıdır $aya da $bbir kısa şekilde ifade etmek ve koymak için çalışılmıştır sıfır vardır $n. Son olarak $n, 2 ile kendisi arasında kaç sayı kaldığını (kalan grep...<2kısım) böldüğünü hesaplayarak asal olup olmadığını kontrol ediyorum ve sonra sayılardan biri sıfırsa, diğerinin 3 modulo 4'e eşit olduğunu kontrol ediyorum. dönüş değeri varsayılan olarak son satırının değeridir ve tüm koşullar yerine getirildiyse bu koşullar bir miktar doğruluk değeri döndürür.


I can't get it to work for negative parameters.
killmous

1
@killmous you're right, just fixed it
Tal

may you explain the algorithm?
proud haskeller

1
Nice! By the way, I think you could shave off a couple characters by writing $a%4>2 instead of $a%4==3.
Todd Lehman

2

golflua 147 141

The above count neglects the newlines that I've added to see the different functions. Despite the insistence to not do so, I brute-force solve primes within the cases.

\p(x)s=2@s*s<=M.a(x)?(x%s==0)~0$s=s+1$~1$
\g(a,b)?a*b!=0~p(a^2+b^2)??a==0~p(b)+M.a(b)%4>2??b==0~p(a)+M.a(a)%4>2!?~0$$
w(g(tn(I.r()),tn(I.r())))

Returns 1 if true and 0 if not.

An ungolfed Lua version,

-- prime number checker
function p(x)
   s=2
   while s*s<=math.abs(x) do
      if(x%s==0) then return 0 end
      s=s+1
   end
   return 1
end

-- check gaussian primes
function g(a,b)
   if a*b~=0 then
      return p(a^2+b^2)
   elseif a==0 then
      return p(b) + math.abs(b)%4>2
   elseif b==0 then
      return p(a) + math.abs(a)%4>2
   else
      return 0
   end
end


a=tonumber(io.read())
b=tonumber(io.read())
print(g(a,b))

You can save 6 characters by just plugging tonumber(io.read()) as an argument to g in the end, and 2 more by removing the newlines
mniip

@mniip: the newlines were not counted, I just added those in for clarity (no sideways scrolling). I'll update the read in g when I get into work in a little bit. Thanks!
Kyle Kanos

Well does it still work in a reasonable amout of time for large numbers? I primarly thought about bruteforcing in the way of checking all gaussian integers a where |a| <= |z| if a | z (if a divides z).
flawr

@flawr: I tested it with a=2147483644, b=896234511 and got 0 in about 0.002 s. I also tested it with 2147483629 & 2147483587 (two very large primes) and got 0 in another 0.002 s. I'm trying to find a large pair of numbers such that a^2+b^2 is prime & ensure that I've got a working solution for such large numbers.
Kyle Kanos

@flawr: Tested with a=4600 & b=5603 (a^2+b^2=2147393609 is prime & < 2^32-1) and it took the same 0.002 seconds to return 1. Yay!
Kyle Kanos

1

APL(NARS), 99 chars, 198 bytes

r←p w;i;k
r←0⋄→0×⍳w<2⋄i←2⋄k←√w⋄→3
→0×⍳0=i∣w⋄i+←1
→2×⍳i≤k
r←1

f←{v←√k←+/2*⍨⍺⍵⋄0=⍺×⍵:(p v)∧3=4∣v⋄p k}

test:

  0 f 13
0
  0 f 9
0
  2 f 3
1
  3 f 4
0
  0 f 7
1
  0 f 9
0
  4600 f 5603
1  

1

Runic Enchantments, 41 bytes

>ii:0)?\S:0)?\:*S:*+'PA@
3%4A|'S/;$=?4/?3

Try it online!

Ended up being a lot easier than I thought and wasn't much room for golfification. The original program I blocked out was:

>ii:0)?\S:0)?\:*S:*+'PA@
3%4A|'S/!   S/;$=

I played around with trying to compare both inputs at the same time (which saved all of one 1 byte), but when that drops into the "one of them is zero" section, there wasn't a good way to figure out which item was non-zero in order to perform the last check, much less a way to do it without spending at least 1 byte (no overall savings).


1

Mathematica, 149 Characters

If[a==0,#[[3]]&&Mod[Abs@b,4]==3,If[b==0,#[[2]]&&Mod[Abs@a,4]==3,#[[1]]]]&[(q=#;Total[Boole@IntegerQ[q/#]&/@Range@q]<3&&q!=0)&/@{a^2+b^2,Abs@a,Abs@b}]

The code doesn't use any standard prime number features of mathematica, instead it counts the number of integers in the list {n/1,n/2,...,n/n}; if the number is 1 or 2, then n is prime. An elaborated form of the function:

MyIsPrime[p_] := (q = Abs@p; 
  Total[Boole@IntegerQ[q/#] & /@ Range@q] < 3 && q != 0)

Bonus plot of all the Gaussian Primes from -20 to 20:

Plot of gaussian primes


1

Ruby -rprime, 65 60 80 bytes

Didn't notice the "can't use isPrime" rule...

->a,b{r=->n{(2...n).all?{|i|n%i>0}};c=(a+b).abs;r[a*a+b*b]||a*b==0&&r[c]&&c%4>2}

Try it online!


0

Python - 117 122 121

def f(a,b):
 v=(a**2+b**2,a+b)[a*b==0]
 for i in range(2,abs(v)):
  if v%i<1:a=b=0
 return abs((a,b)[a==0])%4==3or a*b!=0

Because 3 is the largest a number can be mod 4, you could replace the ==3 with >2
FlipTack
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.