Định lý còn lại của Trung Quốc


21

Các Phần còn lại Định lý Trung Quốc cho chúng ta biết rằng chúng ta luôn có thể tìm thấy một số sản xuất bất kỳ dư theo yêu cầu của môđun thủ khác nhau. Mục tiêu của bạn là viết mã để xuất ra một số như vậy trong thời gian đa thức. Mã ngắn nhất sẽ thắng.

Ví dụ: giả sử chúng tôi đưa ra các ràng buộc này ( %đại diện cho mod):

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

Một giải pháp là n=44. Ràng buộc đầu tiên được thỏa mãn bởi vì 44 = 6*7 + 2, và 44phần còn lại 2khi được chia cho 7, và do đó 44 % 7 == 2. Hai hạn chế khác cũng được đáp ứng. Có tồn tại các giải pháp khác, như n=814n=-341.

Đầu vào

Một danh sách các cặp không trống (p_i,a_i), trong đó mỗi mô đun p_ilà một số nguyên tố riêng biệt và mỗi mục tiêu a_ilà một số tự nhiên trong phạm vi 0 <= a_i < p_i. Bạn có thể lấy đầu vào dưới mọi hình thức thuận tiện; nó không thực sự phải là một danh sách các cặp. Bạn không thể cho rằng đầu vào được sắp xếp.

Đầu ra

Một số nguyên nsao n % p_i == a_icho mỗi chỉ số i. Nó không phải là giá trị nhỏ nhất như vậy và có thể âm.

Giới hạn thời gian đa thức

Để ngăn chặn các giải pháp rẻ tiền mà chỉ cần cố gắng n=0, n=1, n=2, và như vậy, mã của bạn phải chạy trong thời gian đa thức trong chiều dài của đầu vào . Lưu ý rằng một số mtrong đầu vào có độ dài Θ(log m), vì vậy mbản thân nó không phải là đa thức về độ dài của nó. Điều này có nghĩa là bạn không thể đếm đến mhoặc thực hiện mthời gian hoạt động , nhưng bạn có thể tính toán các phép toán số học trên các giá trị.

Bạn không thể sử dụng một định dạng đầu vào không hiệu quả như unary để khắc phục điều này.

Cấm khác

Không được phép xây dựng các thao tác sau: Thực hiện định lý còn lại của Trung Quốc, giải phương trình hoặc số yếu tố.

Bạn có thể sử dụng các phần dựng sẵn để tìm mod và thực hiện phép cộng, trừ, nhân và lũy thừa mô đun (với số mũ số tự nhiên). Bạn không được sử dụng các hoạt động mô đun tích hợp khác, bao gồm nghịch đảo mô đun, phân chia và tìm kiếm đơn hàng.

Các trường hợp thử nghiệm

Chúng cho giải pháp không âm nhỏ nhất. Câu trả lời của bạn có thể khác. Có lẽ tốt hơn nếu bạn kiểm tra trực tiếp rằng đầu ra của bạn đáp ứng từng ràng buộc.

[(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

Tại sao không có phân chia?
jimmy23013

@ user23013 Không có phân chia mô-đun, vì về cơ bản là nghịch đảo mô-đun.
xnor

Có nghịch đảo ma trận được tính là giải phương trình?
flawr 22/03/2015

@flawr: Tôi sẽ nghĩ như vậy.
Alex A.

@xnor: Bạn nghĩ gì? Và làm thế nào về chức năng tối ưu hóa?
flawr 22/03/2015

Câu trả lời:


9

Toán học, 55 51 45

Mô đun nghịch đảo bị cấm, nhưng lũy ​​thừa mô đun được cho phép. Theo định lý nhỏ của Fermat , n^(-1) % p == n^(p-2) % p.

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

Thí dụ:

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

Chỉ để cho vui:

ChineseRemainder@@Reverse@Thread@#&

1
Bạn có thể lưu một byte bằng cách hoán đổi thứ tự các đối số của hàm trong cùng, sao cho bạn có thể sử dụng PowerMod[#2,#-2,#]và tôi cũng không nghĩ rằng có một yêu cầu cho hàm được đặt tên, đưa nó xuống 48.
Martin Ender

Có, chức năng không tên là OK.
xnor

6

Con trăn 2 165 101 99 98 85 byte

Sử dụng định lý nhỏ của Fermat như các câu trả lời khác. Không bận tâm đến việc giữ số tiền cuối cùng trong phạm vi mô-đun, vì chúng tôi không quan tâm đến giải pháp nhỏ nhất. Cảm ơn Biến động đã lưu 13 byte.

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
Bạn có thể loại bỏ không gian trước for.
isaacg 22/03/2015

1
x/a*b*pow(x/a,a-2,a)for a,b in lnên làm việc.
Biến động

Điểm tuyệt vời! Tôi đã cố gắng để thoát khỏi sự dư thừa rõ ràng ở đó nhưng quên rằng tôi chỉ có thể giải nén.
Uri Granta

4

Bình dương, 40 37 36 29

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

Sử dụng định lý nhỏ của Fermat, nhờ alephalpha. Tính toán bằng công thức này .


3

Hồng ngọc, 129

Chà, các đồng chí, có vẻ như các giải pháp của Ruby phải dài hơn vì lũy thừa mô-đun không có sẵn mà không tải thư viện openssl và thực hiện chuyển đổi sang OpenSSL :: BN. Tuy nhiên, đã vui vẻ viết nó:

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)

Bạn không cần dấu ngoặc khi gọi require, evalhoặc puts.
Người hướng dẫn

2

Con trăn 2, 61

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

Điều này sử dụng một biến thể của cấu trúc sản phẩm mà các câu trả lời khác sử dụng.

Ý tưởng là lặp lại các ràng buộc và cập nhật giải pháp nđể đáp ứng các ràng buộc hiện tại mà không làm rối tung các ràng buộc trước đó. Để làm như vậy, chúng tôi theo dõi sản phẩm Pcủa các số nguyên tố được nhìn thấy cho đến nay và quan sát rằng việc thêm bội số Pkhông có hiệu lực modulo bất kỳ số nguyên tố nào đã thấy.

Vì vậy, chúng ta chỉ cần thay đổi nđể đáp ứng n%p == abằng cách thêm bội số đúng P. Chúng tôi giải quyết cho hệ số c:

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

Điều này đòi hỏi rằng c = (a-n) * P^(-1), trong đó nghịch đảo được lấy modulo p. Như những người khác lưu ý, nghịch đảo có thể được tính theo Định lý nhỏ của Fermat như P^(-1) = pow(P,p-2,p). Vì vậy, c = (a-n) * pow(P,p-2,p)và chúng tôi cập nhật nbởi n+= P * (a-n) * pow(P,p-2,p).


1

Haskell, 68 100 byte

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]

Cách sử dụng: f [(5,1), (73,4), (59,30), (701,53), (139,112)]-> 142360350966.

Chỉnh sửa: bây giờ với chức năng "power / mod" nhanh. Phiên bản cũ (68 byte) với chức năng nguồn sẵn có:

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

Tôi nghi ngờ việc bạn thực hiện power-mod không phải là đa thức thời gian vì số mũ tạo ra một số lượng lớn trước mod. Bạn đã thử trường hợp thử nghiệm cuối cùng?
xnor

@xnor: trường hợp thử nghiệm cuối cùng hết bộ nhớ sau vài giây trên máy 2GB của tôi. Tôi đã thêm chức năng cấp nguồn / mod nhanh.
nimi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.