Python、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)
オンラインでお試しください!
さらにバイトを返すことによって保存することができた真の代わりに、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バイトに減らしながら効率を劇的に改善できますが、関数は入力2に対してTrueを返します。
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はで割り切れるがある場合、すなわち、QなるようにB = QA。
≡B(モッズメートル)場合とbが同じ残基モジュロ持ってメートルを場合、すなわち、M | a-b。
λ(n)が最小となるKのようにK ≡1(MOD N) -すなわち、例えばそのN | a k -1 – nと互いに素であるすべての a に対して。
F(n)が最小となるKよう2K + 1 ≡ K + 1(MOD N) -すなわち、例えばそのN | a k + 1(a k -1) –すべてのaに対して。
λ(n)≤f(n)
nを修正し、 aをnと互いに素にします。
fの定義により、n | a f(n)+1(a f(n) -1)。以来およびnは、共通の素因数を持たないでもないんF(n)は1をとnはその意味、| nは a f(n) -1。
以来、λ(n)が最小の整数であり、kのようにN | a k -1nと互いに素であるすべての整数aについてため、λ(n)≤f(n)となります。
λ(n)= f(n)
不等式λ(n)≤f(n)をすでに確立しているので、k =λ(n)がfを定義する条件、つまりn | λ(N)+1(λ(N) - 1)すべてのため。この目的のために、私たちはその確立うp個のαを | λ(N)+1(λ(N) - 1)たびにp個のα | n個。
λ(k)| λ(n)は常にk | N(ソース)ので、(λ(k) - 1)(λ(N)-λ(K) + λ(N)-2λ(K) +⋯+ λ(K) + 1)= A λ(n)を - 1と、従って、λ(k) - 1 | λ(n)を - 1 | λ(N)+1(λ(N) - 1) 。
もしおよびP αの定義により、互いに素λ以上、p個のα | λ(p個のα) - 1 | 必要に応じて、aλ(n)+1(aλ(n) -1)が続きます。
もし= 0、次いで、λ(N)+1(λ(N) - 1)= 0、全ての整数で割り切れます。
最後に、我々は、ケース検討しなければならないとpはα、共通の素因数を持っています。pは素数なので、これはp | A。カーマイケルの定理は、p> 2またはα<3の場合はλ(pα)=(p-1)pα-1、それ以外の場合はλ(pα)= pα-2であることを確立します。すべての場合において、λ(pα)≥p - 2≥2α -2 >α-2です。
したがって、λ(N)+ 1≥λ(P α)+ 1>α - 1、そうλ(N)+ 1≥α及びP α | P λ(n)を+1 | λ(n)を+1 | aλ(N)+1(λ(N) - 1) 。これで証明が完了しました。
使い方
f(n)とλ(n)の定義はaのすべての可能な値を考慮しますが、[0、...、n-1]にある値をテストすれば十分です。
場合fは(N、k)が呼び出され、それは計算K + 1(K - 1)%Nの全ての値のためである範囲で0を場合にのみN | a k + 1(a k -1)。
計算されたすべての剰余がゼロの場合、k =λ(n)でFalseをany
返すため、f(n、k)は1を返します。
一方、k <λ(n)の場合1-any(...)
は0が返されるため、fはkの増分値で再帰的に呼び出されます。主要-~
インクリメントの戻り値F(N、K + 1) 、我々は追加そう1にF(N、λ(N))= 1回ですべての整数のための[1、...、λ(N) - 1 ]。したがって、最終結果はλ(n)です。