这是一个项目欧拉挑战,我试图找到可以被1到20的所有数字整除的最小正数?
我提出的逻辑似乎运行得很慢。它已经运行了最后4分钟,但仍然没有找到该号码。我试图弄清楚a)这个逻辑是否正确? b)为什么这需要这么长时间? c)有人能给我一个更有效的替代逻辑的暗示。
# 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
# What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
smallest_num = 2520
while smallest_num >= 2520:
divisor = 2
while smallest_num % divisor == 0 and divisor < 21:
print("Smalles num = {} and Divisor = {}").format(smallest_num, divisor)
divisor += 1
smallest_num += 1
print("Smallest number is: {}").format(smallest_num)
这仍在处理中,到目前为止我的终端看起来像这样
答案 0 :(得分:1)
这是你的方法“正常”运行(使用自由一词),但正如@James提到的那样,它会花费相当多的时间作为循环。
divisors = np.arange(1, 21)
num = 2520
while True:
if np.all(num % divisors == 0):
print(num)
break
num += 1
一种更好的方法(适用于Python 3.x)。直接来自类似的question:
import functools
import math
functools.reduce(lambda x,y: x*y//math.gcd(x, y), range(1, 21))
Out[27]: 232792560
答案 1 :(得分:1)
以下代码可以正常使用。
#!/usr/bin/env python
import math
#Generating primes
divisorMax = 20;
top = divisorMax + 1 #divisor max is the upper limit
p = [x for x in range(2,top)]
for num in p:
for idx in range(2,(top//num)+1):
if num*idx in p:
p.remove(num*idx)
#Solving the problem
result = 1;
for i in range(0, len(p)):
a = math.floor(math.log(divisorMax) / math.log(p[i]));
result = result * (p[i]**a);
print(result)
您正在使用强力技术来计算数字,这很容易理解和写入,但需要花费很多时间。
我正在使用 Prime Factorisation 技术解释here。
答案 2 :(得分:0)
我不是百分百肯定,如果我的解决方案真的是正确的,但我想它确实很快。
首先,我们不需要关心所有的除数,因为大多数是相互的倍数。因此,最好的方法是向后计算除数,例如从20开始减少到1。
我查看了素数,解决方案需要是10以上所有素数的倍数,而且我们需要检查20除数,其余的可以忽略,因为当测试除数18时,9将起作用等等。
所以我多了11 * 13 * 17 * 19 * 20.结果是923780,并且至少可以被素数+ 20整除。
所以我会从923780开始,每923780号只测试一次。
smallest_num = 923780
steps = 923780
while True:
divisor = 19
while smallest_num % divisor == 0 and divisor > 10:
print("Smalles num = {} and Divisor = {}").format(smallest_num, divisor)
divisor -= 1
if divisor == 10:
print("Smallest number is: {}").format(smallest_num)
break
smallest_num += steps
也许我有逻辑错误?!