为什么我的代码不能用于测试输入? - 项目Euler 549

时间:2017-07-15 19:25:17

标签: python debugging

可以找到此问题here,如下所示:

  

最小数m,10除以m!是m = 5.

     

最小数m,25除以m!是m = 10.

     

设s(n)为最小数m,使得n除以m!。

     

所以s(10)= 5且s(25)= 10.

     

令S(n)为Σs(i)2≤i≤n。

     

S(100)= 2012。

     

找到S(10⁸)。

这是我的代码,正如你所看到的,它是一个完全强力的解决方案,它似乎在几分钟内运行10 ** 8,除此之外,s(10)= 5和s( 25)= 10(根据我的程序),正如问题所说,除此之外,我还生成了一些随机数并检查它们:

def is_int(x): return int(x) == x

factorials = [1] 
for i in range(1, 25):
    factorials.append(factorials[-1] * i)

def s(n):
    i = 2 
    while not is_int(factorials[i] / n): i += 1
    return i

def S(x):
    S = 0 

    for n in range(2, x + 1): 
        if n % 10 ** 5 == 0: print("{0}% done!".format(n / x * 100))
        S += s(n)   

    return S

我检查了预先计算的因子值,它们是正确的。

S(100)的输出是1221,当它应该是2012时,这是我的值 对于s(n):

s(2) = 2
s(3) = 3
s(4) = 4
s(5) = 5
s(6) = 3
s(7) = 7
s(8) = 4
s(9) = 6
s(10) = 5
s(11) = 11
s(12) = 4
s(13) = 13
s(14) = 7
s(15) = 5
s(16) = 6
s(17) = 17
s(18) = 6
s(19) = 19
s(20) = 5
s(21) = 7
s(22) = 11
s(23) = 19
s(24) = 4
s(25) = 10
s(26) = 13
s(27) = 9
s(28) = 7
s(29) = 20
s(30) = 5
s(31) = 19
s(32) = 8
s(33) = 11
s(34) = 17
s(35) = 7
s(36) = 6
s(37) = 19
s(38) = 19
s(39) = 13
s(40) = 5
s(41) = 20
s(42) = 7
s(43) = 20
s(44) = 11
s(45) = 6
s(46) = 19
s(47) = 19
s(48) = 6
s(49) = 14
s(50) = 10
s(51) = 17
s(52) = 13
s(53) = 19
s(54) = 9
s(55) = 11
s(56) = 7
s(57) = 19
s(58) = 20
s(59) = 20
s(60) = 5
s(61) = 20
s(62) = 20
s(63) = 7
s(64) = 8
s(65) = 13
s(66) = 11
s(67) = 20
s(68) = 17
s(69) = 20
s(70) = 7
s(71) = 19
s(72) = 6
s(73) = 20
s(74) = 20
s(75) = 10
s(76) = 19
s(77) = 11
s(78) = 13
s(79) = 19
s(80) = 6
s(81) = 9
s(82) = 20
s(83) = 19
s(84) = 7
s(85) = 17
s(86) = 20
s(87) = 20
s(88) = 11
s(89) = 20
s(90) = 6
s(91) = 13
s(92) = 19
s(93) = 20
s(94) = 19
s(95) = 19
s(96) = 8
s(97) = 20
s(98) = 14
s(99) = 11
s(100) = 10

请问为什么代码不起作用?

2 个答案:

答案 0 :(得分:3)

这个功能很可能是所有问题的根源:

def is_int(x): 
    return int(x) == x

如果您正在尝试检查某个数字是否可被其他数字整除,则这不是最好的方法。特别是对于更高阶数,浮点表示往往会有点冒险。只需使用%运算符,如下所示:

def s(n):
    i = 2 
    while factorials[i] % n: 
        i += 1
    return i

另外,如果你想要S(100),你可能想要将阶乘法一直存储到100!太?

factorials = [1] 
for i in range(1, 101): # note this
    factorials.append(factorials[-1] * i)

现在:

In[]:
S(100)

Out[]:
2012

答案 1 :(得分:2)

您的比较函数def is_int(x): return int(x) == x遇到了浮点数精度有限的问题。

for i in range(1,100):
    fraction = 10**i/(10**i-1)
    if fraction == int(fraction):
        print(i)
        break

返回16

如果不是检查浮点值和整数

之间的相等性,那么计算将是安全的
while not is_int(factorials[i] / n): 
    i += 1

您检查了模数是否为0,因此factorials[i]可以除以n

while not (factorials[i] % n == 0):
    i += 1

然后,在增加计算的因子数后,S(100)会根据需要返回2012

编辑: while not (factorials[i] % n == 0):可以使用0的错误,因此可以像COLDSPEED指出的那样缩短为while factorials[i] % n: