モジュラ乗法逆


22

あなたの仕事は、2つの整数を与え、モジュロbのモジュラ乗法逆関数が存在する場合、それab計算することです。

aモジュロのモジュラー逆数bは、cそのような数ですac ≡ 1 (mod b)。この番号はbaとの任意のペアに対して一意のモジュロですb。それが唯一の最大公約数場合が存在aしてbいます1

トピックに関する詳細情報が必要な場合は、モジュラー乗法的逆関数のWikipediaページ参照してください

入出力

入力は、2つの整数または2つの整数のリストとして与えられます。プログラムは、単一の数、区間内にあるモジュラー乗法逆数0 < c < b、または逆数がないことを示す値のいずれかを出力する必要があります。値は、範囲内の数値を除く任意の値にすることができ(0,b)、例外でもあります。ただし、値は逆行列がない場合と同じである必要があります。

0 < a < b 想定できる

ルール

  • プログラムはある時点で終了し、各テストケースを60秒未満で解決する必要があります
  • 標準的な抜け穴が適用されます

テストケース

以下のテストケースは次の形式で提供されます。 a, b -> output

1, 2 -> 1
3, 6 -> Does not exist
7, 87 -> 25
25, 87 -> 7
2, 91 -> 46
13, 91 -> Does not exist
19, 1212393831 -> 701912218
31, 73714876143 -> 45180085378
3, 73714876143 -> Does not exist

得点

これはコードゴルフであるため、各言語の最短コードが優先されます。

これこれは似たような質問ですが、両方とも特定の状況を求めます。


6
Fermatのリトル定理から、aの乗法逆数が存在する場合、a ^(phi(b)-1)mod bとして効率的に計算できることがわかります。ここで、phiはオイラーのトーティエント関数です:phi(p0 ^ k0 * p1 ^ k1 * ...)=(p0-1)* p0 ^(k0-1)*(p1-1)* p1 ^(k1-1)* ...コードが短くなるとは言わない:)
ngn

1
@Jenny_mathy通常、追加の入力は許可されていません。
ミスターXcoder

3
総当たり攻撃と思われる6つの回答をカウントし、60秒以内にすべてのテストケースを実行することはほとんどありません(スタックエラーまたはメモリエラーが最初に発生するものもあります)。
Ørjanヨハンセン

1
@ngn:フェルマーのリトル定理(FLT)とオイラーの改良を混同しました。フェルマーはオイラーのファイ関数について知らなかった。さらに、FLTとオイラーの改善は、gcd(a、b)= 1の場合にのみ適用されます。 ^(-1)。a ^(-1)を取得するには、a ^(\ phi(b)-2)mod bを使用します。
エリックタワーズ

1
@EricTowersオイラーの結果です。「gcd(a、b)= 1」について-「もしそれがあれば」と言いました。phi(b)-2について確かですか?
-ngn

回答:


11

Mathematica、14バイト

必須のMathematica ビルトイン

ModularInverse

これは、2つの引数(aおよびb)を取り、mod bの逆関数が存在する場合にそれを返す関数です。そうでない場合は、エラーを返しますModularInverse: a is not invertible modulo b.


7

JavaScript(ES6)、79 73 62 61バイト

false逆行列が存在しない場合に返します。

拡張ユークリッドアルゴリズムを使用して、すべてのテストケースをほぼ瞬時に解決します。

f=(a,b,c=!(n=b),d=1)=>a?f(b%a,a,d,c-(b-b%a)/a*d):b<2&&(c+n)%n

テストケース


f(c、a、b = 0、d = 1、n = a)=> c?f(a%c、c、d、b-(のように関数fの名前を書くことができないのはなぜですかaa%c)/ c * d、n):a <2 &&(b + n)%n?
RosLuP

@RosLup f(x,y)は、functionキーワードが明示的に先行している場合を除き、常に関数呼び出しとして解析されます。匿名矢印機能は、他の一方で、として宣言されている(x,y)=>somethingf=(x,y)=>somethingに機能を割り当てるf変数。
アーナルド

4

ゼリー、2バイト

æi

オンラインでお試しください!

これは、モジュラー逆関数に組み込み関数を使用し、モジュラー逆関数がない場合に0を返します。

ゼリー、7バイト

R×%⁸’¬T

オンラインでお試しください!

モジュラー逆行列に空のセット(空の文字列として表される)を出力します。最大のテストケースではTIOのメモリが不足しますが、十分なメモリがあれば動作するはずです。

使い方

R×%⁸’¬T  
R        Generate range of b
 ×       Multiply each by a
  %⁸     Mod each by b
    ’    Decrement (Map 1 to 0 and all else to truthy)
     ¬   Logical NOT
      T  Get the index of the truthy element.

より大きなテストケースで作業したい場合は、メモリではなく多くの時間を必要とするこの(比較的手つかずの)バージョンを試してください:

ゼリー、9バイト

×⁴%³’¬ø1#

