Hệ số nguyên tweet nhanh nhất


17

Nhiệm vụ là tìm một yếu tố không tầm thường của một số tổng hợp.

Viết mã tìm thấy một yếu tố không tầm thường của một số tổng hợp càng nhanh càng tốt đối với mã của bạn dài không quá 140 byte. Đầu ra chỉ nên là yếu tố bạn đã tìm thấy.

Mã của bạn có thể lấy đầu vào và đưa ra đầu ra theo bất kỳ cách nào thuận tiện, ví dụ như là đối số cho hàm.

Các trường hợp kiểm tra liệt kê tất cả các yếu tố (bạn chỉ cần xuất một)

187: 11 17
1679: 23 73
14369648346682547857: 1500450271 9576890767
34747575467581863011: 3628273133 9576890767
52634041113150420921061348357: 2860486313 5463458053 3367900313
82312263010898855308580978867: 264575131106459 311111111111113
205255454905325730631914319249: 2860486313 71755440315342536873 
1233457775854251160763811229216063007: 1110111110111 1000000000063 1111111999999
1751952685614616185916001760791655006749: 36413321723440003717 48112959837082048697

Tôi sẽ không chấm điểm câu trả lời của bạn trong trường hợp kiểm tra khó khăn sau đây có thể được quan tâm để kiểm tra:

513231721363284898797712130584280850383: 40206835204840513073 12764787846358441471

Ghi bàn

Điểm của bạn là thời gian kết hợp để tính tất cả các trường hợp kiểm tra ở trên với hình phạt 10 phút cho mỗi lần xác định không thành công (tất cả được làm tròn đến giây gần nhất). Mã của bạn cũng nên hoạt động cho các số nguyên khác, đó không chỉ là mã hóa các câu trả lời này.

Tôi sẽ dừng mã của bạn sau 10 phút.

Nếu hai người có cùng số điểm thì câu trả lời đầu tiên sẽ thắng.

Những hạn chế

Mã của bạn không thể sử dụng bất kỳ hàm dựng sẵn hoặc thư viện nào thực hiện phép nhân số nguyên. Bạn có thể giả sử đầu vào mất ít hơn 256 bit. Tất cả các số đầu vào sẽ được tổng hợp.

Tôi sẽ có thời gian như thế nào?

Tôi thực sự sẽ chạy time ./myprogtrên hệ thống Ubuntu của mình để thực hiện thời gian vì vậy vui lòng cung cấp một chương trình hoàn chỉnh để tôi chạy bao gồm bất kỳ chức năng nào bạn đã xác định.

Một lưu ý cho các ngôn ngữ được biên dịch

Thời gian biên dịch phải mất không quá 1 phút trên máy của tôi.

Có thực sự có thể?

Nếu bạn bỏ qua các hạn chế về không gian, thì mỗi cái có thể được xác định trong vòng chưa đầy 2 giây trên máy tính của tôi bằng mã Python thuần + pypy.

Vậy thuật toán bao thanh toán không tầm thường là gì?

Thuật toán rho của Pollard rất nhanh và phù hợp để chơi gôn. Tất nhiên có rất nhiều cách khác để tính một số nguyên là tốt.

Thậm chí nhanh hơn là sàng Quadratic . Có vẻ như một thách thức nghiêm trọng để ép nó thành 140 byte.

Điểm số hàng đầu

  • SEJPM , hình phạt 10 phút cho trường hợp thử nghiệm cuối cùng + 16 giây trong Haskell

Vì vậy, chúng ta có thể được cung cấp một số như thế 2 ** 1024nào?
Conor O'Brien

@ ConorO'Brien Bạn sẽ không được cung cấp bất cứ thứ gì có nhiều chữ số hơn các trường hợp thử nghiệm.

Vì vậy, về độ chính xác, không có gì hơn 256 bit.
Conor O'Brien

Đối với một đầu vào như 4, đầu ra nên 2hay 2, 2?
Ông Xcoder

1
@AndersKaseorg Tôi đã cập nhật câu hỏi theo đề xuất của bạn. Cảm ơn.

Câu trả lời:


9

