Zadanie
Napisz funkcję, która akceptuje dwie liczby całkowite a,b
reprezentujące liczbę całkowitą Gaussa z = a+ib
(liczba zespolona). Program musi zwrócić wartość true lub false, w zależności od tego, czy a+ib
jest liczbą pierwszą Gaussa, czy nie .
Definicja:
a + bi
jest liczbą pierwszą Gaussa wtedy i tylko wtedy, gdy spełnia jeden z następujących warunków:
a
ib
oba są niezerowe ia^2 + b^2
są liczbą pierwsząa
wynosi zero,|b|
jest liczbą pierwszą i|b| = 3 (mod 4)
b
wynosi zero,|a|
jest liczbą pierwszą i|a| = 3 (mod 4)
Detale
Powinieneś napisać tylko funkcję. Jeśli twój język nie ma funkcji, możesz założyć, że liczby całkowite są przechowywane w dwóch zmiennych i wydrukować wynik lub zapisać go w pliku.
Nie możesz korzystać z wbudowanych funkcji swojego języka, takich jak isprime
lub prime_list
lub nthprime
lub factor
. Najmniejsza liczba bajtów wygrywa. Praca programu musi na a,b
którym a^2+b^2
jest 32-bitowy (podpisany) całkowitą i powinna zakończyć się w nie znacznie więcej niż 30 sekund.
Pierwsza lista
Kropki oznaczają liczby pierwsze na płaszczyźnie Gaussa ( x
= rzeczywista, y
= urojona oś):
Niektóre większe liczby pierwsze:
(9940, 43833)
(4190, 42741)
(9557, 41412)
(1437, 44090)
factor
w Bashmf
imF
w CJam, ...)Odpowiedzi:
Haskell - 77/
108107 Znakiużycie: w obu rozwiązaniach wpisanie% b zwróci, czy a + bi jest liczbą pierwszą gaussowską.
najniższy udało mi się, ale brak kreatywności i wydajności (77 znaków)
to rozwiązanie obsługuje wszystkie liczby poniżej n, aby sprawdzić, czy jest liczbą pierwszą.
wersja bez golfa:
następne rozwiązanie ma dodatkową funkcję - zapamiętywanie. po sprawdzeniu, czy liczba całkowita n jest liczbą pierwszą, nie trzeba ponownie obliczać „pierwotności” wszystkich liczb mniejszych lub równych n, ponieważ zostaną one zapisane na komputerze.
(107 znaków. Komentarze są dla jasności)
wersja bez golfa:
wykorzystuje to sito Eratostenesa do obliczenia nieskończonej listy wszystkich liczb pierwszych (zwanej l dla listy w kodzie). (nieskończone listy są dobrze znaną sztuczką haskell).
jak można mieć nieskończoną listę? na początku programu lista nie jest oceniana, a zamiast przechowywać elementy list, komputer zapisuje sposób ich obliczenia. ale gdy program uzyskuje dostęp do listy, częściowo ocenia się do żądania. więc jeśli program zażąda czwartego elementu na liście, komputer obliczy wszystkie liczby pierwsze aż do czwartej, które nie zostały jeszcze ocenione, zapisze je, a reszta pozostanie nieoceniona, zapisana jako sposób ich jednokrotnego obliczenia potrzebne.
zwróć uwagę, że wszystko to jest wyrażane swobodnie przez leniwą naturę języka Haskell, czego nie wynika z samego kodu.
obie wersje programu są przeciążone, więc mogą obsługiwać dane o dowolnej wielkości.
źródło
C,
149118 znakówWersja edytowana (118 znaków):
To jest jedna funkcja:
Składa test pierwszeństwa liczb całkowitych na wyrażenie
n/d/d|n<2
ukryte w obliczeniu wartości zwracanej. Ten kod do gry w golfa służy równieża*b
jako zamiennika&&b
(innymi słowya!=0 && b!=0
) i innych sztuczek obejmujących pierwszeństwo operatora i dzielenie liczb całkowitych. Na przykładn/d/d
jest krótszy sposób mówienian/d/d>=1
, który jest bezpieczny sposób przelewowy powiedziećn>=d*d
lubd*d<=n
czy w istocied<=sqrt(n)
.Wersja oryginalna (149 znaków):
Funkcje:
Q ( n ) zwraca 0 (fałsz), jeśli n jest liczbą pierwszą, lub 1 (prawda), jeśli n jest liczbą pierwszą. Jest to funkcja pomocnicza dla G ( a , b ).
G ( a , b ) zwraca 1 (prawda), jeśli a + bi jest liczbą pierwszą Gaussa, lub 0 (fałsz) w przeciwnym razie.
Wyjściowa próbka (skalowana w górę o 200%) dla | a |, | b | ≤ 128:
źródło
d++
nie stało się to częścią warunku, w przeciwnym razie zakłóca logikę. Ponadto przesunięcied=2
wewnątrzfor
pętli faktycznie zwiększa liczbę znaków, zamiast ją zmniejszać, ponieważd
nadal musi być zadeklarowane jakoint
przedfor
pętlą. Czy coś brakuje?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;}
wychodzi tylko z 97 znaków.APL (Dyalog Unicode) ,
36474849474328 bajtówPobiera tablicę dwóch liczb całkowitych
a b
i zwraca wartość logiczną instrukcjia+bi is a Gaussian integer
.Edycja: +11 bajtów, ponieważ źle zrozumiałem definicję liczby Gaussa. +1 bajt od ponownego poprawienia odpowiedzi. +1 bajt z trzeciej poprawki błędu. -2 bajty z powodu użycia pociągu zamiast dfn. -4 bajty dzięki ngn dzięki użyciu osłony
condition: if_true ⋄ if_false
zamiastif_true⊣⍣condition⊢if_false
. -15 bajtów dzięki ngn ze względu na znalezienie zupełnie innego sposobu na napisanie warunku-jeśli-inaczej jako pełnego zestawu.Wypróbuj online!
Wyjaśnienie
źródło
Haskell - 121 znaków (w tym nowe znaki)
Oto stosunkowo proste rozwiązanie Haskell, które nie korzysta z żadnych zewnętrznych modułów i jest zmarnowane tak daleko, jak tylko mogłem je zdobyć.
Wywołaj jako
ghci ./gprimes.hs
i wtedy możesz użyć go w interaktywnej powłoce. Uwaga: liczby ujemne są wybredne i muszą być umieszczone w nawiasach. To znaczyźródło
Python -
121120 znakówp
sprawdza, czyabs(x)
jest liczbą pierwszą, iterując wszystkie liczby od 2 doabs(x)**.5
(co jestsqrt(abs(x))
). Robi to, poddając sięx % s
każdemus
.all
następnie sprawdza, czy wszystkie uzyskane wartości są niezerowe, i przestaje generować wartości, gdy napotka dzielnikx
. Wf
,f(b,a)
zastępuje sprawę dob==0
inspirowany @killmous 'Haskell odpowiedź.-1 znak i poprawka błędu z @PeterTaylor
źródło
s<abs(x)**.5
zs*s<abs(x)
na oszczędność 2. Mimo, że naprawdę powinno być sprawdzenie<=
, więc to chyba wadliwy w chwili obecnej.f(0,15)
przynosi zyskTypeError: unsupported operand type(s) for &: 'bool' and 'generator'
mojemu tłumaczowi. :(f(0,15)
dajeFalse
mi, zarówno w wersji 2.7.6, jak i 3.4.1 (w OS X). W jakiej wersji jesteś?Python 2.7 ,
341301253 bajtów, zoptymalizowany pod kątem szybkościWypróbuj online!
Dzięki: 40 +48 - cała gra w golfa dla Jo Kinga
źródło
f
Lambda jest również uneccesary, wraz zlist
rozmowy. 257 bajtów bez nich oraz pewne usuwanie spacji. Być może nie jest to już tak wydajnePerl -
110107105 znakówMam nadzieję, że poprawnie zastosowałem połączoną definicję ...
Nie golfowany:
Wyjaśnienie, że ktoś pyta: czytam argumenty (
@_
) i umieścić ich wartości bezwzględne w$a
,$b
nie dlatego, że funkcja nie trzeba ich znak. Każde z kryteriów wymaga przetestowania pierwotności liczby, ale liczba ta zależy od tego,$a
czy$b
jest zero, co starałem się wyrazić w najkrótszy sposób i wstawić$n
. Na koniec sprawdzam, czy liczba$n
pierwsza jest liczona, licząc, ile liczb między 2 i sam dzielę ją bez reszty (to jestgrep...<2
część), a następnie sprawdzam dodatkowo, że jeśli jedna z liczb jest zerowa, to druga równa się 3 modulo 4. Funkcja wartość zwracana jest domyślnie wartością ostatniego wiersza, a te warunki zwracają pewną prawdziwą wartość, jeśli wszystkie warunki zostaną spełnione.źródło
$a%4>2
zamiast$a%4==3
.golflua
147141Powyższa liczba pomija nowe wiersze, które dodałem, aby zobaczyć różne funkcje. Pomimo nalegań, aby tego nie robić, brutalnie rozwiązuję liczby pierwsze w tych przypadkach.
Zwraca 1, jeśli prawda, i 0, jeśli nie.
Nie golfowa wersja Lua,
źródło
tonumber(io.read())
jako argumentg
na końcu, i 2 kolejne, usuwająca
gdzie|a| <= |z|
ifa | z
(jeślia
dzieliz
).APL (NARS), 99 znaków, 198 bajtów
test:
źródło
Runiczne Zaklęcia , 41 bajtów
Wypróbuj online!
Skończyło się to o wiele łatwiejszym niż myślałem i nie miałem wiele miejsca na golfiację. Oryginalny program, który zablokowałem, to:
Bawiłem się, próbując porównać oba wejścia jednocześnie (co pozwoliło zaoszczędzić cały jeden 1 bajt), ale kiedy to wpadnie do sekcji „jeden z nich ma zero”, nie było dobrego sposobu, aby dowiedzieć się, który element było niezerowe w celu wykonania ostatniej kontroli, a tym bardziej sposób na zrobienie tego bez wydawania co najmniej 1 bajtu (bez ogólnych oszczędności).
źródło
Mathematica, 149 znaków
Kod nie używa żadnych standardowych funkcji liczb pierwszych w matematyce, zamiast tego zlicza liczby całkowite na liście {n / 1, n / 2, ..., n / n}; jeśli liczba wynosi 1 lub 2, n jest liczbą pierwszą. Opracowana forma funkcji:
Dodatkowy wykres wszystkich liczb pierwszych Gaussa od -20 do 20:
źródło
Rubinowy
-rprime
,656080 bajtówNie zauważyłem zasady „nie można używać isPrime” ...
Wypróbuj online!
źródło
Python -
117 122121źródło
==3
z>2