オンラインでお試しください!

使い方

×⁴%³’¬ø1#
        #   Get the first
      ø1      one integer
            which meets:
×⁴            When multiplied by a
  %³          And modulo-d by b
    ’         Decrement
     ¬        Is falsy

4

Python 2バイト

f=lambda a,b:a==1or-~b*f(-b%a,a)/a

オンラインでお試しください!

与える再帰関数 Trueのためにprint f(1,2)、私は許容できると信じている、と無効な入力のエラー。

私たちは、見つけようとしているバツにおけるaバツ1modb

これは、のように書くことができるX - 1 = K B Kaバツ1=kbk整数です。

取って modaこれは、得られる1kbmoda。マイナスの移動はできますkb1modak

kfbaa

aab

kaバツ1=kbバツkb+1a




3

パイソン251 49 54 53 51 49バイト

officialaimmのおかげで
-1バイトシャギーのおかげで-1バイト

a,b=input()
i=a<2
while(a*i%b-1)*b%a:i+=1
print+i

オンラインでお試しください!

0解決策がない場合に印刷します。


1
出力0のためにa=1b=2、テストケースから、それは出力するはず1です。
シャギー


1
シャギーが指摘したように、失敗しました2, 1
Mr. Xcoder

@Shaggyが機能するようになりました
ロッド

これは、入力に対して(TIOで)60秒で応答を返すことに失敗します31,73714876143
イルマリカロネン

3

Japt9 8バイト

入力を逆順に取得します。-1一致しない場合の出力。大きな整数が大きくなると、処理が終了します。

Ç*V%UÃb1

試して

  • ETHが誤った非常に明白なスペースを指摘してくれたおかげで、1バイト節約されました。

テスト入力73714876143,31は、Firefoxでメモリ不足エラーを生成する(およびChromiumをクラッシュさせる)ようです。これは有効な答えだとは思わない。
イルマリカロネン

@IlmariKaronen:私はソリューションでその事実を明確に指摘しました。コードゴルフの目的で無限のメモリを想定できるため、メモリの問題やクラッシュによってこのソリューションが無効になることはありません。
シャギー

1
残念ながら、メモリの問題により、チャレンジで規定されているように、コードが実際に60秒でテストケースを解決するかどうかを判断することもできません。クラッシュしないように十分なメモリがあったとしても、そうはならないだろうと思いますが、その間プログラムを実際に実行できるコンピュータがなければ、確実に伝える方法はありません。
イルマリカロネン


2

Python 3、49バイト

lambda a,b:[c for c in range(b)if-~c*a%b==1][0]+1

オンラインでお試しください!

Python 3、50バイト

lambda a,b:[c for c in range(1,b+1)if c*a%b==1][0]

オンラインでお試しください!

IndexError: list index out of rangeルールで許可されているため、モジュラー乗法逆行列がない場合にスローされます。


これは31,73714876143、60秒以内に入力の結果を返しません(TIOで)。
イルマリカロネン

