编写程序以验证Erdős–Straus猜想


15

编写程序,以验证Erdős-Straus猜想
程序应该采取作为输入一个整数n3 <= n <= 1 000 000),并打印三重身份满足整数4/n = 1/x + 1/y + 1/z0 < x < y < z

最短的代码获胜。

一些例子:

3 => {1, 4, 12}
4 => {2, 3, 6}
5 => {2, 4, 20}
1009 => {253, 85096, 1974822872}
999983 => {249996, 249991750069, 62495875102311369754692}
1000000 => {500000, 750000, 1500000}

请注意,由于存在多种解决方案,因此程序可能会为这些数字打印其他结果。


程序需要输出所有可能的解决方案还是仅输出一个?例如,对于n = 5,有2种可能性。
伊兹林2014年

1
仅一个就足够了。
2014年

2
根据规范,您唯一的测试用例不是有效输入,这在某种程度上具有误导性。
彼得·泰勒

我将其更改,示例添加了durron597。
2014年

我添加了该示例,因为我的研究表明这是一件特别困难的事情。最难的有都是全等素数对{1, 121, 169, 289, 361, 529}模840
durron597

Answers:


12

Ruby,119106个字符

f=->s,c,a{m=s.to_i;c<2?m<s||(p a+[m];exit):(1+m...c*s).map{|k|f[s/(1-s/k),c-1,a+[k]]}}
f[gets.to_r/4,3,[]]

该代码使用最小界限为每个变量,例如n/4<x<3n/4,类似地对于y。甚至最后一个示例都返回瞬时值(在此处尝试)。

例子:

> 12
[4, 13, 156]

> 123
[31, 3814, 14542782]

> 1234
[309, 190654, 36348757062]

> 40881241801
[10220310451, 139272994276206121600, 22828913614743204775214996005450198400]

很酷的解决方案,但是界限有点紧,因为1 000 000的程序会找到更大的解决方案(请参见我的示例)。
2014年

1
@ user2992539我的代码按字典顺序返回第一个解决方案(250001 <500000)。
2014年

7

Mathematica 62

这种简单的解决方案在大多数情况下都可以正常工作。

f@n_ := FindInstance[4/n == 1/x + 1/y + 1/z && 0 < x < y < z, {x, y, z}, Integers]

示例和时间(以秒为单位)

AbsoluteTiming[f[63]]
AbsoluteTiming[f[123]]
AbsoluteTiming[f[1003]]
AbsoluteTiming[f[3003]]
AbsoluteTiming[f[999999]]
AbsoluteTiming[f[1000000]]

{0.313671,{{x-> 16,y-> 1009,z-> 1017072}}}
{0.213965,{{x-> 31,y-> 3814,z-> 14542782}}}
{0.212016,{{x -> 251,y-> 251754,z-> 63379824762}}}
{0.431834,{{x-> 751,y-> 2255254,z-> 5086168349262}}}
{1.500332,{{x-> 250000,y- > 249999750052,z-> 1201920673328124750000}}}
{1.126821,{{x-> 375000,y-> 1125000,z-> 2250000}}}


但这并不构成完整的解决方案。有一些数字无法解决。例如,

AbsoluteTiming[f[30037]]
AbsoluteTiming[f[130037]]

{2.066699,FindInstance [4/30037 == 1 / x + 1 / y + 1 / z && 0 <x <y <z,{x,y,z},整数]}
{1.981802,FindInstance [4/130037 = = 1 / x + 1 / y + 1 / z && 0 <x <y <z,{x,y,z},整数]}


适合正确工作的正确工具。+1
威廉·巴博萨

3
@WilliamBarbosa我认为这FindInstance不是正确的工具,因为它不能保证结果...
Howard

2
@Howard我实际上是在谈论Mathematica
William Barbosa

Reduce似乎可以解决顽固的案件,尽管这通常需要时间。例如15分钟,找到n = 10037的82个解决方案。
DavidC

3

C#

Disclamer:这不是认真的答案

这只是暴力破解了从1到1 << 30的所有可能性。它很大,很慢,我什至不知道它是否能正常工作,但是它确实遵循了规范,因为它每次都会检查情况,所以很好。我没有测试过,因为ideone的程序时间限制为5秒,因此无法完成执行。

