一点数学和逻辑
Posted
技术标签:
【中文标题】一点数学和逻辑【英文标题】:A bit of math and logic 【发布时间】:2012-09-22 06:55:17 【问题描述】:所以我在这里遇到了这个问题:
如果我们列出所有小于 10 且是 3 或 5 倍数的自然数,我们会得到 3、5、6 和 9。 这些倍数之和是 23。 求 1000 以下所有 3 或 5 的倍数之和。
我在这里写了这个:
def multiples(num, below):
counter = 1
z = 0
while True:
x = num * counter
if x < below:
z += x
else:
break
counter += 1
return z
below = 1000
print "Multiples of 3: " + str(multiples(3, below))
print "Multiples of 5: " + str(multiples(5, below))
print "Added: " + str(multiples(3, below) + multiples(5, below))
如果我将 below
设置为 10,我会得到正确答案,即 23
Multiples of 3: 18
Multiples of 5: 5
Added: 23
但是当我将它设置为 1000 时,我得到了这个:
Multiples of 3: 166833
Multiples of 5: 99500
Added: 266333
这应该是错误的,有什么我没有得到的吗?
【问题讨论】:
这将是 Euler 项目 1 号吗? projecteuler.net/problem=1 非常重要。我第一个失败了xD。不,我现在做得很好,通过了一些。 【参考方案1】:实际上,一旦低于 1000,您需要删除 15 的倍数,因为它将在 3 和 5 中重复。这在 10 以下不会发生..
Multiple of 3 & 5 = (multiple of 3 + multiple of 5 - multiple of 15)
因此,您可以使用Set
来存储这些倍数,以删除重复项..
【讨论】:
【参考方案2】:Pythonic 的方法是使用列表理解(或生成器理解):
sum( n for n in xrange(1,1000)
if n % 3 == 0 or n%5 == 0 )
.
您遇到的问题是您两次包含了 15 的倍数(n%3==0 and n%5==0
),在一个列表中执行此操作可避免此类错误。
【讨论】:
对于用作参数的生成器表达式,你不需要额外的括号:你可以写sum(n for n in xrange(1000) if n%3==0 or n%5==0)
。除此之外,这是最好的答案。【参考方案3】:
multiples_of_3 = range(0,1000,3)
multiples_of_5 = range(0,1000,5)
sum_of_multiples = sum(set(itertools.chain(multiples_of_3, multiples_of_5)))
或
multiples_of_3 = range(0,1000,3)
multiples_of_5 = range(0,1000,5)
multiples_of_15 = set(range(0,1000,15))
sum_of_multiples = sum(set(i for i in itertools.chain(multiples_of_3, multiples_of_5) if i not in multiples_of_15))
【讨论】:
以上是关于一点数学和逻辑的主要内容,如果未能解决你的问题,请参考以下文章