Biorąc pod uwagę nieujemną liczbę całkowitą N
, wyprowadza najmniejszą nieparzystą liczbę całkowitą dodatnią, która jest silnym pseudopierwszym znakiem dla wszystkich pierwszychN
liczb .
Jest to sekwencja OEIS A014233 .
Przypadki testowe (z jednym indeksem)
1 2047
2 1373653
3 25326001
4 3215031751
5 2152302898747
6 3474749660383
7 341550071728321
8 341550071728321
9 3825123056546413051
10 3825123056546413051
11 3825123056546413051
12 318665857834031151167461
13 3317044064679887385961981
Przypadki testowe dla N > 13
nie są dostępne, ponieważ te wartości nie zostały jeszcze znalezione. Jeśli uda Ci się znaleźć kolejne terminy w sekwencji, koniecznie prześlij je do OEIS!
Zasady
- Możesz wybrać
N
wartość zerową lub jedną indeksowaną. - Dopuszczalne jest, aby twoje rozwiązanie działało tylko dla wartości reprezentatywnych w zakresie liczb całkowitych twojego języka (tak więc
N = 12
dla niepodpisanych liczb całkowitych 64-bitowych), ale twoje rozwiązanie musi teoretycznie działać dla każdego wejścia, przy założeniu, że twój język obsługuje liczby całkowite o dowolnej długości.
tło
Każda dodatnia parzysta liczba całkowita x
może być zapisana w postaci, w x = d*2^s
której d
jest nieparzysta. d
i s
można go obliczyć przez wielokrotne dzielenie n
przez 2, aż iloraz nie będzie już podzielny przez 2. d
to ostateczny iloraz i s
jest to liczba razy 2 dzielenian
.
Jeśli liczba całkowita dodatnia n
jest liczbą pierwszą, to małe twierdzenie Fermata głosi:
W dowolnym polu skończonym Z/pZ
(gdzie p
jest liczba pierwsza) jedynymi pierwiastkami kwadratowymi 1
są 1
i -1
(lub równoważnie 1
i p-1
).
Możemy użyć tych trzech faktów, aby udowodnić, że jedno z dwóch poniższych stwierdzeń musi być prawdziwe dla liczby pierwszej n
(gdzie d*2^s = n-1
i gdzie r
jest liczba całkowita [0, s)
):
Test pierwszeństwa Millera-Rabina działa na zasadzie przeciwstawności powyższego twierdzenia: jeśli istnieje podstawa a
taka, że oba powyższe warunki są fałszywe, n
to nie jest pierwsza. Ta baza a
nazywa się świadkiem .
Teraz testowanie każdej bazy [1, n)
byłoby zbyt drogie w obliczeniach dla dużych n
. Istnieje probabilistyczny wariant testu Millera-Rabina, który testuje tylko niektóre losowo wybrane zasady w polu skończonym. Okazało się jednak, że a
wystarczające jest testowanie tylko podstawowych zasad, dlatego test można przeprowadzić w sposób skuteczny i deterministyczny. W rzeczywistości nie wszystkie podstawowe zasady muszą zostać przetestowane - wymagana jest tylko pewna liczba, a liczba ta zależy od wielkości testowanej wartości pierwotności.
Jeśli przetestowana zostanie niewystarczająca liczba zasad podstawowych, test może dać fałszywie dodatnie - nieparzyste liczby całkowite, w których test nie udowodni ich złożoności. W szczególności, jeśli baza a
nie udowodni złożoności nieparzystej liczby złożonej, liczba ta nazywana jest silnym pseudopierwszym znakiem bazy a
. Wyzwanie polega na znalezieniu nieparzystych liczb zespolonych, które są silnymi pseudopierwszymi dla wszystkich zasad mniejszych lub równych N
th pierwszej liczbie podstawowej (co jest równoważne z twierdzeniem, że są one silnymi pseudopierwszymi dla wszystkich baz pierwszych mniejszych lub równych N
th pierwszej liczbie pierwszej) .
Odpowiedzi:
C,
349295277267255 bajtówPobiera 1-wejściowe dane wejściowe na standardowe wejście, np .:
Na pewno w najbliższym czasie nie odkryje żadnych nowych wartości w sekwencji, ale wykonuje zadanie. AKTUALIZACJA: teraz jeszcze wolniej!
a^(d*2^r) == (a^d)^(2^r)
)__int128
, który jest krótszy niżunsigned long long
podczas pracy z większymi liczbami! Również na maszynach little-endian printf z%llu
nadal działa dobrze.Mniej zminimalizowane
(Nieaktualne) Podział
Jak wspomniano, wykorzystuje to dane wejściowe oparte na 1.
Ale dla n = 0 daje wartość 9, która następuje po pokrewnej sekwencji https://oeis.org/A006945 .Nigdy więcej; teraz wisi na 0.Powinien działać dla wszystkich n (przynajmniej dopóki wynik nie osiągnie 2 ^ 64), ale jest niewiarygodnie wolny. Sprawdziłem to na n = 0, n = 1 i (po długim oczekiwaniu), n = 2.
źródło
Python 2,
633465435292282275256247 bajtów0-indeksowane
Konwersja funkcji na program pozwala jakoś zaoszczędzić niektóre bajty ...
Jeśli Python 2 daje mi krótszy sposób na zrobienie tego samego, użyję Python 2. Podział jest domyślnie liczbą całkowitą, więc łatwiejszy sposób dzielenia przez 2 i
print
nie wymaga nawiasów.Wypróbuj online!
Python jest notorycznie wolny w porównaniu do innych języków.
Definiuje test podziału próby dla absolutnej poprawności, a następnie wielokrotnie stosuje test Millera-Rabina, dopóki nie zostanie znaleziony pseudopierwszy.
Wypróbuj online!
EDYCJA : W końcu grał w golfa odpowiedź
EDYCJA : Używany
min
do testu pierwszeństwa podziału próby i zmienił go na alambda
. Mniej wydajny, ale krótszy. Również nie mogłem się powstrzymać i użyłem kilku bitowych operatorów (bez różnicy długości). Teoretycznie powinien działać (nieco) szybciej.EDYCJA : Dzięki @Dave. Mój redaktor mnie trollował. Myślałem, że używam tabulatorów, ale zamiast tego konwertowałem je na 4 spacje. Przeanalizowałem też prawie każdą wskazówkę Pythona i zastosowałem ją.
EDYCJA : Przełączony na indeksowanie 0, pozwala mi zaoszczędzić kilka bajtów z generowaniem liczb pierwszych. Zastanowiłem się także nad kilkoma porównaniami
EDYCJA : Użyła zmiennej do przechowywania wyniku testów zamiast
for/else
instrukcji.EDYCJA : Przeniesiono
lambda
wewnątrz funkcji, aby wyeliminować potrzebę parametru.EDYCJA : Konwersja do programu do zapisywania bajtów
EDYCJA : Python 2 oszczędza mi bajtów! Nie muszę też konwertować danych wejściowych
int
źródło
a^(d*2^r) mod n
!Perl + Math :: Prime :: Util, 81 + 27 = 108 bajtów
Uruchom z
-lpMMath::Prime::Util=:all
(kara 27 bajtów, ouch).Wyjaśnienie
To nie tylko Mathematica ma wbudowane praktycznie wszystko. Perl ma CPAN, jedno z pierwszych dużych repozytoriów bibliotek, i które ma ogromną kolekcję gotowych rozwiązań dla zadań takich jak ten. Niestety nie są one domyślnie importowane (ani nawet instalowane), co oznacza, że w zasadzie nigdy nie jest to dobra opcja ich użycia golfa , ale gdy jedno z nich idealnie pasuje do problemu…
Przeszukujemy kolejne liczby całkowite, dopóki nie znajdziemy jednej, która nie jest liczbą pierwszą, a jednak silnym pseudopierwszym znakiem dla wszystkich liczb całkowitych od 2 do n- tej liczby pierwszej. Opcja wiersza polecenia importuje bibliotekę zawierającą dane wbudowane narzędzie, a także ustawia niejawne dane wejściowe (do wiersza na raz;
Math::Prime::Util
ma własną wbudowaną bibliotekę bignum, która nie lubi znaków nowej linii w liczbach całkowitych). Wykorzystuje standardową sztuczkę Perla polegającą na użyciu$\
(separatora linii wyjściowej) jako zmiennej w celu ograniczenia niezręcznych analiz i umożliwienia generowania danych wyjściowych w sposób niejawny.Pamiętaj, że musimy użyć
is_provable_prime
tutaj , aby zażądać deterministycznego, a nie probabilistycznego testu podstawowego. (Zwłaszcza biorąc pod uwagę, że probabilistyczny test główny najprawdopodobniej użyje Millera-Rabina, czego nie możemy oczekiwać w tym przypadku, aby dać wiarygodne wyniki!)Perl + Math :: Prime :: Util, 71 + 17 = 88 bajtów, we współpracy z @Dada
Biegnij z
-lpMntheory=:all
(kara 17 bajtów).Wykorzystuje kilka sztuczek golfowych Perla, których albo nie znałem (najwyraźniej Math :: Prime :: Util ma skrót!), O których wiedziałem, ale nie pomyślałem o użyciu (
}{
do$\
jednoznacznego wygenerowania danych zamiast"$_$\"
domyślnie każdej linii) lub wiedział o, ale jakoś udało się go niewłaściwie zastosować (usuwając nawiasy z wywołań funkcji). Dzięki @Dada za wskazanie mi tego. Poza tym jest identyczny.źródło
ntheory
zamiastMath::Prime::Util
. Ponadto,}{
zamiast;$_=""
powinno być dobrze. I możesz pominąć spację1
i nawiasy kilku wywołań funkcji. Również&
działa zamiast&&
. To powinno dać 88 bajtów:perl -Mntheory=:all -lpe '1until!is_provable_prime(++$\)&is_strong_pseudoprime$\,2..nth_prime$_}{'
}{
. (O dziwo, przypomniałem sobie nawias, ale minęło trochę czasu, odkąd grałem w Perla i nie pamiętałem zasad, aby go pominąć.) Jednak w ogóle nie wiedziałem ontheory
skrócie.