モジュラー逆数の計算


16

2つの正の数xとnwithが与えられたx<2^n場合、計算する最短の関数を記述しx^-1 mod 2^nます。言い換えれば、yそのようなことを見つけますx*y=1 mod 2^n。

少なくともの間n=64、関数は妥当な時間内に完了する必要があるため、完全な検索は機能しません。

逆が存在しない場合は、何らかの方法で呼び出し元にそれを示す必要があります(例外をスローする、センチネル値を返すなど)。

どこから始めたらよいかわからない場合は、拡張ユークリッドアルゴリズムを試してください。


これは、いくつかの数学ソフトウェアで単一のステートメントになるだろう
— st0le

1
@ st0le:そうです、そのようなシステムでそのような関数を使用することは許可されません。:-D
— クリスジェスターヤング

回答:


2

Python 95 89

cあなたの機能です。逆関数がない場合(つまり、xが偶数の場合)、0を返します。

p=lambda x,y,m:y and p(x,y/2,m)**2*x**(y&1)%m or 1
c=lambda x,n:[0,p(x,2**n-1,2**n)][x%2]

3

Python、29バイト

lambda x,n:pow(x,2**n-1,2**n)

これは、偶数xに対して 0を返します。オイラーの定理を使用し、2 ^ n − 1は2 ^(n − 1)− 1で割り切れるという観測をPythonの組み込み高速モジュラーべき乗法を使用して行います。これはnから7000程度まで十分に高速で、約1秒以上かかります。


2

Mathematica-22

f=PowerMod[#,-1,2^#2]&

f[x,n]返すyとx*y=1 mod 2^nそうでない場合は、x is not invertible modulo 2^n


2

GolfScript(23文字)

{:^((1${\.**2^?%}+*}:f;

存在しないインバースのセンチネル結果は0です。

これはオイラーの定理の簡単な応用です。ので、 X - 1 ≡ X 2 N - 1 - 1バツφ(2n)≡1(モッド2n)バツ−1≡バツ2n−1−1(モッド2n)

残念ながら、直接計算するには指数が大きすぎるため、ループを使用し、ループ内でモジュラーリダクションを行う必要があります。反復工程である、我々は、基本ケースの選択肢がありますのいずれかを有しますバツ2k−1=(バツ2k−1−1)2×バツk=1

{1\:^(@{\.**2^?%}+*}:f;

またはk=2で

{:^((1${\.**2^?%}+*}:f;

私は別のアプローチに取り組んでいますが、センチネルはもっと難しいです。

キーの観測は、私たちが少しずつアップ逆を構築することができるということです。場合はバツy≡1(モッド2k−1)バツy∈{1、1+2k−1}(モッド2k)バツバツ(y+バツy−1)≡1(モッド2k)y′=(x+1)y−1

0x≡1(mod20)

x(1−(x+1)nx)≡1(mod2n)

x+1

それは19文字の機能を提供します

{1$)1$?@/~)2@?%}:f;

xx&11

{1$.1&+1$?@/~)2@?%}:f;

02n−1

01−(x+1)n1−1n

{1$.1&*)1$?@/~)2@?%}:f;

nn x f

{..1&*)2$?\/~)2@?%}:f;

1

ルビー-88文字

関数を使用しますf。

def e a,b;a%b==0?[0,1]:(x,y=e(b,a%b);[y,x-(y*(a/b))])end
def f x,n;e(x,2**n)[0]*(x%2)end

リンクされたWikiページの単純な再帰関数は、エラー時に0を返します。


e:をインライン化すると、一部の文字を保存できます(e=->a,b{...})[x,2**n][0]。のa%b<1代わりにテストすることでキャラクターを保存することもできますa%b==0。
— 歴史家


1

パイス、9バイト

.^Et^2Q^2

ここで試してみてください!

入力を逆順に取得します。または、9バイトも:.^EtK^2QK。

説明

。^ Et ^ 2Q ^ 2-完全なプログラム。

。^-パウ関数。Python(パウ)でも同じです。
  E-2番目の入力。
    ^ 2Q-そして2 ^最初の入力。
   t-減少しました。
       ^ 2-そして2 ^最初の再入力。

0

GAP、39バイト

f:=function(x,n)return 1/x mod 2^n;end;

f(x,n)xモジュロの逆数を返し、2^nエラーメッセージを返します

Error, ModRat: for <r>/<s> mod <n>, <s>/gcd(<r>,<s>) and <n> must be coprime

逆が存在しない場合。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.