问题1项目欧拉 必须返回233168 正在返回266333
我不打算使用不同的方法,我想知道为什么这个代码不能正常工作,从我做的调试看起来就像我希望看到的一切都在那里。
numArray = []
a = 0
b = 0
total = 0
totala = 0
totalb = 0
#numArray a and b were for testing purposes to make sure array was correct length
numArraya = []
numArrayb = []
while a < 1000:
numArray.append(a)
numArraya.append(a)
a += 3
#expecting to get 334, returns 334
#print (len(numArraya))
while b < 1000:
numArray.append(b)
numArrayb.append(b)
b += 5
#expecting 200, returns 200
#print (len(numArrayb))
#for numa in numArraya:
# totala += numa
#print (totala)
#for numb in numArrayb:
# totalb += numb
#print (totalb)
for num in numArray:
total += num
print (total)
答案 0 :(得分:5)
您的解决方案包含的数字是3和5的倍数,两次。您要在最终总和中两次添加15,30,45等:
>>> 266333 - 233168
33165
>>> sum(range(0, 1000, 15))
33165
如果b
中已存在numArray
,则可以修复您的解决方案:
while b < 1000:
if b not in numArray:
numArray.append(b)
numArrayb.append(b)
b += 5
更简单的解决方案是从0到999循环并使用%
模数运算符测试每个数字;如果结果为0,则左侧的数字可以被右侧的参数整除。与sum()
内置函数和生成器表达式一起,变为:
sum(x for x in range(1000) if x % 3 == 0 or x % 5 == 0)
你的方法,如果作为一个固定的问题,也很好:
sum(set(range(0, 1000, 3)).union(range(0, 1000, 5)))
两种方法仍然循环,因此随着数字增长将花费更多时间。然而,有一个需要恒定时间的数学解决方案。
请注意,您的“错误”暗示了可能的路径;如果所有3的倍数和5的倍数之和低于1000的所有倍数(3倍5 == 15)的总和低于1000,那么如果你有一个简单的公式来计算x的任意倍数之和在n以下,您可以通过添加3和5的总和并减去15的总和来计算此问题的解决方案。
换句话说,如果f(x, n)
计算x
以下n
的所有倍数的总和,则欧拉#1的解决方案等于f(3, 1000) + f(5, 1000) - f(3 * 5, 1000)
。< / p>
在这种情况下,f
是:
def f(x, n):
divisor = (n - 1) // x
return (divisor * x * (divisor + 1)) // 2
给你一个直线的线性时间结果:
>>> def f(x, n):
... divisor = (n - 1) // x
... return (divisor * x * (divisor + 1)) // 2
...
>>> f(3, 1000) + f(5, 1000) - f(3 * 5, 1000)
233168
答案 1 :(得分:0)
参见“包含 - 排除原则”; “FizzBuzz”。
我怀疑任何不喜欢Euler项目的人都可以坚持下去。如果还不清楚它有什么好玩的话,这里有一个暗示。当您之前尝试解决问题失败时,请将其作为一个谜题,找出您可能需要做的不同的事情。
如果你仍然有点不耐烦,你通常可以找出问题背后的原则。例如,当你遇到一个特定的问题时,你可能会知道整数参数和整数答案的问题被称为“Diophantine”。你会知道变量的平方问题被称为“二次”。通过搜索这些单词,您会发现问题是“Pell方程式”。
希望你学到很多东西,最重要的是,玩得开心!
答案 2 :(得分:0)
在“普通”python中没有数组。它们被称为列表。要使用数组,必须安装像numpy这样的库。列表会根据需要调整其长度,因此您无需知道定义它时的大小。
答案 3 :(得分:0)
这已经有一段时间了,但希望现在你可以将你的代码重新编写成一个方便的1-liner,例如:
result = sum([x for x in range(1000) if (x%3==0 or x%5==0)]
继续编码!