Bei einer nicht negativen Ganzzahl N
wird die kleinste ungerade positive Ganzzahl ausgegeben, die eine starke Pseudoprime für alle ersten N
Primzahlen darstellt.
Dies ist die OEIS-Sequenz A014233 .
Testfälle (einseitig indiziert)
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
Testfälle für N > 13
sind nicht verfügbar, da diese Werte noch nicht gefunden wurden. Wenn Sie den / die nächsten Begriff (e) in der Sequenz finden, senden Sie ihn / sie unbedingt an OEIS!
Regeln
- Sie können wählen, ob Sie
N
einen Null- oder einen Ein-Index-Wert verwenden möchten. - Es ist akzeptabel, dass Ihre Lösung nur für die Werte funktioniert, die im ganzzahligen Bereich Ihrer Sprache darstellbar sind (also bis zu
N = 12
64-Bit-Ganzzahlen ohne Vorzeichen), aber Ihre Lösung muss theoretisch für jede Eingabe funktionieren, mit der Annahme, dass Ihre Sprache Ganzzahlen beliebiger Länge unterstützt.
Hintergrund
Jede positive gerade ganze Zahl x
kann in der Form geschrieben werden , x = d*2^s
wo d
ungerade ist. d
und s
kann durch wiederholtes Dividieren berechnet werden , n
um 2 , bis der Quotient nicht mehr durch 2 teilbar d
ist , dass Endquotienten, und s
ist die Anzahl von Malen 2 dividieren n
.
Wenn eine positive ganze Zahl n
eine Primzahl ist, lautet der kleine Satz von Fermat :
In jedem endlichen Feld Z/pZ
(wo p
eine Primzahl ist) 1
sind 1
und -1
(oder äquivalent 1
und p-1
) die einzigen Quadratwurzeln von .
Wir können diese drei Tatsachen verwenden, um zu beweisen, dass eine der folgenden beiden Aussagen für eine Primzahl wahr sein muss n
(wo d*2^s = n-1
und r
in welcher Zahl eine ganze Zahl ist [0, s)
):
Der Miller-Rabin-Primalitätstest testet das Gegenteil der obigen Behauptung: Wenn es eine Basis gibt a
, bei der beide oben genannten Bedingungen falsch sind, n
ist dies keine Primzahl. Diese Basis a
wird als Zeuge bezeichnet .
Jetzt [1, n)
wäre das Testen jeder Basis in unerschwinglicher Rechenzeit für große Unternehmen n
. Es gibt eine probabilistische Variante des Miller-Rabin-Tests, die nur einige zufällig ausgewählte Basen im endlichen Feld testet. Es wurde jedoch herausgefunden, dass das Testen nur von primären a
Basen ausreichend ist, und daher kann der Test auf effiziente und deterministische Weise durchgeführt werden. Tatsächlich müssen nicht alle Primzahlenbasen getestet werden - es ist nur eine bestimmte Anzahl erforderlich, und diese Anzahl hängt von der Größe des Werts ab, dessen Primalität getestet wird.
Wenn nicht genügend Primzahlenbasen getestet werden, kann der Test falsch positive Ergebnisse liefern - ungerade zusammengesetzte ganze Zahlen, bei denen der Test ihre Zusammensetzung nicht nachweist. Insbesondere, wenn eine Basis a
die Zusammensetzung einer ungeraden zusammengesetzten Zahl nicht beweisen kann, wird diese Zahl als starkes Pseudoprime zur Basis bezeichnet a
. Bei dieser Herausforderung geht es darum, die ungeraden zusammengesetzten Zahlen zu finden, die starke Pseudoprimes für alle Basen sind, die kleiner oder gleich der dritten N
Primzahl sind (was gleichbedeutend damit ist, dass sie starke Pseudoprimes für alle Primzahlen sind, die kleiner oder gleich der N
dritten Primzahl sind). .
Antworten:
C
349295277267255 BytesNimmt 1-basierte Eingabe für stdin auf, zB:
Es wird sicherlich nicht in naher Zukunft neue Werte in der Sequenz entdecken, aber es wird die Arbeit erledigen. UPDATE: jetzt noch langsamer!
a^(d*2^r) == (a^d)^(2^r)
)__int128
, die kürzer sind alsunsigned long long
bei der Arbeit mit größeren Nummern! Auch auf Little-Endian-Rechnern%llu
funktioniert der printf mit noch einwandfrei.Weniger reduziert
(Veraltete) Aufschlüsselung
Wie bereits erwähnt, wird hier eine 1-basierte Eingabe verwendet.
Für n = 0 ergibt sich jedoch eine 9, die der verwandten Sequenz https://oeis.org/A006945 folgt .Nicht länger; jetzt hängt es an 0.Sollte für alle n funktionieren (zumindest bis die Ausgabe 2 ^ 64 erreicht), ist aber unglaublich langsam. Ich habe es auf n = 0, n = 1 und (nach langem Warten) auf n = 2 überprüft .
quelle
Python 2,
633465435292282275256247 Bytes0-indiziert
Das Konvertieren von einer Funktion in ein Programm spart irgendwie einige Bytes ...
Wenn mir Python 2 eine kürzere Möglichkeit bietet, das Gleiche zu tun, verwende ich Python 2. Division ist standardmäßig eine Ganzzahl, also eine einfachere Möglichkeit, durch 2 zu teilen, und
print
benötigt keine Klammern.Probieren Sie es online!
Python ist im Vergleich zu anderen Sprachen notorisch langsam.
Definiert einen Testteilungs-Test auf absolute Korrektheit und wendet dann wiederholt den Miller-Rabin-Test an, bis ein Pseudoprim gefunden wird.
Probieren Sie es online!
EDIT : Endlich golfen die Antwort
EDIT : Wird
min
für den Primalitätstest der Testabteilung verwendet und in a geändertlambda
. Weniger effizient, aber kürzer. Konnte mir auch nicht helfen und benutzte ein paar bitweise Operatoren (kein Längenunterschied). Theoretisch sollte es (etwas) schneller gehen.EDIT : Danke @ Dave. Mein Redakteur hat mich beschimpft. Ich dachte, ich benutze Tabulatoren, aber es wurde stattdessen in 4 Leerzeichen umgewandelt. Ging auch so ziemlich jeden einzelnen Python-Tipp durch und wendete ihn an.
BEARBEITEN : Umgestellt auf 0-Indizierung, ermöglicht es mir, ein paar Bytes beim Generieren der Primzahlen zu sparen. Auch ein paar Vergleiche überdacht
EDIT : Verwendet eine Variable, um das Ergebnis der Tests anstelle von
for/else
Anweisungen zu speichern .BEARBEITEN : Verschob das
lambda
Innere der Funktion, um die Notwendigkeit eines Parameters zu beseitigen.BEARBEITEN : In ein Programm konvertiert, um Bytes zu sparen
EDIT : Python 2 spart mir Bytes! Außerdem muss ich die Eingabe nicht in konvertieren
int
quelle
a^(d*2^r) mod n
!Perl + Math :: Prime :: Util, 81 + 27 = 108 Bytes
Laufen Sie mit
-lpMMath::Prime::Util=:all
(27-Byte-Strafe, autsch).Erläuterung
Es ist nicht nur Mathematica, das für praktisch alles eine eingebaute Funktion hat. Perl verfügt über CPAN, eines der ersten großen Bibliotheksrepositorys, und eine riesige Sammlung vorgefertigter Lösungen für Aufgaben wie diese. Leider werden sie nicht standardmäßig importiert (oder sogar installiert), was bedeutet, dass es grundsätzlich nie eine gute Option ist, sie in Code-Golf zu verwenden , aber wenn eine davon genau zum Problem passt ...
Wir durchlaufen aufeinanderfolgende ganze Zahlen, bis wir eine finden, die keine Primzahl und dennoch eine starke Pseudoprime für alle ganzzahligen Basen von 2 bis zur n- ten Primzahl ist. Die Befehlszeilenoption importiert die Bibliothek, die das betreffende eingebaute Element enthält, und legt auch die implizite Eingabe fest (auf Zeile für Zeile;
Math::Prime::Util
verfügt über eine eigene eingebaute Bignum-Bibliothek, die keine Zeilenumbrüche in den Ganzzahlen mag). Hierbei wird der Perl-Standardtrick$\
(Ausgabezeilentrennzeichen) als Variable verwendet, um umständliche Parser zu reduzieren und die implizite Generierung der Ausgabe zu ermöglichen.Beachten Sie, dass wir hier verwenden müssen, um
is_provable_prime
eher einen deterministischen als einen probabilistischen Primetest anzufordern. (Vor allem, da ein probabilistischer Primetest wahrscheinlich in erster Linie mit Miller-Rabin durchgeführt wird, und wir in diesem Fall keine verlässlichen Ergebnisse erwarten können!)Perl + Math :: Prime :: Util, 71 + 17 = 88 Bytes, in Zusammenarbeit mit @Dada
Laufen Sie mit
-lpMntheory=:all
(17-Byte-Strafe).Dies verwendet ein paar Perl-Golftricks, die ich entweder nicht kannte (anscheinend hat Math :: Prime :: Util eine Abkürzung!), Die ich kannte, aber nicht zu verwenden dachte (
}{
um$\
implizit einmal statt"$_$\"
implizit jeder Zeile auszugeben ). , oder wussten über, aber irgendwie geschafft, falsch anzuwenden (Klammern aus Funktionsaufrufen entfernen). Vielen Dank an @Dada für diesen Hinweis. Abgesehen davon ist es identisch.quelle
ntheory
anstelle von verwendenMath::Prime::Util
. Auch sollte}{
statt;$_=""
in Ordnung sein. Und Sie können das Leerzeichen nach1
und die Klammer einiger Funktionsaufrufe weglassen . Funktioniert auch&
statt&&
. Das sollte 88 Bytes ergeben:perl -Mntheory=:all -lpe '1until!is_provable_prime(++$\)&is_strong_pseudoprime$\,2..nth_prime$_}{'
}{
. (Seltsamerweise erinnerte ich mich an die Sache mit den Klammern, aber es ist schon eine Weile her, seit ich in Perl Golf gespielt habe und konnte mich nicht mehr an die Regeln erinnern, nach denen ich sie ausgelassen hatte.) Ich wusste überhaupt nichts über dientheory
Abkürzung.