Einleitung / Hintergrund
In einer kürzlichen Diskussion im Krypto-Chat wurde ich aufgefordert, mit dem Fermat-Primalitätstest und den Carmichael-Zahlen zu diskutieren / zu helfen . Dieser Test basiert auf der Prämisse, dass a^(p-1) mod p==1
immer für Primzahlen gilt p
, aber nicht immer für Verbundwerkstoffe. Jetzt ist eine Carmichael-Zahl im Wesentlichen der schlimmste Feind des Fermat-Tests: Eine Zahl, für die Sie sich entscheiden müssen, um a
nicht mit ihnen p
zu koprimieren, um sie zu erhalten a^(p-1) mod p!=1
. Wenn dies a
nicht Co-Prime ist, haben Sie im Wesentlichen einen nicht trivialen Faktor von gefundenp
und wie wir alle wissen, kann Factoring ziemlich schwierig sein. Besonders wenn alle Faktoren ausreichend groß sind. Sie werden jetzt vielleicht feststellen, warum der Fermat-Test in der Praxis nicht so oft verwendet wird (nun, es gibt bessere Algorithmen), weil es Zahlen gibt, für die Sie als Verteidiger (in Bezug auf die Sicherheit) ähnlich viel Arbeit leisten müssten wie ein Angreifer (nämlich Faktor die Zahl).
Jetzt, da wir wissen, warum diese Zahlen etwas faszinierend sind, werden wir sie so schnell wie möglich generieren, sodass wir uns den generierenden Code einfach merken können, wenn wir jemals einen brauchen!
Carmichael-Nummern werden in OEIS auch als A002997 bezeichnet .
Es gibt bereits eine damit verbundene Herausforderung , aber die Einträge von dort sind hier nicht wettbewerbsfähig, da sie im Gegensatz zur Größe auf Geschwindigkeit optimiert sind. Das gleiche Argument gilt für die umgekehrte Richtung. Einträge hier machen wahrscheinlich Kompromisse gegen die Geschwindigkeit zugunsten der Größe.
Spezifikation
Eingang
Dies ist eine Standardsequenz Herausforderung, so dass Sie eine positive oder nicht negative ganze Zahl nehmen n
als Eingabe. n
kann je nach Wunsch 0- oder 1-indiziert sein (bitte angeben).
Ausgabe
Ihre Ausgabe ist entweder die n
-te Carmichael-Nummer oder die erste n
Carmichael-Nummer, wie Sie es bevorzugen (bitte angeben).
Spezifikation
Eine ganze Zahl x
ist genau dann eine Carmichael-Zahl, wenn sie zusammengesetzt x
ist und für alle ganzen Zahlen y
mit gcd(x,y)=1
gilt y^(x-1) mod x==1
.
Wer gewinnt?
Dies ist Code-Golf , also gewinnt der kürzeste Code im Byte!
Es gelten die Standardregeln für E / A und Lücken.
Testfälle
Die ersten Carmichael-Zahlen sind:
561,1105,1729,2465,2821,6601,8911,10585,15841,
29341,41041,46657,52633,62745,63973,75361,101101,
115921,126217,162401,172081,188461,252601,278545,
294409,314821,334153,340561,399001,410041,449065,
488881,512461
quelle
Python 2 , 92 Bytes
Probieren Sie es online aus!
1-indexiert und langsam wie Melasse.
Im Listenverständnis verwende ich Dennis 'Methode, um alle Ganzzahlen zu
n
generieren , die gleichzeitig kopiert werden ( ns Summen ), und berechne dannx**~-n%n
für alle. Nennen wir diese ListeL
.Um eine Carmichael-Nummer zu ermitteln, vergleiche ich diese Liste lexikografisch mit einer Liste, die aus
n-1
Einsen besteht. Warum funktioniert das?Jedes Element von
L
ist eine positive ganze Zahl:(k/n)
ist Koprime zun
, so(k/n)**~-n
ist es auch, so(k/n)**~-n%n > 0
. Somit sind die einzig möglichen Werte davonL
lexikographisch kleiner als[1]*(n-1)
diejenigen, die vollständig aus weniger alsn-1
Eins bestehen. (L
Kann nicht mehr alsn-1
Werte enthalten, dan
es nicht mehr alsn-1
Summen geben kann! Vergleiche wie[1,1,1,1,3] < [1,1,1,1]
sind also out.)Wenn Sie überprüfen, ob weniger als
n-1
Einträge vorhanden sindL
,n
wird sichergestellt, dass diese zusammengesetzt sind. (n-1
Totative zu haben ist eine äquivalente Bedingung zur Primalität.) Und dann ist die Bedingung, eine Carmichael-Zahl zu sein, genau, dass jedes ElementL
gleich ist1
. Dieser lexikografische Vergleich erkennt also genau dieL
s, an denen wir interessiert sind.Mr. Xcoder sparte ein Byte, indem er zur rekursiven Lambda-Form wechselte:
j
Zählt jedes Mal herunter, wenn wir eine Carmichael-Zahl treffen, undn
zählt jedes Mal hoch, wenn wir wiederkehren. Sobald alsoj
Null erreicht ist,n-1
entspricht dies deroriginal_value_of_j
'ten Carmichael-Zahl.quelle
Gelee ,
1211 Bytes-1 Byte dank Meilen & Mr. Xcoder (Verwendung des Carmichael-Funktionsatoms & eines Golfs davon)
Eine monadische Verbindung,
n
die eine Liste der erstenn
Carmichael-Nummern aufnimmt und zurückgibt.Probieren Sie es online aus!
Wie?
Ähnlich wie im vorherigen (unten), mit der Ausnahme, dass für die Carmichael-Funktion eine Funktion integriert ist, die die kleinste Potenz liefert, sodass der auf diese Potenz angehobene Eingang zu einem Modulo kongruent ist, das für alle ganzen Zahlen mit dieser ganzen Zahl übereinstimmt. Somit können wir die falsch-positiven (Primzahlen) in weniger Bytes ausschließen und haben schnelleren Code!
Vorherige 12 Bytes :
Probieren Sie es online aus! (Ja, es läuft ab
n=3
).Wie?
Eine Zahl
c
ist eine Carmichael-Zahl, wenn sie zusammengesetzt ist, und es ist wahr, dass jede ganze Zahlx
, die auf angehobenc
wird, mitx
Modulo kongruent istc
.Wir müssen dies nur für positive überprüfen
x
bis zux=c
sich selbst.Beachten Sie auch, dass bei
x=c
der Prüfung geprüft wird, ob diex
Erhöhung auf die Potenz vonx
zux
Modulo kongruent istx
, was wahr ist - wir müssen dies also nicht überprüfen (dies führt zu kürzerem Code).quelle
ECMAScript Regex,
8689 BytesWarnung: Lesen Sie dies nicht, wenn Sie nicht möchten, dass unäre Regex-Magie für Sie verwöhnt wird. Wenn Sie versuchen möchten, diese Magie selbst herauszufinden, empfehle ich dringend, zunächst einige Probleme in ECMAScript-Regex zu lösen : In diesem früheren Beitrag finden Sie eine Liste der nacheinander mit Spoiler-Tags versehenen empfohlenen Probleme, die nacheinander gelöst werden können.
^(?!(x(x+))(?!\2*$)\1*(?=\1$)(?!(xx+)\3+$))((?=(xx+?)\5*$)(?=(x+)(\6+$))\7(?!\5*$)){2,}x$
Probieren Sie es online aus!
Die Hauptmagie dieses regulären Ausdrucks liegt in dem Teil, der behauptet, dass alle Primfaktoren von N von genau einer Multiplizität sind. Es ist der gleiche Trick wie bei meinen Match-Strings, deren Länge eine vierte Potenz ist, und bei der Suche nach den glattesten Zahlen-Regexen: wiederholte implizite Division durch den kleinsten Primfaktor.
Es ist auch möglich, direkt zu testen, dass N keine perfekten Quadratfaktoren hat (dh dass N quadratfrei ist). Dies verwendet eine Variante des Multiplikationsalgorithmus, der kurz in einem Absatz meines Regex-Beitrags mit zahlreichen Zahlen beschrieben wird , um zu testen, ob eine Zahl ein perfektes Quadrat ist. Das ist ein Spoiler . So lesen keine weiteren , wenn Sie nicht einige erweiterte einstellige regex Magie für Sie verwöhnen wollen . Wenn Sie versuchen möchten, diese Magie selbst herauszufinden, empfehle ich dringend, zunächst einige Probleme in der Liste der empfohlenen Probleme mit fortlaufenden Spoiler-Tags in diesem früheren Beitrag zu lösen und zu versuchen, die mathematischen Erkenntnisse unabhängig voneinander zu entwickeln.
Die Verwendung dieses Algorithmus für dieses Problem bietet jedoch keinen Vorteil. Dies führt zu einem langsameren regulären Ausdruck mit einer größeren Größe von 97 Bytes. Ohne den Primmultiplizitätstest (der in einer Schleife sowohl bestätigt, dass es mindestens 2 Primfaktoren gibt als auch dass es sich jeweils um eine einzelne Multiplizität handelt) müssen wir separat behaupten, dass N zusammengesetzt ist.
Probieren Sie es online aus!
quelle
decision-problem
Antwort, aber die Herausforderung ist einesequence
Herausforderung.) Vermutlich gibt es in einer leistungsstärkeren Regex-Variante einen direkteren Test für quadratische Teiler?^(?!(x(x+))(?!\2*$)\1*(?=\1$)(?!(xx+)\3+$)|((^x|xx\5){2,})\4*$)(xx+)\6+$
72 Byte Golf spielen können .J ,
725951 BytesProbieren Sie es online aus!
quelle
Netzhaut , 94 Bytes
Probieren Sie es online aus! 1-indiziert. Nicht schnell, daher tritt
n>5
bei TIO eine Auszeit auf. Erläuterung:Erhöhen Sie den aktuellen Wert. Beim ersten Durchgang wird dies ebenfalls
n
aus dem Ausgabepuffer gelöscht ($+
kann aber trotzdem darauf zugreifen).Testen Sie, ob der aktuelle Wert eine Carmichael-Zahl ist. Dies verwendet den alternativen Algorithmus von @ Deadcode, da die Quadraterkennung beim Schreiben mit .NET / Perl / PCRE-Regex kürzer ist.
Wiederholen, bis der aktuelle Wert eine Carmichael-Zahl ist.
Erhöhen Sie den aktuellen Wert.
Wiederholen Sie das anfängliche Inkrement und die darüber liegenden Schleifenzeiten
n
.Konvertieren Sie das Ergebnis in eine Dezimalzahl.
quelle
Haskell , 95 Bytes
Probieren Sie es online aus!
Degolfed:
quelle