모듈 식 곱셈 역


22

당신의 임무는 두 개의 정수를 주어야 a하고 b, 모듈로 b의 존재하는 경우 모듈로 곱한 역수를 계산하는 것입니다.

모듈 a로 의 모듈러 역수 b는 다음 c과 같은 숫자 입니다 ac ≡ 1 (mod b). 이 숫자는 및의 b모든 쌍에 대해 고유 한 모듈로 입니다 . 그것은의 최대 공약수는 경우에만 존재 하고 있다 .abab1

위키 백과 페이지 당신이 항목에 대한 자세한 정보가 필요한 경우 모듈 역수에 대한이 상담 할 수있다.

입력과 출력

입력은 두 정수 또는 두 정수 목록으로 제공됩니다. 프로그램은 단일 숫자, 구간에있는 모듈 식 곱셈 역수 0 < c < b또는 역수가 없음을 나타내는 값을 출력해야합니다 . 값은 range의 숫자를 제외한 모든 것이 (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의 Little Theorem에 따르면 a의 곱셈 역행은 존재한다면 a ^ (phi (b) -1) mod b로 효율적으로 계산할 수 있습니다. 여기서 phi는 Euler의 끈질긴 함수입니다. k1 * ...) = (p0-1) * p0 ^ (k0-1) * (p1-1) * p1 ^ (k1-1) * ... 더 짧은 코드로 이어지지 않음 :)
ngn

1
@Jenny_mathy 추가 입력을받는 것은 일반적으로 허용되지 않습니다.
Mr. Xcoder

3
나는 무차별 강제로 보이는 6 가지 답변을 세고 60 초 안에 모든 테스트 사례를 실행할 가능성이 적습니다 (일부 스택이나 메모리 오류가 먼저 발생합니다).
Ørjan Johansen '

1
@ngn : 당신은 Ferler의 Little Theorem (FLT)을 Euler의 개선과 함께했습니다. Fermat는 오일러 파이 기능에 대해 몰랐습니다. 또한 FLT와 Euler의 개선은 gcd (a, b) = 1 인 경우에만 적용됩니다. 마지막으로, 작성한 양식에서 "a ^ (\ phi (b) -1) mod b"는 a가 아니라 1과 일치합니다. ^ (-1). a ^ (-1)을 얻으려면 a ^ (\ phi (b) -2) mod b를 사용하십시오.
에릭 타워

1
@EricTowers Euler의 결과입니다. "gcd (a, b) = 1"과 관련하여- "반대 존재하는 경우"라고 말했습니다. phi (b) -2에 대해 확신합니까?
ngn

답변:


11

수학, 14 바이트

의무 Mathematica 내장 :

ModularInverse

두 개의 인수 ( ab)를 사용하고 mod b가 존재하면 그 역수를 반환 하는 함수입니다 . 그렇지 않으면 오류를 반환합니다 ModularInverse: a is not invertible modulo b..


7

자바 스크립트 (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의 이름을 쓸 수없는 이유는 무엇입니까? aa % c) / c * d, n) : a <2 && (b + n) % n?
RosLuP

@RosLup f(x,y)function키워드 가 명시 적으로 앞에 오는 경우를 제외하고 항상 함수 호출로 구문 분석됩니다 . 반면 익명의 화살표 함수는로 선언되어 (x,y)=>something있으며 f=(x,y)=>something함수를 f변수에 할당합니다 .
Arnauld

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.

더 큰 테스트 사례에 대해 작업하려면 메모리보다 많은 시간이 필요한이 (상대적으로 ungolfed) 버전을 사용해보십시오.

젤리, 9 바이트

×⁴%³’¬ø1#

온라인으로 사용해보십시오!

작동 원리

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

4

파이썬 2 , 34 바이트

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

온라인으로 사용해보십시오!

재귀 제공 기능 True을 위해 print f(1,2)내가 허용 생각하는, 유효하지 않은 입력에 대한 오류.

우리는 찾으려고 노력 xX 1ax1(modb) .

ax1=kbk

취득 moda1kb(moda)kb1(moda)k

kf(b%a,a)

aab

kax1=kbxkb+1a



3

매스 매 티카, 18 바이트

