중국 나머지 정리


21

중국 잉여 정리는 우리가 항상 다른 주요 계수에 따라 필요한 나머지를 생산하는 번호를 찾을 수 있음을 알려줍니다. 목표는 다항식 시간으로 그러한 숫자를 출력하는 코드를 작성하는 것입니다. 가장 짧은 코드가 승리합니다.

예를 들어, 다음과 같은 제약 조건이 있다고 가정합니다 ( %mod를 나타냄).

n % 7  == 2
n % 5  == 4
n % 11 == 0

한 가지 해결책은 n=44입니다. 첫 번째 제약이 있기 때문에 만족 44 = 6*7 + 2, 그래서 44나머지를 가지고 2로 나눈 경우에 7따라서 및 44 % 7 == 2. 다른 두 가지 제약 조건도 충족됩니다. 같은 다른 솔루션이 존재 n=814하고 n=-341.

입력

비어 있지 않은 쌍의 목록 (p_i,a_i). 여기서 각 계수 p_i는 고유 한 소수이고 각 목표 a_i는 범위 내의 자연수 0 <= a_i < p_i입니다. 편리한 형태로 입력 할 수 있습니다. 실제로 쌍의 목록 일 필요는 없습니다. 입력이 정렬되었다고 가정하지 않을 수 있습니다.

산출

각 인덱스에 n해당 하는 정수 입니다. 그런 최소값 일 필요는 없으며 음수 일 수 있습니다.n % p_i == a_ii

다항식 시간 제한

n=0,, n=1등을 시도하는 저렴한 솔루션을 방지하려면 n=2코드가 입력 길이의 다항식 시간으로 실행되어야합니다 . m입력 의 숫자 는 length Θ(log m)가 있으므로 길이 m자체는 다항식이 아닙니다. 이는 계산 시간을 계산 m하거나 m계산할 수 없지만 값에 대한 산술 연산을 계산할 수 있음을 의미 합니다.

이 문제를 해결하기 위해 단항과 같은 비효율적 인 입력 형식을 사용할 수 없습니다.

기타 금지

다음을 수행 할 수있는 기본 제공 기능은 허용되지 않습니다. 중국어 나머지 정리를 구현하고 방정식 또는 요인 번호를 해결하십시오.

내장 기능을 사용하여 모드를 찾고 모듈 식 더하기, 빼기, 곱하기 및 지수화 (자연수 지수 포함)를 수행 할 수 있습니다. 당신은 할 수 없습니다 기타를 사용하여 내장 된 모듈 형 역, 부서 및 주문 발견을 포함한 모듈 형 작업.

테스트 사례

이것들은 가장 작은 음이 아닌 솔루션을 제공합니다. 답변이 다를 수 있습니다. 출력이 각 제약 조건을 충족하는지 직접 확인하는 것이 좋습니다.

[(5, 3)] 
3

[(7, 2), (5, 4), (11, 0)]
44

[(5, 1), (73, 4), (59, 30), (701, 53), (139, 112)]
1770977011

[(982451653, 778102454), (452930477, 133039003)]
68121500720666070

왜 부서가 없습니까?
jimmy23013

@ user23013 기본적으로 모듈 식이므로 모듈 식 구분이 없습니다.
xnor

행렬 반전은 풀기 방정식으로 계산됩니까?
flawr

@ flawr : 그렇게 생각합니다.
Alex A.

@ xnor : 어떻게 생각하세요? 그리고 최적화 기능은 어떻습니까?
flawr

답변:


9

매스 매 티카, 55 51 45

모듈러 역은 금지되지만 모듈 식 지수는 허용됩니다. 페르마의 작은 정리, n^(-1) % p == n^(p-2) % p.

