가장 빠른 트위스트 가능한 정수 팩터


17

이 작업은 복합 숫자의 사소한 요소를 찾는 것입니다.

코드 길이가 140 바이트를 넘지 않으면 서 가능한 빨리 복합 수의 중요하지 않은 요소를 찾는 코드를 작성하십시오. 결과는 찾은 요소 일뿐입니다.

코드는 예를 들어 함수에 대한 인수를 포함하여 편리한 방법으로 입력을 가져오고 출력 할 수 있습니다.

모든 요소를 ​​나열하는 테스트 사례 (하나만 출력하면 됨)

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

테스트에 관심이있을 수있는 다음과 같은 어려운 테스트 사례에서 귀하의 답변에 점수를 매기 지 않습니다.

513231721363284898797712130584280850383: 40206835204840513073 12764787846358441471

점수

점수는 각 실패한 인수 분해에 대해 10 분의 페널티 (모든 것이 가장 가까운 초로 반올림 됨)로 위의 모든 테스트 케이스를 인수 분해하는 결합 된 시간입니다. 코드는 다른 정수에서도 작동해야합니다.이 답변을 하드 코딩해서는 안됩니다.

10 분 후에 코드를 중지하겠습니다.

두 사람이 같은 점수를 얻으면 첫 번째 답변이 이깁니다.

제한 사항

코드는 정수 인수 분해를 수행하는 내장 함수 또는 라이브러리 함수를 사용할 수 없습니다. 입력이 256 비트보다 적은 것으로 가정 할 수 있습니다. 모든 입력 번호는 합성됩니다.

나는 어떻게 시간을 할 것인가?

말 그대로 time ./myprog우분투 시스템에서 타이밍을 실행하기 위해 실행하므로 정의 한 기능이 포함 된 완전한 프로그램을 실행하십시오.

컴파일 된 언어에 대한 참고 사항

컴퓨터에서 컴파일 시간이 1 분을 넘지 않아야합니다.

실제로 가능합니까?

공간 제약 조건을 무시하면 순수 Python 코드 + pypy를 사용하여 컴퓨터에서 각 제약 조건을 2 초 이내에 인수 할 수 있습니다.

그렇다면 사소한 인수 분해 알고리즘은 무엇입니까?

Pollard의 rho 알고리즘 은 빠르고 골프에 적합합니다. 물론 정수인수 분해하는 다른 방법도 많이 있습니다.

이차 체 는 더 빠릅니다 . 140 바이트로 압축하는 것은 심각한 도전처럼 보입니다.

최고의 점수

  • SEJPM , 마지막 테스트 케이스에 대해 10 분의 페널티 + Haskell 에서 16 초

따라서 우리는 2 ** 1024?
코너 오브라이언

@ ConorO'Brien 테스트 케이스보다 더 많은 숫자가 제공되지 않습니다.

따라서 정밀도 측면에서 256 비트를 넘지 않습니다.
코너 오브라이언

4와 같은 입력의 경우 출력은 2또는 2, 2?
Mr. Xcoder

1
@AndersKaseorg 귀하의 제안에 따라 질문을 업데이트했습니다. 감사.

답변:


9

하스켈, 100 97 91 89 87 72 67 바이트

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

@flawr로 인해 -3 바이트-
@flawr로 다시 -6 바이트-@flawr로 다시
-2 바이트-
최적화 된 매개 변수 세트로 인해 -2 바이트
-flaps로 인해 -1 바이트-또 다른 시간
-요건으로 인해 -14 바이트 @AndersKaseorg 덕분에 하나의 요소 -5 바이트 만 출력
하면됩니다.

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

이것은 눈에 띄지 않는 시간에 처음 5 개의 테스트 사례에 적용됩니다.
가장 큰 테스트 사례에서 시간이 초과 될 수 있습니다.

일반적으로 이것은 일반적으로 가장 작은 요인의 제곱근에 비례하여 사소하지 않은 요인을 시간으로 반환합니다.
다항식을 바꾸지 않고 모든 경우에 작동하지는 않으며 140 바이트에서 예외적 인 경우를 탐지하기가 어렵습니다.
또한 전체 인수 분해가 아니라 사소한 요소와이 요소에 의한 입력의 나눗셈을 출력합니다.
또한 크기별로 요인을 정렬하지 않습니다.