Haskell, 100 97 91 89 87 72 67 byte

Dùng thử trực tuyến!

-3 byte nhờ @flawr
-6 byte nhờ @flawr một lần nữa
-2 byte nhờ @flawr một lần nữa
-2 byte nhờ một bộ tham số được tối ưu hóa
-1 byte nhờ @flawrs thêm một lần nữa
-14 byte nhờ yêu cầu chỉ phải xuất một yếu tố
-5 byte nhờ @AndersKaseorg

f n|let s x=mod(x*x+7)n;a#b|d<-gcd(b-a)n,d>1=d|c<-s b=s a#s c=5#s 5

Điều này làm việc cho 5 trường hợp thử nghiệm đầu tiên trong thời gian không thể nhận ra.
Điều này có thể sẽ hết thời gian trên trường hợp thử nghiệm lớn nhất.

Nói chung, điều này thường sẽ trả về một yếu tố không tầm thường theo thời gian tỷ lệ với căn bậc hai của yếu tố nhỏ nhất.
Nó sẽ không hoạt động trên mọi đầu vào vì nó không thay đổi đa thức và việc phát hiện trường hợp ngoại lệ khó thực hiện trong 140 byte.
Nó cũng sẽ không đưa ra hệ số đầy đủ, mà là một yếu tố không tầm thường và sự phân chia đầu vào theo yếu tố này.
Nó cũng sẽ không sắp xếp các yếu tố theo kích thước.

Phương pháp được sử dụng là Pollard-Rho-Factoring với giá trị bắt đầu chuẩn là 2 (với x^2+1đa thức chuẩn được áp dụng một lần) và hệ số hằng số đa thức không chuẩn là 7 (vì 1không hoạt động với 1679) cho tất cả các đánh giá tiếp theo.

Chương trình đầy đủ ( factor.hs):

import System.Environment(getArgs)

f n|let s x=mod(x*x+7)n;a#b|d<-gcd(b-a)n,d>1=d|c<-s b=s a#s c=5#s 5

main= do
      args <- getArgs
      print$f (read $ head args :: Integer)

Biên dịch thành $ ghc factor.hs(nhu cầu ghccài đặt).
Chạy như$ ./factor <number> .

Chạy ví dụ:

$ ./factor 187
11

Mã bị đánh cắp:

f n=g 5 (s 5)
   where s x=mod(x*x+7)n
         g a b = if d>1 then d else g(s a)(s(s b))
               where d=gcd(b-a)n

Tính toán yếu tố không tầm thường bằng cách gọi gvới các giá trị ban đầu. Đa thức được áp dụng trước trên 2 ở đây và áp dụng lại trên kết quả (5) để đầu vào g(trong mệnh đề "where" ) luôn có thể dễ dàng được sử dụng cho kiểm tra gcd. g(phiên bản golf sử dụng infix #) sau đó cố gắng tính toán một yếu tố không tầm thường d(trong mệnh đề where trong phiên bản không chơi gôn, trong dòng trong golfed) là sự khác biệt giữa hai yếu tố đầu vào g, nếu nó thành công trả về yếu tố đã nói , khác thử lại. Ở đây, nó có thể tạo ra nnhư là đầu ra nếu a==bvà do đó chỉ trả về một yếu tố tầm thường, cách tiếp cận phù hợp để xử lý điều này sẽ là thay đổi các giá trị bắt đầu theo sự kiện này hoặc thay đổi đa thức.


|1<2=s a#(s$s b)có thể được thay thế bằng |c<-s b=s a#s ctôi nghĩ :) (cũng: tại sao bạn không đăng liên kết TIO ?)
flawr

Tôi cập nhật câu hỏi theo gợi ý bình luận. Bây giờ bạn chỉ cần xuất một yếu tố và các số được đảm bảo là tổng hợp.

3
Tái
bút

4
Bây giờ bạn có 53 byte để thực hiện thuật toán bao thanh toán phức tạp hơn nữa :)

1
Ngoài ra, bạn có thể lấy ra abs , vì bluôn luôn không âm. (Có lẽ bạn có ý đó abs$b-a, nhưng gcdchấp nhận các lập luận tiêu cực và luôn tạo ra một kết quả không âm.) Điều đó làm giảm điều này xuống dưới một nửa tweet!
Anders Kaseorg