(如果有人在想:这是一个高达308个字节的字节

static double[]f(double n)
{
    for(double x=1;x<1<<30;x++)
    {
        for(double y=1;y<1<<30;y++)
        {
            for(double z=1;z<1<<30;z++)
            {
                if(4/n==1/x+1/y+1/z)
                    return new[]{x,y,z};
            }
        }
    }
    return null;
}

更新:修复它,因此它实际上可以工作


2
不起作用(提示:整数除法)。
霍华德

可能由于舍入错误而无法使用。
2014年

@ user2992539它对我有用,我用5输入进行了测试,并给出了正确的结果(2, 4, 20
ChristophBöhmwalder2014年

@HackerCow它可能不适用于大整数。
2014年

1
@HackerCow您当然可以通过以y = x + 1和z = y + 1开头来节省时间。使用等效检查4xyz = n(xy + yz + xz)可能会更快,尽管我接受这是一个较长的表达式,并且也存在舍入问题。
Alchymist 2014年

3

Python 2,171字节

from sympy import*
def f(n):
 for d in xrange(1,n*n):
  for p in divisors(4*d+n*n):
   q=(4*d+n*n)/p;x=(n+p)/4;y=(n+q)/4
   if (n+p)%4+(n+q)%4+n*x*y%d<1:return x,y,n*x*y/d

在线尝试!

第一个答案的速度足以进行详尽的测试。这是能够找到的所有3≤解决方案ñ ≤1000000大约为24分钟合计,平均每1.4毫秒。

怎么运行的

将4 / n = 1 / x + 1 / y + 1 / z改写为z = n · x · y / d,其中d = 4· x · y - n · x - n · y。然后,我们可以因子4· d + Ñ 2 =(4· X - ñ)·(4· ÿ - Ñ),这使我们快得多的方式来搜索Xÿ只要d是小。给定X < ÿ < Ž,我们至少可以证明d <3· Ñ 2 /4(因此结合在外环),尽管实际上它往往是小得多-95%的时间,我们可以使用d = 1、2或3。最坏的情况是n = 769129,其最小d是1754(这种情况大约需要1秒)。


1

Mathematica,99个字节

f[n_]:=(x=1;(w=While)[1>0,y=1;w[y<=x,z=1;w[z<=y,If[4/n==1/x+1/y+1/z,Return@{x,y,z}];++z];++y];++x])

这是相当幼稚的蛮力,因此伸缩性并不佳。我肯定会达到一百万(所以暂时不要认为这是无效的)。n = 100需要半秒钟,但n = 300已经需要12秒。


1

Golflua 75

n从提示符读取(在终端中调用之后),但是基本上像Calvin的Hobbies解决方案那样进行迭代:

n=I.r()z=1@1~@y=1,z-1~@x=1,y-1?4*x*y*z==n*(y*z+x*z+x*y)w(n,x,y,z)~$$$z=z+1$

上面的非高尔夫Lua版本是

n=io.read()
z=1
while 1 do
   for y=1,z-1 do
      for x=1,y-1 do
         if 4*x*y*z==n*(y*z+x*z+x*y) then
            print(n,x,y,z)
            return
         end
      end
   end
   z=z+1
end

例子:

n=6     -->     3      4     12
n=12    -->     6     10     15
n=100   -->    60     75    100
n=1600  -->  1176   1200   1225

1

Python,117

n=input();r=range;z=0
while 1:
 z+=1
 for y in r(z):
  for x in r(y):
    if 4*x*y*z==n*(y*z+x*z+x*y):print x,y,z;exit()

例:

16 --> 10 12 15

没什么特别的。


1
如果只调用一次,为什么要定义一个函数呢?
isaacg 2014年

@isaacg它需要以某种方式停止,但是使用exit()它确实可以缩短它。
加尔文的业余爱好

0

C#-134

好吧,我之前在这里发布了答案,但这并不是那么严重。碰巧的是,我经常很无聊,所以我打了一下高尔夫球。

它从技术上正确计算了所有示例(我没有尝试最后两个示例,因为ideone再次施加了5秒的时间限制),但是第一个示例产生了正确的结果(不一定是您计算出的结果,而是一个正确的结果)。这奇怪的数字输出坏了(我不知道为什么),它给10, 5, 25(这是根据维基百科的一个有效的答案)。

现在有134个字节,我可能还可以打更多一点。

float[]f(float n){float x=1,y,z;for(;x<1<<30;x++)for(y=1;y<x;y++)for(z=1;z<y;z++)if(4/n==1/x+1/y+1/z)return new[]{x,y,z};return null;}

0

Haskell-150个字符

main = getLine >>= \n -> (return $ head $ [(x,y,z) | x <- [1..y], y <- [1..z], z <- [1..], (4/n') == (1/x) + (1/y) + (1/z)]) where n' = read n

这应该可行,但是我还没有编译它。几乎可以肯定,它非常缓慢。它检查有效整数的每个可能的三元组,并且在看到有效的集合时应停止。

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.