@IlmariKaronenは私のマシンで56秒で終了するようです(Macbook Pro '15)
Mr. Xcoder

2

8日、6バイト

コード

invmod

説明

invmoda、moduloの逆の値を計算する8番目の単語ですb。返すnullオーバーフローまたはその他のエラーが発生する。

使用法とテストケース

ok> 1 2 invmod .
1
ok> 3 6 invmod .
null
ok> 7 87 invmod .
25
ok> 25 87 invmod .
7
ok> 2 91 invmod .
46
ok> 13 91 invmod .
null
ok> 19 1212393831 invmod .
701912218
ok> 31 73714876143 invmod .
45180085378
ok> 3 73714876143 invmod .
null


2

J、28バイト

4 :'(1=x+.y)*x y&|@^<:5 p:y'

オンラインでお試しください!

オイラーの定理を使用します。逆行列が存在しない場合は0を返します。

説明

4 :'(1=x+.y)*x y&|@^<:5 p:y'  Input: a (LHS), b (RHS)
4 :'                       '  Define an explicit dyad - this is to use the special
                              form `m&|@^` to perform modular exponentiation
                          y   Get b
                      5 p:    Euler totient
                    <:        Decrement
             x                Get a
                   ^          Exponentiate
               y&|@             Modulo b
       x+.y                   GCD of a and b
     1=                       Equals 1
            *                 Multiply

2

Pyth、10バイト

@Jakubeのおかげで3バイト節約されました

xm%*szdQQ1

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

-1乗法逆数を返しません。

コードの内訳

xm%*szdQQ1      Let Q be the first input.
 m      Q       This maps over [0 ... Q) with a variable d.
   *szd         Now d is multiplied by the evaluated second input.
  %    Q        Now the remained modulo Q is retrieved.
x        1      Then, the first index of 1 is retrieved from that mapping.

Pyth15 13バイト

KEhfq1%*QTKSK

乗法的逆数が存在しない場合に例外をスローします。

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

Pyth、15バイト

Iq1iQKEfq1%*QTK

これにより、そのような数が存在しない場合を処理するために多くのバイトが追加されます。そのケースを処理する必要がない場合、プログラムを大幅に短縮できます。

fq1%*QTK

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


で保存された2バイトKExm%*QdKK1
ジャクベ

または、入力の順序を入れ替える場合は3バイト:xm%*szdQQ1
ジャクベ

@ジャクベ編集ありがとうございます!
氏Xcoder

これはどのように作動しますか?
Kritixiリトス

@Cowsquack完全に原始的なコードの内訳を追加しましたが、完全な説明を含める時間はありません。うまくいけば今のところは十分にはっきりしているが、すぐにもっと完全な説明を加えようと思う。
ミスターXcoder

1

C(gcc)、115バイト

#define L long long
L g(L a,L b,L c,L d){return a?g(b%a,a,d-b/a*c,c):b-1?0:d;}L f(L a,L b){return(g(a,b,1,0)+b)%b;}

オンラインでお試しください!

拡張ユークリッドアルゴリズム、再帰バージョン

C(gcc)、119バイト

long long f(a,b,c,d,t,n)long long a,b,c,d,t,n;{for(c=1,d=0,n=b;a;a=t)t=d-b/a*c,d=c,c=t,t=b%a,b=a;return b-1?0:(d+n)%n;}

オンラインでお試しください!

拡張ユークリッドアルゴリズム、反復バージョン


1

C(GCC) 48の110 104バイト

#define f(a,b)g(a,b,!b,1,b)
long g(a,b,c,d,n)long a,b,c,d,n;{a=a?g(b%a,a,d,c-(b-b%a)/a*d):!--b*(c+n)%n;}

オンラインでお試しください!

これは、60秒以内にすべての入力(長い範囲に収まる)で動作するはずです。

編集。私はすでにn変数を乱用しているので、gccが最初の割り当てをに入れると仮定することもでき%raxます。


1
残念ながら、これはループ内の整数オーバーフローが原因で、かなり小さな入力でも間違った結果をもたらします。たとえば、f(3,1000001)717を返します。これは明らかにナンセンスです(正しい答えは333334です)。また、より広い整数型を使用してこのバグを修正したとしても、このブルートフォースアプローチは、チャレンジで指定されたより大きなテストケースのいくつかで確実にタイムアウトします。
イルマリカロネン


0

公理、45バイト

f(x:PI,y:PI):NNI==(gcd(x,y)=1=>invmod(x,y);0)

エラーの場合は0、その他の場合はx * z Mod y = 1でzを返します


0

Python 2、52バイト

Xcoder氏のおかげで-3バイト。

f=lambda a,b,i=1:i*a%b==1and i or i<b and f(a,b,i+1)

オンラインでお試しください!

False解決策なしで出力し、b大きくなるとエラーが発生します。

組み込みTIO

スタックスニペットでiframeをテストしているだけで、非常に素晴らしい動作をします。


私はこれがうまくいくと確信していませi*a%b0
小麦ウィザード

入力に対する「最大再帰深度を超えました」エラーで失敗します(31,73714876143)
イルマリカロネン

0

JavaScript(ES6)、42 41 39 38バイト

false一致しない場合の出力。2番目の数値が大きくなりすぎると、オーバーフローエラーがスローされます。

x=>y=>(g=z=>x*z%y==1?z:z<y&&g(++z))(1)

0

ゼリー、27バイト

²%³
⁴Ç⁹Сx⁸
ÆṪ’BṚçL$P%³×gỊ¥

オンラインでお試しください!

モジュラーべき乗を使用してオイラーの定理を使用します。Jellyにはモジュラーべき乗を実行する組み込み機能がないため、実装する必要があり、ほとんどのバイトを使用しました。


0

公理、99バイト

w(a,b,x,u)==(a=0=>(b*b=1=>b*x;0);w(b rem a,a,u,x-u*(b quo a)));h(a,b)==(b=0=>0;(b+w(a,b,0,1))rem b)

関数h()を使用します。h(a、b)は、エラー[逆方向に存在しない]の場合は0を返します。それ以外の場合は、a * z mod b = 1のようなzを返します。引数が負の場合でも問題ありません...

これは、intのリストを再調整する一般的なegcd()関数になります(したがって、それらも負になる可能性があります)

egcd(aa:INT,bb:INT):List INT==
   x:=u:=-1   -- because the type is INT
   (a,b,x,u):=(aa,bb,0,1)
   repeat
      a=0=>break
      (q,r):=(b quo a, b rem a)
      (b,a,x,u):=(a,r,u,x-u*q)
   [b,x, (b-x*aa)quo bb]

これはそれを使用する方法です

(7) -> h(31,73714876143)
   (7)  45180085378
                                                    Type: PositiveInteger

私はhttps://pastebin.com/A13ybrycからインターネットで基本アルゴを見つけます

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