费马的分解助手


19

我们希望因式分解半素。这项挑战的目标是找到两个小整数和,用Fermat方法将分解为,从而可以轻松的因数。ü v ü v ñ ñNuvuvNN

任务

给定一个半素数 和一个正整数,我们将和定义为:ķ X ÿNkxy

Ŷ=X2-ķÑ

x=kN
y=x2kN

步骤#1-查找k

首先,您需要找到k的最小可能值,以k使y平方数也称为完美平方)。

这允许通过Fermat分解因子方法的单次迭代分解kN。更具体地说,这立即导致:ķñ

kN=(x+y)×(xy

(更新:此序列现在发布为A316780

步骤#2-分解ķ

然后,您必须找到两个正整数üv,使得:

c u = x +

uv=ķ
dv=X-
cu=x+y
dv=xy

其中CdN的素因N

摘要

您的任务是编写一个程序或函数,将作为输入,并以任何顺序和任何合理的格式打印或输出和。ü vNuv

让我们考虑N=199163

步骤1

的最小可能值是,这给:40ķ40

ÿ=28232-40×199163=7969329-7966520=2809=532ķÑ=2823+53×2823-53ķÑ=2876×2770

X=40×199163=2823
ÿ=28232-40×199163=7969329-7966520=2809=532
ķñ=2823+53×2823-53
ķñ=2876×2770

第2步

的正确因式分解为,因为:ķ = 4 × 10ķķ=4×10

ķñ=2876×2770
ķñ=719×4×277×10
N=719×277

因此,正确答案应该是或。[4,10][10,4]

规则

  • 不需要严格执行上述两个步骤。您可以自由使用任何其他方法,只要它找到和的正确值即可。uv
  • uvN
  • 输入保证为半素数。
  • 这是代码高尔夫球,因此最短的答案以字节为单位。
  • 禁止出现标准漏洞。

测试用例

N          | k    | Output
-----------+------+------------
143        | 1    | [   1,  1 ]
2519       | 19   | [   1, 19 ]
199163     | 40   | [   4, 10 ]
660713     | 1    | [   1,  1 ]
4690243    | 45   | [   9,  5 ]
11755703   | 80   | [  40,  2 ]
35021027   | 287  | [   7, 41 ]
75450611   | 429  | [ 143,  3 ]
806373439  | 176  | [   8, 22 ]
1355814601 | 561  | [  17, 33 ]
3626291857 | 77   | [   7, 11 ]
6149223463 | 255  | [  17, 15 ]
6330897721 | 3256 | [  74, 44 ]

示例实施

fNuv

gNuvNO(1)


我们是否保证输入N实际上是半素数?
格雷格·马丁

@GregMartin是的。
Arnauld

Answers:


8

Mathematica,81 79字节

感谢Martin Ender节省了2个字节!

(c=Ceiling;For[j=0;z=E,c@z>z,p=(x=c@Sqrt[j+=#])+{z=Sqrt[x^2-j],-z}];p/#~GCD~p)&

将半素数作为输入并返回有序对正整数的纯函数。的For确切过程中的问题描述(使用循环工具#用于代替的输入n),以x所定义的有,虽然我们存储j = k*n,而不是k本身和z=Sqrt[y]代替y本身。我们还在循环p={x+z,x-z}内进行计算For,最终节省了一个字节(类似于第七次尝试)。然后,两个期望因子为(x+z)/GCD[#,x+z](x-z)/GCD[#,x-z],简洁表达式p/#~GCD~p直接将其作为有序对进行计算。

好奇心:我们想循环直到z为整数;但是由于我们Ceiling已经在代码中使用了它,所以它节省了两个字节!IntegerQ@z来定义c=Ceiling(这花费了四个字节,如Mathematica高尔夫球手所知道的),然后测试是否c@z>z。我们必须初始化z为某种东西,并且某种东西最好不要是整数,这样循环才能开始。幸运的E是一个简洁的选择。


4

JavaScript(ES7),86 81字节

n=>(g=k=>(y=(n*k)**.5+1|0,y+=(y*y-n*k)**.5)%1?g(k+1):n*u++%y?g(k):[--u,k/u])(u=1)

编辑:由于@Arnauld,节省了4个字节。


4

Python 2中,127 121 117 111 107 104个 101 99个字节

-1个字节归功于Neil,-3个字节归功于ovs

N=input()
k=u=1;p=m=.5
while p%1:p=1+(k*N)**m//1;p+=(p*p-k*N)**m;k+=1
while N*u%p:u+=1
print~-k/u,u

在线尝试!

好奇心:

p初始化为,.5以便循环条件在第一次迭代时为true。请注意,存储p(as x+ sqrt(y))比分别存储x和短y


x*x代替x**2
尼尔,

@Neil是的,当然。谢谢
数学迷

1

公理,131115字节

v(x)==floor(x^.5)::INT;r(n)==(k:=0;repeat(k:=k+1;x:=1+v(k*n);y:=v(x*x-k*n);x^2-y^2=k*n=>break);[w:=gcd(k,x+y),k/w])

解决问题的函数是上面的r(n)。高尔夫和测试

vv(x)==floor(x^.5)::INT    

--(x-y)*(x+y)=k*n
rr(n)==
  k:=0
  repeat
     k:=k+1
     x:=1+vv(k*n)
     y:=vv(x*x-k*n)
     x^2-y^2=k*n=>break
  [w:=gcd(k,x+y),k/w]


(4) -> [[i,r(i)] for i in [143,2519,199163,660713,4690243,11755703]]
   (4)
   [[143,[1,1]], [2519,[1,19]], [199163,[4,10]], [660713,[1,1]],
    [4690243,[9,5]], [11755703,[40,2]]]
                                                      Type: List List Any
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.