PowerMod[#,-1,#2]&

입력

[31, 73714876143]


3

파이썬 2 , 51 49 54 53 51 49 바이트

공식적인 덕분에
-1 바이트 Shaggy 덕분에 -1 바이트

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

온라인으로 사용해보십시오!

0해결책이 없을 때 인쇄 합니다.


1
및에 0대한 출력 ; 테스트 사례에서을 출력해야합니다 . a=1b=21
Shaggy


1
Shaggy가 지적했듯이 실패합니다2, 1
Mr. Xcoder

@Shaggy는 이제 작동합니다
Rod

입력에 대한 TIO에서 60 초 내에 응답을 리턴하지 않습니다 31,73714876143.
Ilmari Karonen

3

Japt , 9 8 바이트

입력을 역순으로 취합니다. -1일치하지 않는 출력 . 정수가 클수록 커집니다.

Ç*V%UÃb1

그것을 테스트

  • ETH가 잘못된 매우 명확한 공간을 지적하여 1 바이트를 절약했습니다.

테스트 입력 73714876143,31이 Firefox에서 메모리 부족 오류를 발생시키고 Chromium과 충돌하는 것으로 보입니다. 나는 이것이 올바른 대답이라고 생각하지 않습니다.
Ilmari Karonen

@ IlmariKaronen : 내 솔루션에서 그 사실을 분명히 지적했습니다. 우리는 코드 골프 목적으로 무한 메모리를 가정 할 수 있으므로 메모리 문제와 충돌로 인해이 솔루션이 무효화되지 않습니다.
Shaggy

1
불행히도 메모리 문제로 인해 코드가 테스트 케이스를 60 초 안에 실제로 해결할지 여부를 알 수 없습니다. 충돌하지 않도록 사용할 수있는 메모리가 충분하더라도 실제로 프로그램을 오랫동안 실행할 수있는 컴퓨터가 없다면 확실히 말할 방법이 없습니다.
Ilmari Karonen


2

파이썬 3 , 49 바이트

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

온라인으로 사용해보십시오!

파이썬 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,7371487614360 초 내에 입력 결과를 리턴하지 않습니다 (TIO에서).
Ilmari Karonen

@IlmariKaronen 내 컴퓨터에서 56 초 안에 끝날 것 같습니다 (Macbook Pro '15)
Mr. Xcoder

2

8 일 , 6 바이트

암호

invmod

설명

invmodamodulo 의 역의 값을 계산하는 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

피스 , 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.

Pyth , 15 13 바이트

KEhfq1%*QTKSK

곱하기 역수가 존재하지 않는 경우 예외가 발생합니다.

여기 사용해보십시오!

Pyth , 15 바이트

Iq1iQKEfq1%*QTK

이것은 그러한 숫자가 존재하지 않는 경우를 처리하기 위해 많은 바이트를 추가합니다. 이 경우를 처리 할 필요가 없으면 프로그램을 크게 단축 할 수 있습니다.

fq1%*QTK

여기 사용해보십시오!


2 바이트 저장KExm%*QdKK1
Jakube

또는 입력 순서를 바꾸면 3 바이트 :xm%*szdQQ1
Jakube

@Jakube 고마워요, 편집!
Mr. Xcoder

어떻게 작동합니까?
Kritixi Lithos

@Cowsquack 나는 완전히 원시적 인 코드 분석을 추가했지만 rn 완전한 설명을 포함 할 시간이 없습니다. 바라건대 지금은 충분히 명확하지만 곧 더 완전한 설명을 추가하려고 노력할 것입니다.
Mr. Xcoder


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). 또한 더 넓은 정수 유형을 사용하여이 버그를 수정 했음에도 불구하고이 무차별 대입 방식은 문제에서 제시된 더 큰 테스트 사례 중 일부에 대해 시간 초과됩니다.
Ilmari Karonen


0

공리, 45 바이트

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

오류가 0이면 x * z Mod y = 1 인 z를 반환합니다.


0

파이썬 2 , 52 바이트

Mr. 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

Stack Snippets에서 iframe을 테스트하고 있으며 환상적으로 작동합니다.


나는이 작품 확실하지 않다, 할 수없는 i*a%b0?
밀 마법사

입력에 대한 "최대 재귀 깊이 초과"오류로 실패합니다 (31,73714876143).
Ilmari Karonen

0

자바 스크립트 (ES6), 42 41 39 38 바이트

false일치하지 않는 출력 . 두 번째 숫자가 너무 커지면 오버플로 오류가 발생합니다.

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

0

젤리 , 27 바이트

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

온라인으로 사용해보십시오!

모듈러 지수와 함께 Euler의 정리를 사용합니다. 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을 반환하고, 그렇지 않으면 z를 반환하여 a * z mod b = 1이되도록합니다. 인수가 음수 일지라도 괜찮습니다 ...

이것은 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.