(PowerMod[x=1##&@@#/#,#-2,#]x).#2&@@Thread@#&

예:

In[1]:= f = (PowerMod[x=1##&@@#/#,#-2,#]x).#2&@@Thread@#&;

In[2]:= f[{{5, 3}}]

Out[2]= 3

In[3]:= f[{{7, 2}, {5, 4}, {11, 0}}]

Out[3]= 1584

In[4]:= f[{{5, 1}, {73, 4}, {59, 30}, {701, 53}, {139, 112}}]

Out[4]= 142360350966

재미로:

ChineseRemainder@@Reverse@Thread@#&

1
가장 안쪽 함수의 인수 순서를 바꿔서 1 바이트를 절약 할 수 있습니다. 따라서 사용할 수 PowerMod[#2,#-2,#]있으며 함수의 이름을 지정해야 할 필요가 없다고 생각합니다. 48로 줄입니다.
Martin Ender

예, 명명되지 않은 기능은 정상입니다.
xnor

6

파이썬 2, 165 101 99 98 85 바이트

다른 답변과 마찬가지로 Fermat의 작은 정리를 사용합니다. 우리는 가장 작은 솔루션에 관심이 없으므로 모듈 식 범위 내에서 최종 합계를 유지하는 데 신경 쓰지 않습니다. 13 바이트를 저장해 주셔서 감사합니다.

l=input();x=reduce(lambda a,b:a*b[0],l,1)
print sum(x/a*b*pow(x/a,a-2,a)for a,b in l)

[(5, 3)]
3
[(7, 2), (5, 4), (11, 0)]
1584
[(5, 1), (73, 4), (59, 30), (701, 53), (139, 112)]
142360350966

1
전에 공백을 제거 할 수 있습니다 for.
isaacg

1
x/a*b*pow(x/a,a-2,a)for a,b in l작동해야합니다.
변동성

훌륭한 포인트! 나는 명백한 중복성을 없애려고 노력했지만 포장을 풀 수는 없었습니다.
Uri Granta

4

피스, 40 37 36 29

M*G.^G-H2Hsm*edg/u*GhHQ1hdhdQ

alephalpha 덕분에 Fermat의 작은 정리를 사용합니다. 이 공식을 사용하여 계산합니다 .


3

루비, 129

동지들에 따르면, openssl 라이브러리를로드하고 OpenSSL :: BN으로 변환하지 않으면 모듈 식 지수를 사용할 수 없기 때문에 Ruby 솔루션이 더 길어야합니다. 그래도 재미있게 작성했습니다.

require("openssl")
z=eval(gets)
x=1
z.map{|a,b|x*=a}
s=0
z.map{|a,b|e=a.to_bn;s+=(x/a).to_bn.mod_exp(e-2,e).to_i*b*x/a}
puts(s)

당신은 호출 할 때 괄호를 필요로하지 않는 require, eval또는 puts.
Tutleman

2

파이썬 2, 61

n=P=1
for p,a in input():n+=P*(a-n)*pow(P,p-2,p);P*=p
print n

이것은 다른 답변이 사용 하는 제품 구성 의 변형을 사용합니다.

아이디어는 제약 조건을 반복 n하고 이전 제약 조건을 손상시키지 않고 솔루션 을 업데이트 하여 현재 제약 조건을 충족시키는 것입니다. 그렇게하기 위해, 우리는 P지금까지 본 소수 의 곱을 추적하고 , 배수의 곱을 추가 P해도 이미 본 소수에 대한 모듈로 효과가 없음을 관찰합니다 .

따라서 올바른 배수를 추가하여 n만족 하도록 변경 하면 n%p == a됩니다 P. 우리는 계수를 해결합니다 c.

(n + P*c) % p == a

이것은 c = (a-n) * P^(-1)역수를 취한 곳에서 모듈로가 필요합니다 p. 다른 사람들이 지적했듯이, 역은 Fermat의 Little Theorem으로 계산할 수 있습니다 P^(-1) = pow(P,p-2,p). 따라서로 c = (a-n) * pow(P,p-2,p)업데이트 n합니다 n+= P * (a-n) * pow(P,p-2,p).


1

하스켈, 68100 바이트

f l=sum[p#(m-2)*n*p|(m,n)<-l,let a#0=1;a#n=(a#div n 2)^2*a^mod n 2`mod`m;p=product(map fst l)`div`m]

사용법 : f [(5,1), (73,4), (59,30), (701,53), (139,112)]-> 142360350966.

편집 : 이제 빠른 "power / mod"기능이 있습니다. 전원 기능이 내장 된 이전 버전 (68 바이트) :

f l=sum[l#m^(m-2)`mod`m*n*l#m|(m,n)<-l]
l#m=product(map fst l)`div`m

지수가 mod보다 많은 수를 생성하기 때문에 power-mod 구현이 다항식 시간이 아닌 것으로 생각됩니다. 마지막 테스트 사례를 사용해 보셨습니까?
xnor

@ xnor : 마지막 테스트 케이스에 2GB 컴퓨터에서 몇 초 후에 메모리가 부족합니다. 빠른 전원 / 모드 기능을 추가했습니다.
nimi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.