找到可以被1到20的所有数字整除的最小正数?

时间:2017-05-28 15:00:21

标签: python

这是一个项目欧拉挑战,我试图找到可以被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)

这仍在处理中,到目前为止我的终端看起来像这样

FloatLayout

3 个答案:

答案 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

也许我有逻辑错误?!