Python, 76 73 67 byte
f=lambda n,k=1:1-any(a**-~k*~-a**k%n for a in range(n))or-~f(n,k+1)
Provalo online!
È possibile salvare un ulteriore byte restituendo True anziché 1 .
Implementazione alternativa
Utilizzando lo stesso approccio, vi è anche la seguente implementazione di @feersum che non utilizza la comprensione dell'elenco.
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)
Questa implementazione richiede tempo O (n λ (n) ) . L'efficienza potrebbe essere notevolmente migliorata, riducendo in realtà il punteggio a 66 byte , ma la funzione restituirà True per l'ingresso 2 .
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)
sfondo
Definizioni e notazione
Tutte le variabili impiegate indicheranno numeri interi; n , k e α denoteranno numeri interi positivi ; e p indicherà un numero primo positivo .
a | b se b è divisibile per a , cioè se esiste q tale che b = qa .
a ≡ b ( mod m) se un e b hanno lo stesso residuo modulo m , cioè, se m | a - b .
λ (n) è il più piccolo k tale che a k ≡ 1 ( mod n) - cioè, tale che n | a k - 1 - per tutti a che sono coprime a n .
f (n) è il più piccolo k tale che un 2k + 1 ≡ a k + 1 ( mod n) - cioè, tale che n | a k + 1 (a k - 1) - per tutti a .
λ (n) ≤ f (n)
Fix n e lasciare un coprimi be a n .
Dalla definizione di f , n | a f (n) +1 (a f (n) - 1) . Poiché a e n non hanno un fattore primo comune, né a f (n) +1 e n , il che implica che n | a f (n) - 1 .
Poiché λ (n) è il numero intero più piccolo k tale che n | un k - 1 per tutti gli interi a che sono primi con n , segue che λ (n) ≤ f (n) .
λ (n) = f (n)
Poiché abbiamo già stabilito la disuguaglianza λ (n) ≤ f (n) , è sufficiente verificare che k = λ (n) soddisfi la condizione che definisce f , cioè che n | a λ (n) +1 (a λ (n) - 1) per tutti a . A tal fine, stabiliremo che p α | a λ (n) +1 (a λ (n) - 1) ogni volta che p α | n .
λ (k) | λ (n) ogni volta che k | n ( sorgente ), quindi (a λ (k) - 1) (a λ (n) -λ (k) + a λ (n) -2λ (k) + ⋯ + a λ (k) + 1) = a λ (n) - 1 e, quindi, a λ (k) - 1 | a λ (n) - 1 | a λ (n) +1 (a λ (n) - 1) .
Se a e p α sono coprimi, con la definizione di λ e sopra, p α | a λ (p α ) - 1 | a λ (n) +1 (a λ (n) - 1) segue, come desiderato.
Se a = 0 , allora a λ (n) +1 (a λ (n) - 1) = 0 , che è divisibile per tutti i numeri interi.
Infine, dobbiamo considerare il caso in cui a e p α hanno un fattore primo comune. Poiché p è primo, questo implica che p | a . Il teorema di Carmichael stabilisce che λ (p α ) = (p - 1) p α - 1 se p> 2 o α <3 e che λ (p α ) = p α - 2 altrimenti. In tutti i casi, λ (p α ) ≥ p α - 2 ≥ 2 α - 2 > α - 2 .
Pertanto, λ (n) + 1 ≥ λ (p α ) + 1> α - 1 , quindi λ (n) + 1 ≥ α e p α | p λ (n) +1 | a λ (n) +1 | a λ (n) +1 (a λ (n) - 1) . Questo completa la prova.
Come funziona
Mentre le definizioni di f (n) e λ (n) considerano tutti i possibili valori di a , è sufficiente testare quelli che si trovano in [0, ..., n - 1] .
Quando viene chiamato f (n, k) , calcola un k + 1 (a k - 1)% n per tutti i valori di a in quell'intervallo, che è 0 se e solo se n | a k + 1 (a k - 1) .
Se tutti i residui calcolati sono zero, k = λ (n) e any
restituisce False , quindi f (n, k) restituisce 1 .
D'altra parte, mentre k <λ (n) , 1-any(...)
restituirà 0 , quindi f viene chiamato ricorsivamente con un valore incrementato di k . Il principale -~
incrementa il valore di ritorno di f (n, k + 1) , quindi aggiungiamo 1 a f (n, λ (n)) = 1 una volta per ogni numero intero in [1, ..., λ (n) - 1 ] . Il risultato finale è quindi λ (n) .