Пітон, 76 73 67 байт
f=lambda n,k=1:1-any(a**-~k*~-a**k%n for a in range(n))or-~f(n,k+1)
Спробуйте в Інтернеті!
Подальший байт можна зберегти, повернувши True замість 1 .
Альтернативна реалізація
Використовуючи той самий підхід, є також наступна реалізація від @feersum, яка не використовує розуміння списку.
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)
Зауважте, що для цієї реалізації потрібен час O (n λ (n) ) . Ефективність може бути значно покращена, фактично зменшивши бал до 66 байт , але функція поверне значення True для введення 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)
Фон
Визначення та позначення
Всі використані змінні будуть позначати цілі числа; n , k і α позначатимуть додатні цілі числа; і p позначатиме позитивний простим розрядом .
а | b, якщо b ділиться на a , тобто якщо є q такий, що b = qa .
a ≡ b ( mod m), якщо a і b мають однаковий модуль залишку m , тобто, якщо m | а - б .
λ (n) - найменший k такий, що a k ≡ 1 ( mod n) - тобто такий, що n | a k - 1 - для всіх a, що є спільними з n .
е (п) є найменшим до таким чином, що 2k + 1 ≡ до + 1 ( по модулю п) - тобто такі , що п | a k + 1 (a k - 1) - для всіх a .
λ (n) ≤ f (n)
Виправте n і нехай a coprime to n .
За визначенням f , n | a f (n) +1 (a f (n) - 1) . Оскільки і п не мають загального прем'єр - фактор, не займайтеся в п (п) +1 і п , звідки слід , що п | a f (n) - 1 .
Оскільки λ (n) - найменше ціле число k таке, що n | a k - 1 для всіх цілих чисел a, які є спільними з n , випливає, що λ (n) ≤ f (n) .
λ (n) = f (n)
Оскільки ми вже встановили нерівність λ (n) ≤ f (n) , достатньо перевірити, чи відповідає k = λ (n) умові, що визначає f , тобто, що n | a λ (n) +1 (a λ (n) - 1) для всіх a . Для цього встановимо, що p α | a λ (n) +1 (a λ (n) - 1), коли p α | н .
λ (k) | λ (n) всякий раз, коли k | n ( джерело ), так (a λ (k) - 1) (a λ (n) -λ (k) + a λ (n) -2λ (k) + ⋯ + a λ (k) + 1) = a λ (n) - 1 і, отже, a λ (k) - 1 | a λ (n) - 1 | a λ (n) +1 (a λ (n) - 1) .
Якщо a і p α є спірними, за визначенням λ і вищевикладеним, p α | a λ (p α ) - 1 | a λ (n) +1 (a λ (n) - 1) слідує за бажанням.
Якщо a = 0 , то a λ (n) +1 (a λ (n) - 1) = 0 , що ділиться на всі цілі числа.
Нарешті, ми повинні розглянути випадок, коли a і p α мають спільний простий фактор. Оскільки p є простим, це означає, що p | а . Теорема Карміхеля встановлює, що λ (p α ) = (p - 1) p α - 1, якщо p> 2 або α <3, а λ (p α ) = p α - 2 в іншому випадку. У всіх випадках λ (p α ) ≥ p α - 2 ≥ 2 α - 2 > α - 2 .
Тому λ (n) + 1 ≥ λ (p α ) + 1> α - 1 , тому λ (n) + 1 ≥ α і p α | p λ (n) +1 | a λ (n) +1 | a λ (n) +1 (a λ (n) - 1) . Це завершує доказ.
Як це працює
Хоча визначення f (n) та λ (n) враховують усі можливі значення a , достатньо перевірити ті, що лежать у [0, ..., n - 1] .
Коли f (n, k) викликається, він обчислює a k + 1 (a k - 1)% n для всіх значень a в цьому діапазоні, що дорівнює 0, якщо і лише тоді, коли n | a k + 1 (a k - 1) .
Якщо всі обчислені залишки дорівнюють нулю, k = λ (n) і any
повертає False , значить f (n, k) повертає 1 .
З іншого боку, в той час як до <λ (п) , 1-any(...)
буде повертати 0 , тому е викликається рекурсивно з порядковим значенням до . Провідні -~
прирости повертають значення f (n, k + 1) , тому ми додаємо 1 до f (n, λ (n)) = 1 раз на кожне ціле число в [1, ..., λ (n) - 1 ] . Кінцевий результат, таким чином, λ (n) .