사용 된 방법은 모든 추가 평가를 위해 표준 시작 값이 2 (표준 다항식이 한 번 적용됨)이고 비표준 다항식 상수가 7 ( 1679에서는 작동하지 않았기 때문에 ) 인 Pollard-Rho-Factoring 입니다 .x^2+11

전체 프로그램 ( 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)

다음과 같이 컴파일하십시오 $ ghc factor.hs( ghc설치되어 있어야 함).
로 실행하십시오 $ ./factor <number>.

예제 실행 :

$ ./factor 187
11

Ungolfed 코드 :

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

g초기 값 으로 호출 하여 중요하지 않은 요소를 계산 합니다. 다항식은 여기에 2로 미리 적용되고 결과 (5)에 다시 적용되므로 g( "where"절에 대한 ) 입력은 항상 gcd-test에 쉽게 사용할 수 있습니다. g(골프 버전은 infix를 사용 #) d두 입력 사이의 차이 로 중요하지 않은 요소 (골프 버전의 인라인 골프 클럽 버전의 where 절에서 )를 계산하려고 시도 g하면 성공하면 해당 요소를 반환합니다. 그렇지 않으면 다시 시도하십시오. 여기서는 사소한 요소 만 반환하는 n경우 출력으로 생성 될 수 있으며, a==b이를 처리하는 올바른 접근 방법은이 이벤트의 시작 값을 변경하거나 다항식을 변경하는 것입니다.


|1<2=s a#(s$s b)|c<-s b=s a#s c내가 생각하는 것으로 대체 될 수 있습니다 :) (또한 : 왜 TIO 링크 를 게시하지 않습니까?)
flawr

의견 제안에 따라 질문을 업데이트했습니다. 이제 하나의 요소 만 출력하면되고 숫자는 복합이어야합니다.

3
추신 : 왜 우리는 골프를
합니까

4
이제 훨씬 더 복잡한 인수 알고리즘을 구현할 수있는 53 바이트가 있습니다.

1
또한 항상 음수가 아니기 abs 때문에 를 꺼낼 수 있습니다 b. (아마도 당신은을 의미 abs$b-a했지만 gcd부정적인 주장을 받아들이고 항상 음이 아닌 결과를 낳습니다.) 이것은 절반 이하의 트윗으로 가져옵니다!
Anders Kaseorg

6

Pari / GP , 137 바이트, ~ 5 초

GP의 내장 타원 곡선 작업 (및 일부 매개 변수 조정) 사용 :

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])))

ecm인자를 반환해야하는 함수입니다. 온라인으로 사용해보십시오!

테스트:

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

언 골프 드 :

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")
}

안타깝게도 요소 2와 3을 처리하면 많은 바이트가 사용됩니다. 2 단계를 추가하는 데 사용할 수있는 바이트 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

공리, 137 바이트 9 분

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)

p () 함수에 대한 테스트를 위해 파일에서 복사 할 항목을 아래에 인수 분해하여 p-1 algo를 구현하는 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)])

결과는 다음과 같습니다.

(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

우분투의 명령 줄 에서이 코드를 실행하는 방법을 정확하게 설명해 주시겠습니까? axiom을 설치하고 골프가 아닌 코드가 포함 된 foo.ax라는 파일을 만들었습니다.

@Lembik 1) foo.input에서 fop.ax 이름 바꾸기 2) 하나의 터미널 또는 xterm에서 Axiom을 실행하십시오. 3) Axiom 터미널에 다음 명령 ")을 읽으십시오."C : absolutepath \ foo " test () 함수. 이것은 Windows에서 수행하는 방법입니다. 단 하나의 Axiom 세션을 열고 ") read"명령으로 파일을로드하는 것으로 보입니다
RosLuP

파일에 문제가있는 경우 @Lembik 나도 괜찮을 것이라고 생각합니다 : 1) Axiom을 실행하십시오. 2) 쓰기) Axiom 프로그램의 <return>에 시간. Axiom 프로그램에서 배열 vA, 함수 p () 및 test () 4) write test () <return>
RosLuP

@Lembik 얼마나 시간이 걸립니까?
RosLuP

1

공리, 10 분 + 31 초

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 ()는 함수 rho, 하나의 137 바이트 함수입니다. ungolfed z ()를 rho ()라고 부릅니다. gcd (0, n) = n이라고 가정하면 루프가 멈추고 실패 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)]) 

결과 (z ()는 모두 괜찮지 만 마지막 숫자 1751952685614616185916001760791655006749는 고려되지 않은 상태로 유지됨 (10 분))

(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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.