5

Pari / GP , 137 byte, ~ 5 giây

Sử dụng các hoạt động đường cong elip tích hợp của GP (và một số điều chỉnh tham số ngầm) :

ecm(n)=iferr(if(n%2==0,2,n%3==0,3,for(a=1,n,ellmul(ellinit(Mod([a,a^2-a-1],n)),[1,a],lcm([1..ceil(4^a^0.5)])))),e,gcd(n,lift(Vec(e)[3])))

ecmlà một hàm mà (nên) trả về một yếu tố. Hãy thử trực tuyến!

Kiểm tra:

ecm(n)=iferr(if(n%2==0,2,n%3==0,3,for(a=1,n,ellmul(ellinit(Mod([a,a^2-a-1],n)),[1,a],lcm([1..ceil(4^a^0.5)])))),e,gcd(n,lift(Vec(e)[3])))

{
ns = [
  187,
  1679,
  14369648346682547857,
  34747575467581863011,
  52634041113150420921061348357,
  82312263010898855308580978867,
  205255454905325730631914319249,
  1233457775854251160763811229216063007,
  1751952685614616185916001760791655006749
  ]
}

test(n) = {
    d = ecm(n);
    if (!(1<d && d<n && n%d==0), error(d));
    print(n, ": ", d)
}

apply(test, ns)

quit

Ung dung:

ecm(n) = {
  iferr(if(n%2 == 0, 2,
           n%3 == 0, 3,
           for(a = 1, n,
               /* x^3 + A*x + B = y^2 */
               E = ellinit(Mod([a, a^2-a-1], n)); /* [A, B] */
               x0 = [1, a]; /* [x, y] */
               B = ceil(4^a^0.5); /* ~ exp(sqrt(log(p))), p ~= exp(a) */
               print("a=", a, ", B=", B);
               ellmul(E, x0, lcm([1..B]))
              )
          ),
         ERR, gcd(n, lift(Vec(ERR)[3] /* = Mod(d, n) */)),
         errname(ERR)=="e_INV")
}

Đáng buồn thay, việc xử lý các yếu tố 2 và 3 sử dụng nhiều byte. Byte có thể đã được sử dụng để thêm giai đoạn 2:

ecm(n)=iferr(for(a=1,n,Y=X=ellmul(E=ellinit(Mod([a,1],n)),[0,1],(B=ceil(4^a^0.5))!);for(z=0,9*B,Y=elladd(E,Y,X))),e,gcd(n,lift(Vec(e)[3])))

1

Tiên đề, 137 byte 9 phút

p(n:PI):PI==(j:=1;a:=3;s:=n^.2;repeat(b:=j:=nextPrime(j);repeat(b<s=>(b:=b*j);break);a:=powmod(a,b,n);d:=gcd(a-1,n);d>1 or j>n=>break);d)

phía trên hàm p () sẽ triển khai thuật toán p-1 để bao thanh toán bên dưới những gì cần sao chép trong một tệp để kiểm tra hàm p ()

-- one has to copy this below text in a file name for example file.input
-- in one window where there is Axiom one could write 
-- )read C:\absolutepathwherethereisthatfile\file
-- and call the function test()
-- test()
-- the first character of all function and array must be afther a new line "\n"
)cl all
)time on
vA:=[187,1679,14369648346682547857,34747575467581863011,52634041113150420921061348357,82312263010898855308580978867,205255454905325730631914319249,1233457775854251160763811229216063007, 1751952685614616185916001760791655006749]

p(n:PI):PI==(j:=1;a:=3;s:=n^.2;repeat(b:=j:=nextPrime(j);repeat(b<s=>(b:=b*j);break);a:=powmod(a,b,n);d:=gcd(a-1,n);d>1 or j>n=>break);d)

-- this would try to factor n with p-1 Pollard method
pm1(n:PI):PI==
   j:=1;a:=3;s:=n^.2
   repeat
      b:=j:=nextPrime(j)
      repeat(b<s=>(b:=b*j);break)
      a:=powmod(a,b,n)
      d:=gcd(a-1,n);d>1 or j>n=>break
   d

