Jal*_*lxP 4 python algorithm search
我目前正在经历欧拉项目.我已经开始使用JavaScript了,昨天我已经切换到Python,因为我陷入了一个似乎很复杂的问题,用Javascript解决但很容易用Python解决,所以我决定从第一个问题开始蟒蛇.
我遇到问题5,它要求我找到最小的正数,它可以被1到20的所有数字整除.
我知道如何使用纸和笔来解决它,我已经使用编程解决了问题,但是为了优化它,我在欧拉项目的论坛中越过了这个解决方案.
它看起来很优雅,与我的相比它速度相当快,很荒谬,因为解决1到1000号的相同问题需要大约2秒钟,我需要几分钟.
我试图理解它,但我仍然很难理解它到底在做什么.这里是:
i = 1
for k in (range(1, 21)):
if i % k > 0:
for j in range(1, 21):
if (i*j) % k == 0:
i *= j
break
print i
Run Code Online (Sandbox Code Playgroud)
它最初由名为lassevk的用户发布
这个代码计算最小公倍数从数字1
到20
(或任何其他range
使用).
它从该范围开始1
,然后对于k
该范围内的每个数字,它检查是否k
是因子i
,如果不是(即何时i % k > 0
),则将该数字作为因子.
然而这样做i *= k
不会产生最常见的多,因为例如当你i = 2
和k = 6
它足以繁衍i
的3
有i % 6 == 0
,所以内环发现数最少j
,从而i*j
具有k
的一个因素.
到底每隔数k
的范围内是这样的,i % k == 0
和我们总是添加最小因素,以做到这一点,因此我们计算了至少公倍数.
也许准确地显示值的变化有助于理解过程:
i = 1
k = 1
i % k == 0 -> next loop
i = 1
k = 2
i % k == 1 > 0
j = 1
if (i*j) % k == 1 -> next inner loop
j = 2
if (i*j) % k == 0
i *= j
i = 2
k = 3
i % k == 2 > 0
j = 1
if (i*j) % k == 2 -> next inner loop
j = 2
if (i*j) % k == 4 % 3 == 1 -> next inner loop
j = 3
if (i*j) % k == 6 % 3 == 0
i *= j
i = 6
k = 4
i % k == 2 > 0
j = 1
if (i*j) % k == 6 % k == 2 -> next inner loop
j = 2
if (i*j) % k == 12 % k == 0
i *= j
i = 12
k = 5
i % k == 2 > 0
j = 1
if (i*j) % k == 12 % k == 2 -> next inner loop
j = 2
if (i*j) % k == 24 % k == 4 -> next inner loop
j = 3
if (i*j) % k == 36 % k == 1 -> next inner loop
j = 4
if (i*j) % k == 48 % k == 3 -> next inner loop
j = 5
if (i*j) % k == 60 %k == 0
i *= j
i = 60
...
Run Code Online (Sandbox Code Playgroud)
你可以立即注意到一些事情:
range(1, 21)
可以安全地改变range(2, 21)
,因为1
从来没有做任何事情k
都是内部循环结束时的素数,j=k
并且最终会结束i *= k
.这是预期的,因为k
它是一个素数,它没有因素,所以没有选择较小的数字j
,将成i
倍数k
.i
乘以一个数字,j < k
以便所有因子k
现在都在i
.