Twoim celem jest ustalenie, czy dana liczba n
jest liczbą pierwszą w najmniejszej liczbie bajtów. Ale twój kod musi być pojedynczym wyrażeniem Python 2 na liczbach składających się tylko z
- operatorzy
- zmienna wejściowa
n
- stałe całkowite
- zdanie wtrącone
Bez pętli, bez przypisań, bez wbudowanych funkcji, tylko to, co wymieniono powyżej. Tak, to możliwe.
Operatorzy
Oto lista wszystkich operatorów w Pythonie 2 , które obejmują operatory arytmetyczne, bitowe i logiczne:
+ adddition
- minus or unary negation
* multiplication
** exponentiation, only with non-negative exponent
/ floor division
% modulo
<< bit shift left
>> bit shift right
& bitwise and
| bitwise or
^ bitwise xor
~ bitwise not
< less than
> greater than
<= less than or equals
>= greater than or equals
== equals
!= does not equal
Wszystkie wartości pośrednie są liczbami całkowitymi (lub False / True, które domyślnie wynoszą 0 i 1). Potęgowanie nie może być stosowane z wykładnikami ujemnymi, ponieważ może to powodować liczby zmiennoprzecinkowe. Zauważ, że dzieli /
podział podłogi, w przeciwieństwie do Pythona 3, więc //
nie jest potrzebny.
Nawet jeśli nie znasz języka Python, operatory powinny być dość intuicyjne. Patrz tej tabeli operatorów, i tym odcinku i poniżej w szczegółowym opisie gramatyki. Możesz uruchomić Python 2 na TIO .
I / O
Dane wejściowe: dodatnia liczba całkowita, n
która wynosi co najmniej 2.
Wyjście: 1 jeśli n
jest liczbą pierwszą, a 0 w przeciwnym razie. True
i False
mogą być również używane. Wygrywa najmniej bajtów.
Ponieważ twój kod jest wyrażeniem, będzie fragmentem, oczekującym wartości wejściowej przechowywanej jako n
i oceniającym pożądane wyjście.
Kod musi działać n
niezależnie od dowolnych, dużych limitów systemowych. Ponieważ typ liczbowy Pythona jest nieograniczony, operatorzy nie mają żadnych ograniczeń. Uruchomienie kodu może jednak zająć dużo czasu.
Odpowiedzi:
43 bajty
Wypróbuj online!
Metoda jest podobna do drugiej (usuniętej) odpowiedzi Dennisa, ale łatwiej jest udowodnić, że jest poprawna.
Dowód
Skrócona forma
Najbardziej znacząca cyfra2n n
(4**n+1)**n%4**n**2
w podstawie która nie jest podzielna przez n, spowoduje, że następna (mniej znacząca) cyfra będzie niezerowa (jeśli ta „kolejna cyfra” nie znajduje się w części ułamkowej), wówczas wykonywana jest a z maską bitową w celu sprawdzenia jeśli jakakolwiek cyfra w nieparzystej pozycji jest niezerowa.(4**n+1)**n%4**n**2/n
&
2**(2*n*n+n)/-~2**n
Długa forma
Niech jest liczbą o tej podstawy b reprezentację, czyli n b n + ⋯ + 1 b 1 + 0 b 0 i i być cyfra w " pozycja „ i w reprezentacji bazy b .[an,…,a1,a0]b b anbn+⋯+a1b1+a0b0 ai i b
Ponieważ (przyn2n-1s) jest liczbą całkowitą, a⌊2n2n×4n2−11+2n=2n(2n−1)×(4n)n−14n−1=[2n−1,0,2n−1,0,2n−1,0]2n n 2n−1 ,
=[2n-1,0,2n-1,0,2n-1,0]2n.⌊2n1+2n⌋=0 [2n−1,0,2n−1,0,2n−1,0]2n
2**(2*n*n+n)/-~2**n
Następnie rozważ
%4**n**2
liczbę do ostatnich cyfr - co wyklucza (czyli 1), ale obejmuje wszystkie inne współczynniki dwumianowe.O
/n
:Jeśli jest liczbą pierwszą, wynikiem będzie . Wszystkie cyfry w nieparzystej pozycji są równe zero.n [(nn−1)/n,0,…,0,(n1)/n,0,0]2n
Jeśli nie jest liczbą pierwszą:n
Niech będzie największą liczbą całkowitą taką, że ( ). Przepisz dywidendę jakoa n∤(na) n>a>0
Pierwszy summand ma wszystkie cyfry podzielne przez , a cyfra na pozycji zero.n 2a−1
Drugi zbiór ma swoją najbardziej znaczącą cyfrę (w pozycji ) niepodzielną przez i (podstawa) , więc iloraz przy dzieleniu tej przez miałby cyfrę w pozycji niezerową.2a n 2n>n n 2a−1
Dlatego końcowy wynik (2n 2a+1
(4**n+1)**n%4**n**2/n
) powinien mieć cyfrę (podstawa , oczywiście) w pozycji niezerową.Wreszcie bitowe AND (2n a&0=0,a&(2n−1)=a 0≤a<2n n n
&
) wykonuje wektoryzowane bitowe AND na cyfrach w podstawie (ponieważ podstawa jest potęgą 2), a ponieważ dla wszystkich , wynosi zero iff ma wszystkie cyfry w pierwszych nieparzystych pozycjach zero - co odpowiada jest liczbą pierwszą.(4**n+1)**n%4**n**2/n&2**(2*n*n+n)/-~2**n
(4**n+1)**n%4**n**2/n
źródło
(4**n+1)**n%2**n**2/n&2**n**2/-~2**n<1
zadziała?n
nie powodując niepożądanych interakcji między bazą cyfr4**n
.(4**n+1)**n%4**n**2/n<<n&4**n**2/-~2**n<1
. Jestem ciekawy, czy to wyzwanie jest możliwe bez operatorów bitowych.Python 2 , 56 bajtów
Wypróbuj online!
Jest to proof-of-concept, że to wyzwanie jest wykonalne tylko operatorów arytmetycznych, w szczególności bez bitowe
|
,&
lub^
. Kod wykorzystuje operatory bitowe i porównania tylko do gry w golfa i można je łatwo zastąpić odpowiednikami arytmetycznymi.Jednak rozwiązanie jest bardzo wolne i nie byłem w stanie uruchomić `, dzięki dwupoziomowym potęgom takim jak .n=6 2nn
Główną ideą jest wyrażenie na silnię, który pozwala nam wykonać test pierwszeństwa Twierdzenia Wilsona gdzie jest operatorem modulo.n! (n−1)!%n>n−2 %
Możemy wyrazić współczynnik dwumianowy , który składa się z silni
Ale nie jest jasne, jak wyodrębnić tylko jeden z tych czynników. Sztuką jest rozbicieczyniąc naprawdę ogromnym.n! m
Więc jeśli pozwolimy być produktem , mamyc (1−1m)(1−2m)⋯(1−n−1m)
Gdybyśmy mogli po prostu zignorować , bylibyśmy skończeni. Reszta tego postu pokazuje, jak duże musimy zrobić aby móc to zrobić.c m
Zauważ, że zbliża się do od dołu jako . Musimy tylko zrobić tak duże, że pominięcie daje nam wartość z liczbą całkowitąabyśmy mogli obliczyćc 1 m→∞ m c n!
W tym celu wystarczy miećaby uniknąć przekroczenia stosunku następnej liczby całkowitej .1−c<1/n! n!+1
Zauważ, że jest iloczynem warunków, z których najmniejszym jest . Więc mamyc n (1−n−1m)
co oznacza . Ponieważ chcemy mieć, wystarczy wziąć .1−c<n2m 1−c<1/n! m≥n!⋅n2
W kodzie używamy . Ponieważ używa Twierdzenia Wilsona, w rzeczywistości potrzebujemy tylko . Łatwo zauważyć, że spełnia granicę małych wartości i szybko przerasta asymptotycznie prawą stronę, powiedzmy z przybliżeniem Stirlinga .m=nn (n−1)! m≥(n−1)!⋅(n−1)2 m=nn
źródło
Ta odpowiedź nie wykorzystuje żadnej sprytowej teorii. Spamuje bitowe operatory Pythona, aby utworzyć instrukcję „for loop”, sprawdzając wszystkie pary aby zobaczyć, czy .1≤i,j<n i×j=n
Python 2, zdecydowanie za dużo bajtów (278 dzięki Jo King w komentarzach!)
Wypróbuj online!
To jest o wiele więcej bajtów niż inne odpowiedzi, więc na razie pozostawiam to bez odpowiedzi. Poniższy fragment kodu zawiera funkcje i przypisanie zmiennych dla przejrzystości, ale podstawienie zamienia isPrime (n) w pojedyncze wyrażenie Python.
Dlaczego to działa?
Zrobię ten sam algorytm tutaj w bazie 10 zamiast binarnej. Spójrz na tę zgrabną frakcję:
Jeśli umieścimy dużą moc 10 w liczniku i użyjemy podziału podłogi Pythona, daje to wyliczenie liczb. Na przykład z podziałem podłogi, wyliczając liczby .1015/(9992)=1002003004 1,2,3,4
Powiedzmy, że mnożymy dwie liczby w ten sposób, z różnymi odstępami zer. Umieszczę przecinki sugestywnie w produkcie.
Produkt wylicza, w trzycyfrowych sekwencjach, tabliczkę mnożenia do 4 razy 4. Jeśli chcemy sprawdzić, czy liczba 5 jest liczbą pierwszą, musimy tylko sprawdzić, czy pojawia się gdziekolwiek w tym produkcie.005
Aby to zrobić, XOR powyższy produkt XOR numer , a następnie odejmujemy liczbę . Nazwij wynik . Jeśli w wyliczeniu tablicy mnożenia pojawiło się , spowoduje to przeniesienie odejmowania i umieszczenie w odpowiednim miejscu w .005005005…005 001001001…001 d 005 999 d
Aby przetestować to przepełnienie, obliczamy AND AND i liczbę . Wynik wynosi zero wtedy i tylko wtedy, gdy 5 jest liczbą pierwszą.d 900900900…900
źródło