项目欧拉:问题8

时间:2010-12-13 16:53:32

标签: python

n = # some ridiculously large number, omitted
N = [int(i) for i in str(n)]
maxProduct = 0
for i in range(0,len(N)-4):
    newProduct = 1
    is_cons = 0
    for j in range(i,i+4):
        if N[j] == N[j+1] - 1:
        is_cons += 1
    if is_cons == 5:
        for j in range(i,i+5):
            newProduct *= N[j]
        if newProduct > maxProduct:
            maxProduct = newProduct
print maxProduct

我已经在这个问题上工作了好几个小时了,我无法让它发挥作用。我已经尝试过在纸上做这个算法而且效果很好..你能给我一些提示吗?

7 个答案:

答案 0 :(得分:3)

我认为你误解了这个问题。如果它表示“5个连续数字”,那只表示一个接一个的5个数字 - 你应该检查数字的是否连续(即每一个都大于最后一个)。因此,抛弃所有is_cons逻辑,只检查每个5位数块的乘积。

答案 1 :(得分:2)

Marijus,我建议你重新思考算法,这是解决问题的一种非常奇怪的方式。它更简单,使用函数max,单个迭代(例如,generator expression),并尝试在没有时间变量的情况下进行。它可以在2/3行中优雅地解决(事实上,你可以用一行来完成它,但是例如product函数的抽象是可取的,因为你将在其他行中使用它欧拉问题)

答案 2 :(得分:1)

有一件事看起来不对:range(n, m)为您提供从n包含到m独占的数字,即range(N, N+4)为您提供 4 索引(问题想要五个连续数字)。

答案 3 :(得分:0)

我找到了一个与@ tokland的帖子一致的解决方案。

from itertools import islice
from operator import mul

def max_product(num, length=5):
    num_list = map(int, str(num))
    num_slices = (islice(num_list, x, x+length) for x in xrange(0, len(num_list)-length))
    return max(reduce(mul, y) for y in num_slices)

Itertool疯狂。

from itertools import izip, islice, imap, tee
from operator import mul

def max_product(num, length=5):
    num_lists = enumerate(tee(imap(int, str(num)), length))
    digit_slices = izip(*[islice(num_list, ord, None) for ord, num_list in num_lists])
    return max(reduce(mul, y) for y in digit_slices)

答案 4 :(得分:0)

我同意@tokeland,你可能需要重新考虑这个算法。另外,正如@delnan所说,范围(i,i + 4)将只给出4个值。这是一个应该做的代码

 n = str([whatever number])
 maximum = 0
 for i in range(0,len(n)):
     substr = n[i:i+5]
     product = 1
     for digit in substr:
         product *= int(digit)
         if product > maximum:
              maximum = product
 return maximum

答案 5 :(得分:0)

这是我的解决方案:

number = '\
73167176531330624919225119674426574742355349194934\
96983520312774506326239578318016984801869478851843\
85861560789112949495459501737958331952853208805511\
12540698747158523863050715693290963295227443043557\
66896648950445244523161731856403098711121722383113\
62229893423380308135336276614282806444486645238749\
30358907296290491560440772390713810515859307960866\
70172427121883998797908792274921901699720888093776\
65727333001053367881220235421809751254540594752243\
52584907711670556013604839586446706324415722155397\
53697817977846174064955149290862569321978468622482\
83972241375657056057490261407972968652414535100474\
82166370484403199890008895243450658541227588666881\
16427171479924442928230863465674813919123162824586\
17866458359124566529476545682848912883142607690042\
24219022671055626321111109370544217506941658960408\
07198403850962455444362981230987879927244284909188\
84580156166097919133875499200524063689912560717606\
05886116467109405077541002256983155200055935729725\
71636269561882670428252483600823257530420752963450'

print max([reduce(lambda accum, x : accum * x, [int(x) for x in number[i:i+5]]) for i in range(len(number) - 5)])

答案 6 :(得分:0)

10安培;#。 5 {。(}。~I。@(=> ./)@(5&(* /)))10#。^:_ 1个数字

是一个J解决方案,其中number是一个非常长的数字作为扩展整数。

它从右到左或多或少地执行,括号用于两件事 - 它们传递正确的参数,以便它们可以在多个地方使用,这样您就不必创建命名的中间变量并且优先执行(当然,当传入参数时,很明显括号内的内容必须最后执行,而不是第一次.J是一种非常有趣的语言,括号表示先执行然后再执行但总的来说,执行是从右到左。数字被分成数字,并且每个重叠的五位数组的总和产生。找到最大的和产品并与该向量进行比较以创建一个布尔向量找到比较的索引。然后丢弃原始矢量的头部,直到找到的索引。然后提取一个五位数的大块,并将这五个数字粘在一起。

我认为低至8的问题实际上只是让你进入欧拉 - 它们很简单,大多数都是J中的一个衬里。

我不确定我是否第一次将这个作为一个班轮,我可能有一个中间命名变量 - 但由于我已经做了一些这些问题,我相信我比我知道J好多了,我可以像这样把一个短语放在一起没有太多问题,我知道在哪里放括号。在那里,做欧拉练习已经成功。