我目前正在尝试使用Python解决Project Euler问题(我今天才提到的)。我正在工作的问题是问题5,其中
2520是可以除以1到10之间的每个数字的最小数字,没有任何余数。
从1到20的所有数字均可被整除的最小正数是多少?
之前我已经解决了使用Java的问题,所以使用与之前相同的方法,我只是创建了一个迭代的循环,但似乎我的代码永远不会结束。
的Python:
i = 1
while 1:
if i%2 == 0 and i%3==0 and i%4==0 and i%5==0 and i%6==0 and i%7==0 and i%8==0 and i%9==0 and i%10==0 and i%11==0 and i%12==0 and i%13==0 and i%14==0 and i%15==0 and i%16==0 and i%17==0 and i%18==0 and i%19==0:
print i
break
i+=1
爪哇:
public class p5
{
public static void main(String[] args)
{
for (int i=1;;i++)
{
if (i%1==0&&i%2==0&&i%3==0&&i%4==0&&i%5==0&&i%6==0&&i%7==0&&i%8==0&&i%9==0&&i%10==0&&i%11==0&&i%12==0&&i%13==0&&i%14==0&&i%15==0&&i%16==0&&i%17==0&&i%18==0&&i%19==0&&i%20==0)
{
System.out.println(i);
break;
}
}
}
}
Java在我的计算机上执行了不到3秒钟,而Python代码似乎永远不会结束。有什么提示吗?
修改
显然我输错了,导致它永远不会结束。然而,即使整个事情写得正确(与我的Java输出相同),它仍然需要 1分20秒,而对于Java,它需要大约1 - 2秒。我做错了吗?或者Python的表现不好(不应该是afaik)
答案 0 :(得分:4)
原始int
s的算术在Java中要快得多,然后在CPython中使用完整的整数对象,即你所看到的30倍的性能差异对你的代码来说并不奇怪。
请注意,该算法效率非常低,并且对于稍大的输入不起作用,例如,对于1到50的数字(它需要太长时间,并且正确的结果大于Java中的max int / long)。
使用更高效的算法,我需要〜100
micro - 秒来计算机器上1到100之间所有数字的结果:
#!/usr/bin/env python
from functools import reduce
def gcd(a, b):
"""Greatest common divisor (factor)."""
while b: # Euclid's algorithm
a, b = b, a % b
return a
def lcm(*args):
"""Least common multiple."""
# lcm(a, b, c) == lcm(lcm(a, b), c)
return reduce(lambda a, b: a * b // gcd(a, b), args)
def f(n):
"""Smallest positive number evenly divisible by all numbers from 1
to n including.
"""
return lcm(*range(1, n + 1))
print(f(10)) # -> 2520
print(f(50)) # -> 3099044504245996706400
#!/usr/bin/env python
import timeit
from functools import partial
def measure():
for n in [10, 50, 100]:
print("%d: %5.2f microseconds" % (n, timeit.timeit(partial(f, n),
number=1000*1000)))
measure()
答案 1 :(得分:2)
使用pypy,我的纯粹强力解决方案需要大约250毫秒:
i = 20
while 1:
if i%20 == 0 and i%19==0 and i%18==0 and i%17==0 and i%16==0 and i%15==0 and i%14==0 and i%13==0 and i%12==0 and i%11==0:
print i
break
i+=20
更优雅应该使用最大公约数和最小公倍数之类的东西。