Python, 76 73 67 octets
f=lambda n,k=1:1-any(a**-~k*~-a**k%n for a in range(n))or-~f(n,k+1)
Essayez-le en ligne!
Un autre octet peut être sauvegardé en retournant True au lieu de 1 .
Mise en œuvre alternative
En utilisant la même approche, il y a aussi l'implémentation suivante de @feersum qui n'utilise pas les compréhensions de liste.
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)
Notez que cette implémentation nécessite O (n λ (n) ) temps. L'efficacité pourrait être considérablement améliorée tout en réduisant le score à 66 octets , mais la fonction renverrait True pour l'entrée 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)
Contexte
Définitions et notation
Toutes les variables employées désigneront des entiers; n , k et α désigneront des entiers positifs ; et p désignera un nombre premier positif .
a | b si b est divisible par a , c'est-à-dire s'il y a q tel que b = qa .
a ≡ b ( mod m) si a et b ont le même résidu modulo m , c'est-à-dire si m | a - b .
λ (n) est le plus petit k tel que a k ≡ 1 ( mod n) - c'est-à-dire tel que n | a k - 1 - pour tous les a qui sont coprimes à n .
f (n) est le plus petit k tel que a 2k + 1 ≡ a k + 1 ( mod n) - c'est-à-dire tel que n | a k + 1 (a k - 1) - pour tous a .
λ (n) ≤ f (n)
Fixez n et laissez a être coprime à n .
Par la définition de f , n | a f (n) +1 (a f (n) - 1) . Depuis un et n n'ont pas un facteur premier commun, non plus un f (n) 1 et n , ce qui implique que n | a f (n) - 1 .
Puisque λ (n) est le plus petit entier k tel que n | a k - 1 pour tous les entiers a qui ont la priorité pour n , il en résulte que λ (n) ≤ f (n) .
λ (n) = f (n)
Puisque nous avons déjà établi l'inégalité λ (n) ≤ f (n) , il suffit de vérifier que k = λ (n) vérifie la condition qui définit f , c'est-à-dire que n | a λ (n) +1 (a λ (n) - 1) pour tout a . Pour cela, nous allons établir que p α | a λ (n) +1 (a λ (n) - 1) chaque fois que p α | n .
λ (k) | λ (n) chaque fois que k | n ( source ), donc (a λ (k) - 1) (a λ (n) -λ (k) + a λ (n) -2λ (k) + ⋯ + a λ (k) + 1) = a λ (n) - 1 et donc un λ (k) - 1 | a λ (n) - 1 | a λ (n) +1 (a λ (n) - 1) .
Si a et p α sont coprimes, par la définition de λ et celle ci-dessus, p α | a λ (p α ) - 1 | Un λ (n) +1 (un λ (n) - 1) suit, comme vous le souhaitez.
Si a = 0 , alors un λ (n) 1 (a λ (n) - 1) = 0 , ce qui est divisible par tous les nombres entiers.
Enfin, nous devons considérer le cas où a et p α ont un facteur premier commun. Puisque p est premier, cela implique que p | a . Le théorème de Carmichael établit que λ (p α ) = (p - 1) p α - 1 si p> 2 ou α <3 et que λ (p α ) = p α - 2 sinon. Dans tous les cas, λ (p α ) ≥ p α - 2 ≥ 2 α - 2 > α - 2 .
Par conséquent, λ (n) + 1 ≥ λ (p α ) + 1> α - 1 , donc λ (n) + 1 ≥ α et p α | p λ (n) +1 | a λ (n) +1 | a λ (n) +1 (a λ (n) - 1) . Ceci complète la preuve.
Comment ça marche
Alors que les définitions de f (n) et λ (n) considèrent toutes les valeurs possibles de a , il suffit de tester celles qui se trouvent dans [0, ..., n - 1] .
Lorsque f (n, k) est appelé, il calcule un k + 1 (a k - 1)% n pour toutes les valeurs de a dans cette plage, qui est 0 si et seulement si n | a k + 1 (a k - 1) .
Si tous les résidus calculés sont zéro, k = λ (n) et any
renvoie False , donc f (n, k) renvoie 1 .
D'autre part, alors que k <λ (n) , 1-any(...)
retournera 0 , f est appelé de manière récursive avec une valeur incrémentée de k . Le premier -~
incrémente la valeur de retour de f (n, k + 1) , nous ajoutons donc 1 à f (n, λ (n)) = 1 une fois pour chaque entier de [1, ..., λ (n) - 1 ] . Le résultat final est donc λ (n) .