Python, 76 73 67 Bytes
f=lambda n,k=1:1-any(a**-~k*~-a**k%n for a in range(n))or-~f(n,k+1)
Probieren Sie es online!
Ein weiteres Byte könnte durch Rückgabe von True anstelle von 1 gespeichert werden .
Alternative Implementierung
Mit dem gleichen Ansatz gibt es auch die folgende Implementierung von @feersum, die keine Listenverständnisse verwendet.
f=lambda n,k=1,a=1:a/n or(a**-~k*~-a**k%n<1)*f(n,k,a+1)or-~f(n,k+1)
Es ist zu beachten, dass diese Implementierung eine O (n & lgr; (n) ) - Zeit erfordert . Die Effizienz könnte drastisch verbessert werden, während der Score tatsächlich auf 66 Bytes verringert wird , aber die Funktion würde True für Eingabe 2 zurückgeben .
f=lambda n,k=1,a=1:a/n or~-a**k*a**-~k%n<1==f(n,k,a+1)or-~f(n,k+1)
Hintergrund
Definitionen und Notation
Alle verwendeten Variablen bezeichnen ganze Zahlen. n , k und α bezeichnen positive ganze Zahlen; und p bezeichnet eine positive Primzahl .
a | b wenn b durch a teilbar ist , dh wenn q so ist, dass b = qa .
a ≡ b ( mod m) wenn a und b den gleichen Rest modulo m haben , dh wenn m | a - b .
λ (n) ist das kleinste k, so dass a k ≡ 1 ( mod n) - dh so, dass n | a k - 1 - für alle a , die koprime zu n sind .
f (n) ist das kleinste k, so dass a 2k + 1 ≤ a k + 1 ( mod n) - dh so, dass n | a k + 1 (a k - 1) - für alle a .
λ (n) ≤ f (n)
Fixiere n und lasse a zu n koprimieren .
Nach der Definition von f , n | a f (n) + 1 (a f (n) - 1) . Da ein und n keinen gemeinsamen Primfaktor hat, auch nicht ein f (n) + 1 und n , die das bedeutet , n | a f (n) - 1 .
Da λ (n) die kleinste ganze Zahl k ist, so dass n | a k - 1 für alle ganzen Zahlen a , die zu n koprime sind , folgt λ (n) ≤ f (n) .
λ (n) = f (n)
Da wir bereits die Ungleichung λ (n) ≤ f (n) festgestellt haben, reicht es aus, zu überprüfen, dass k = λ (n) die Bedingung erfüllt, die f definiert , dh dass n | a λ (n) +1 (a λ (n) - 1) für alle a . Zu diesem Zweck legen wir fest, dass p α | eine λ (n) + 1 (a λ (n) - 1) , wenn p & agr; | n .
λ (k) | λ (n) wann immer k | n ( Quelle ), also (a & lgr; (k) - 1) (a & lgr; (n) - & lgr; (k) + a & lgr; (n) - 2 & lgr; (k) + & lgr; + a & lgr; (k) + 1) = a λ (n) - 1 und daher a λ (k) - 1 | a λ (n) - 1 | eine λ (n) + 1 (a λ (n) - 1) .
Wenn a und p α Coprime sind, ist nach der Definition von λ und dem oben Gesagten p α | a λ ( pα ) - 1 | eine λ (n) + 1 (a λ (n) - 1) folgt, wie gewünscht.
Wenn a = 0 , dann ist a λ (n) + 1 (a λ (n) - 1) = 0 , was durch alle ganzen Zahlen teilbar ist.
Schließlich müssen wir den Fall betrachten, in dem a und p α einen gemeinsamen Primfaktor haben. Da p eine Primzahl ist, impliziert dies, dass p | a . Carmichaels Theorem legt fest, dass λ ( pα ) = (p - 1) pα - 1, wenn p> 2 oder α <3, und dass λ ( pα ) = pα - 2, wenn nicht. In allen Fällen ist λ ( pα ) ≥ pα - 2 ≥ 2α - 2 > α - 2 .
Daher ist & lgr; (n) + 1 ≥ & lgr; (p & agr; ) + 1> & agr; - 1 , so dass & lgr; (n) + 1 ≥ & agr; und p & agr; | p λ (n) +1 | a λ (n) +1 | eine λ (n) + 1 (a λ (n) - 1) . Damit ist der Beweis abgeschlossen.
Wie es funktioniert
Während die Definitionen von f (n) und λ (n) alle möglichen Werte von a berücksichtigen , ist es ausreichend, diejenigen zu testen, die in [0, ..., n - 1] liegen .
Wenn f (n, k) aufgerufen wird, berechnet es ein k + 1 (a k - 1)% n für alle Werte von a in diesem Bereich, der genau dann 0 ist, wenn n | a k + 1 (a k - 1) .
Wenn alle berechneten Reste gleich null sind, k = λ (n) und any
kehrt Falsch , so f (n, k) liefert 1 .
Wenn andererseits k <λ (n) ist , 1-any(...)
wird 0 zurückgegeben , so dass f rekursiv mit einem inkrementierten Wert von k aufgerufen wird . Der führende -~
erhöht den Rückgabewert von f (n, k + 1) , also addieren wir 1 zu f (n, λ (n)) = 1 einmal für jede ganze Zahl in [1, ..., λ (n) - 1 ] . Das Endergebnis ist somit λ (n) .