Python 找到能被1到20之间的所有数整除的最小正数?

Python 找到能被1到20之间的所有数整除的最小正数?,python,Python,这是一个Euler项目的挑战,我试图找到最小的正数,它可以被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

这是一个Euler项目的挑战,我试图找到最小的正数,它可以被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)
#2520是最小的数字,可以被1到10之间的每个数字除,没有余数。
#能被1到20的所有数整除的最小正数是多少?
最小数量=2520
当最小_num>=2520时:
除数=2
当最小的_num%除数==0且除数<21时:
打印(“Smalles num={}和除数={}”).format(最小值,除数)
除数+=1
最小_num+=1
打印(“最小值为:{}”)。格式(最小值)
这仍在处理中,到目前为止,我的终端看起来像这样

这里是您的方法“正确地”运行(自由地使用术语),但正如@James所提到的,作为一个循环,它将花费惊人的时间

divisors = np.arange(1, 21)
num = 2520
while True:
    if np.all(num % divisors == 0):
        print(num)
        break
    num += 1
更好的方法(对于Python3.x)。直接从类似的公司获得:

这里是您的方法“正确地”运行(自由地使用术语),但是正如@James所提到的,作为一个循环,它将花费惊人的时间

divisors = np.arange(1, 21)
num = 2520
while True:
    if np.all(num % divisors == 0):
        print(num)
        break
    num += 1
更好的方法(对于Python3.x)。直接从类似的公司获得:


我不是100%确定,如果我的解决方案真的是正确的,但我想是的,而且速度相当快

首先,我们不需要关心所有的除数,因为大多数除数是彼此的倍数。所以最好的方法是倒着数数除数,比如从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

也许我有逻辑错误

我不是100%确定,如果我的解决方案真的是正确的,但我想是的,而且速度相当快

首先,我们不需要关心所有的除数,因为大多数除数是彼此的倍数。所以最好的方法是倒着数数除数,比如从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

也许我有逻辑错误

以下代码工作正常

#!/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)
您正在使用蛮力计算数字,这很容易理解和编写,但需要花费大量时间


我使用的是已解释过的素因子分解技术。

以下代码运行良好

#!/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)
您正在使用蛮力计算数字,这很容易理解和编写,但需要花费大量时间


我使用的是素因子分解技术解释。

此代码将永远运行。您可以对其进行优化,使其不会检查1到20之间的每个数字。例如,通过检查20,您也在检查1、2、4、5和10。当最小的\u num>=2520时,
没有理由停止,因此不,您的逻辑不正确。另外,给出2520的原因是,您可以首先在较小的问题上测试您的逻辑。尝试编写一个不包含2520的程序,但在考虑从1到10的数字时,生成2520作为输出。对于编程循环,通常最好手动写出前几次迭代中变量的变化情况。这通常可以诊断关于循环是否会停止或达到其目标的问题。你正在寻找最不常见的倍数,而这种蛮力方法是最糟糕的方法。你要做的是素因子分解。或者使用欧几里得算法,找到GCD并进行除法。此代码将永远运行。您可能会对其进行优化,使其不会检查1到20之间的每个数字。例如,通过检查20,您也在检查1、2、4、5和10。当最小的\u num>=2520时,
没有理由停止,因此不,您的逻辑不正确。另外,给出2520的原因是,您可以首先在较小的问题上测试您的逻辑。尝试编写一个不包含2520的程序,但在考虑从1到10的数字时,生成2520作为输出。对于编程循环,通常最好手动写出前几次迭代中变量的变化情况。这通常可以诊断关于循环是否会停止或达到其目标的问题。你正在寻找最不常见的倍数,而这种蛮力方法是最糟糕的方法。你要做的是素因子分解。或者使用欧几里德算法,找到GCD并进行除法。