Euler Project problem #12 Python 代码给出了奇怪的结果
Euler Project problem #12 Python code gives weird results
我正在尝试解决 Project Euler 的 problem number 12。这是问题所在:
The sequence of triangle numbers is generated by adding the natural
numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7
= 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
- 1: 1
- 3: 1,3
- 6: 1,2,3,6
- 10: 1,2,5,10
- 15: 1,3,5,15
- 21: 1,3,7,21
- 28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five
divisors.
What is the value of the first triangle number to have over five
hundred divisors?
我定义了两个函数来完成这项工作:
1) allfactor(x)
:这给了我们一个列表形式的给定数字的所有因子。示例:allfactor(10)
给我们 [1, 2, 5, 10]
2)TriangularNo(x)
:这给了我们第 n 个三角数。例子 TriangularNo(5)
给我们 5
这是我写的完整代码:
facs=[]
def allfacof(x):
for i in range(1,int(x/2)+1):
if x%i==0:
facs.append(i)
else:
pass
facs.append(x)
return(facs)
def TriangularNo(x):
no=0
for i in range(1,x+1):
no=no+i
return(no)
a=0 # a will tell us the number of iterations
while True:
a+=1
N=TriangularNo(a)
length=(len(allfacof(N)))
if int(length)>=500:
print(N)
break
else:
pass
当我 运行 这段代码时,我得到 1378
作为输出,这显然是错误的,因为 len(allfacof(1378))
结果是 8
而不是 500
按照问题的要求。
注意在 while
循环中,我使用 if int(length)>=500:
所以这意味着当我的代码 运行s, length
以某种方式获得值 = 500 但是当我运行 单独的函数它说它的长度是 8。
我只是找不到错误。请帮助我
问题是您将 facs
用作全局变量并且您只是附加到项目。您应该使它成为 allfacof() 的成员,以便它在每个值后清除。
如果你查看 facs
然后你会发现它等于
1, 1, 3, 1, 2, 3, 6, 1, 2, 5, 10 ...
虽然将 facs
移动到 all_factors_of()
可以解决您眼前的问题,但此代码的下一个问题是性能。让我们首先考虑三角形数的生成。 @Voo建议的优化:
def TriangularNo(n):
return n * (n + 1) / 2
如果我们正在寻找 任意 三角形数字, 很好——但我们不是。我们正在寻找 连续 三角形数字,因此在这种情况下,公式 减慢 我们的代码!按顺序进行时,您只需进行几次加法即可获得下一个三角形编号——但使用公式时,您需要进行加法、乘法和除法!如果你按顺序去更贵。由于我们 是 按顺序进行,这似乎是对 Python 生成器的完美使用:
def triangular_number_generator():
triangle = number = 1
while True:
yield triangle
number += 1
triangle += number
这清楚地表明了获得下一个三角形编号所需的两个加法。现在让我们考虑一下您的因式分解函数:
您的因式分解函数在按顺序 生成因数时会降低性能。但我们只关心 个因素 ,顺序无关紧要。所以当我们分解 28 时,我们可以同时将 1 和 28 添加到因子列表 。同上 2 和 14——使 14 成为我们的新上限。类似地 4 和 7,其中 7 成为新的上限。所以我们更快地收集因子并快速降低我们需要检查的上限。这是代码的其余部分:
def factors_of(number):
divisor = 1
limit = number
factors = []
while divisor <= limit:
if number % divisor == 0:
factors.append(divisor)
remainder = number // divisor
if remainder != divisor:
factors.append(remainder)
limit = remainder - 1
divisor += 1
return factors
triangular = triangular_number_generator()
number = next(triangular)
factors = factors_of(number)
while len(factors) <= 200:
number = next(triangular)
factors = factors_of(number)
print(number)
比较如何?如果我们 运行 您的固定代码的下限 > 200 个因子,则需要大约 分钟 才能得出答案 (2031120)。上面的代码大约需要 秒 的 1/3。现在考虑达到 > 500 个因素需要多长时间。最后,实现既定目标:
What is the value of the first triangle number to have over five
hundred divisors?
你的原始代码中的这个比较:
if int(length)>=500:
需要改为:
if length > 500:
尽管因子计数的跳跃方式对 500 没有影响。但是对于较小的限制,对于测试,它会产生影响。
我正在尝试解决 Project Euler 的 problem number 12。这是问题所在:
The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
- 1: 1
- 3: 1,3
- 6: 1,2,3,6
- 10: 1,2,5,10
- 15: 1,3,5,15
- 21: 1,3,7,21
- 28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
我定义了两个函数来完成这项工作:
1) allfactor(x)
:这给了我们一个列表形式的给定数字的所有因子。示例:allfactor(10)
给我们 [1, 2, 5, 10]
2)TriangularNo(x)
:这给了我们第 n 个三角数。例子 TriangularNo(5)
给我们 5
这是我写的完整代码:
facs=[]
def allfacof(x):
for i in range(1,int(x/2)+1):
if x%i==0:
facs.append(i)
else:
pass
facs.append(x)
return(facs)
def TriangularNo(x):
no=0
for i in range(1,x+1):
no=no+i
return(no)
a=0 # a will tell us the number of iterations
while True:
a+=1
N=TriangularNo(a)
length=(len(allfacof(N)))
if int(length)>=500:
print(N)
break
else:
pass
当我 运行 这段代码时,我得到 1378
作为输出,这显然是错误的,因为 len(allfacof(1378))
结果是 8
而不是 500
按照问题的要求。
注意在 while
循环中,我使用 if int(length)>=500:
所以这意味着当我的代码 运行s, length
以某种方式获得值 = 500 但是当我运行 单独的函数它说它的长度是 8。
我只是找不到错误。请帮助我
问题是您将 facs
用作全局变量并且您只是附加到项目。您应该使它成为 allfacof() 的成员,以便它在每个值后清除。
如果你查看 facs
然后你会发现它等于
1, 1, 3, 1, 2, 3, 6, 1, 2, 5, 10 ...
虽然将 facs
移动到 all_factors_of()
可以解决您眼前的问题,但此代码的下一个问题是性能。让我们首先考虑三角形数的生成。 @Voo建议的优化:
def TriangularNo(n):
return n * (n + 1) / 2
如果我们正在寻找 任意 三角形数字,很好——但我们不是。我们正在寻找 连续 三角形数字,因此在这种情况下,公式 减慢 我们的代码!按顺序进行时,您只需进行几次加法即可获得下一个三角形编号——但使用公式时,您需要进行加法、乘法和除法!如果你按顺序去更贵。由于我们 是 按顺序进行,这似乎是对 Python 生成器的完美使用:
def triangular_number_generator():
triangle = number = 1
while True:
yield triangle
number += 1
triangle += number
这清楚地表明了获得下一个三角形编号所需的两个加法。现在让我们考虑一下您的因式分解函数:
您的因式分解函数在按顺序 生成因数时会降低性能。但我们只关心 个因素 ,顺序无关紧要。所以当我们分解 28 时,我们可以同时将 1 和 28 添加到因子列表 。同上 2 和 14——使 14 成为我们的新上限。类似地 4 和 7,其中 7 成为新的上限。所以我们更快地收集因子并快速降低我们需要检查的上限。这是代码的其余部分:
def factors_of(number):
divisor = 1
limit = number
factors = []
while divisor <= limit:
if number % divisor == 0:
factors.append(divisor)
remainder = number // divisor
if remainder != divisor:
factors.append(remainder)
limit = remainder - 1
divisor += 1
return factors
triangular = triangular_number_generator()
number = next(triangular)
factors = factors_of(number)
while len(factors) <= 200:
number = next(triangular)
factors = factors_of(number)
print(number)
比较如何?如果我们 运行 您的固定代码的下限 > 200 个因子,则需要大约 分钟 才能得出答案 (2031120)。上面的代码大约需要 秒 的 1/3。现在考虑达到 > 500 个因素需要多长时间。最后,实现既定目标:
What is the value of the first triangle number to have over five hundred divisors?
你的原始代码中的这个比较:
if int(length)>=500:
需要改为:
if length > 500:
尽管因子计数的跳跃方式对 500 没有影响。但是对于较小的限制,对于测试,它会产生影响。