test()==(for i in 1..#vA repeat output [vA.i, p(vA.i)])

kết quả ở đây:

(5) -> test()
   [187,11]
   [1679,73]
   [14369648346682547857,9576890767]
   [34747575467581863011,9576890767]
   [52634041113150420921061348357,2860486313]
   [82312263010898855308580978867,311111111111113]
   [205255454905325730631914319249,2860486313]
   [1233457775854251160763811229216063007,1111111999999]
   [1751952685614616185916001760791655006749,36413321723440003717]
                                                               Type: Void
                              Time: 496.78 (EV) + 53.05 (GC) = 549.83 sec

Bạn có thể đánh vần chính xác làm thế nào để chạy mã này từ dòng lệnh trong ubfox không? Tôi đã cài đặt tiên đề và tạo một tệp có tên foo.ax với mã không được đánh gôn của bạn trong đó.

@Lembik 1) đổi tên fop.ax trong foo.input 2) chạy Axiom trong một thiết bị đầu cuối hoặc xterm 3) viết vào thiết bị đầu cuối Axiom đó theo lệnh ") đọc C: hqutepathath để kiểm tra chức năng (). Đây là cách thực hiện trong Windows, đầu mối có vẻ như tôi mở một phiên Axiom và tải tệp bằng lệnh ") read"
RosLuP

@Lembik nếu có vấn đề với các tập tin, tôi nghĩ nó cũng sẽ ổn thôi mảng vA, hàm p () và test () 4) trong chương trình Axiom viết test () <return>
RosLuP

@Lembik vậy mất mấy giờ?
RosLuP

1

Tiên đề, 10 phút + 31 giây

A(a)==>a:=(a*a+7)rem n;z(n)==(p:=a:=b:=101;for i in 1..repeat(A(a);A(b);A(b);p:=mulmod(p,a-b,n);i rem 999<9=>(p:=gcd(p,n);p>1=>break));p)

z () là hàm rho, một hàm 137 byte; vô dụng z () và gọi nó là rho (). Nó sẽ giả sử rằng gcd (0, n) = n để vòng lặp dừng và trả về cho fail n.

)time on    
rho(n)==
  p:=a:=b:=101
  for i in 1..repeat
          A(a);A(b);A(b)
          p:=mulmod(p,a-b,n)
          i rem 999<9=>(p:=gcd(p,n);p>1=>break)
  p

va1:=[187,1679,14369648346682547857,34747575467581863011,52634041113150420921061348357,82312263010898855308580978867,205255454905325730631914319249,1233457775854251160763811229216063007, 1751952685614616185916001760791655006749]
p1()==(for i in 1..#va1-1 repeat output [va1.i,z(va1.i)]) 

kết quả (z () vẫn ổn với tất cả, nhưng số cuối 1751952685614616185916001760791655006749 vẫn chưa được tính (10 phút))

(6) -> p1()
   [187,17]
   [1679,23]
   [14369648346682547857,1500450271]
   [34747575467581863011,3628273133]
   [52634041113150420921061348357,2860486313]
   [82312263010898855308580978867,264575131106459]
   [205255454905325730631914319249,2860486313]
   [1233457775854251160763811229216063007,1111111999999]
                                                               Type: Void
                                 Time: 30.38 (EV) + 1.38 (GC) = 31.77 sec

(8) -> z(1679)
   (8)  23
                                                    Type: PositiveInteger
                                                              Time: 0 sec

0

Python 3 , 100 99 byte, 45 40 39 giây + phạt 10 phút

import math
def f(n):
 x=y=2;d=1
 while d<2:y=y*y+1;x,y=1+x*x%n,y*y%n+1;d=math.gcd(x-y,n)
 return d

Hãy thử trực tuyến!

Sử dụng Pollard-Rho với giá trị ban đầu 2 và đa thức x ^ 2 + 1.


Bạn có thể sử dụng pow(với đối số thứ 3) để cải thiện tốc độ thực hiện của mình.
mbomb007
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.