简体   繁体   English

查找10,000位数字中13个相邻数字的最大乘积

[英]Finding maximum product of 13 adjacent digits in 10,000 digit number

Can't seem to figure out what's wrong with my code (Project Euler problem 8). 似乎无法弄清楚我的代码有什么问题(Project Euler问题8)。 I want to find the maximum product of 13 adjacent digits in the 10,000 digit number below, and I'm getting the wrong answer. 我想在下面的10,000位数字中找到13个相邻数字的最大乘积,我的答案是错误的。

my_list = list('7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450')

for i in range(1000):
    my_list[i] = int(my_list[i])

previous_product = 1
for x in range(13):
  previous_product *= my_list[x]
current_product = previous_product*my_list[13]/my_list[0]

for i in range(1, 987):
  if current_product > previous_product:
    maximum_product = current_product
  previous_product = current_product
  if my_list[i]==0:
    current_product = 1
    for x in range(13):
      current_product *= my_list[i+x+1]
  else:
    current_product = previous_product*my_list[i+x+1]/my_list[i]

print(maximum_product)

Edit: Solved! 编辑:解决了! maximum_product was defined wrongly... it takes on the value of the most recent "current product" that happens to be greater than the previous product, not necessarily the largest product. maximum_product的定义错误...它采用了最新“当前产品”的价值,该价值恰好大于以前的产品,不一定是最大的产品。

Correct, albeit not-super-efficient code: 正确,尽管不是超级高效的代码:

   my_list = list('7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450')

for i in range(1000):
    my_list[i] = int(my_list[i])

previous_product = 1
for x in range(13):
  previous_product *= my_list[x]
current_product = previous_product*my_list[13]/my_list[0]

large_products = []

for i in range(1, 987):
  if current_product > previous_product:
    large_products.append(current_product)
  previous_product = current_product
  if my_list[i]==0:
    current_product = 1
    for x in range(13):
      current_product *= my_list[i+x+1]
  else:
    current_product = previous_product*my_list[i+x+1]/my_list[i]

print(max(large_products))

I haven't checked why your approach doesn't work but you can easily solve this with: 我没有检查为什么你的方法不起作用,但你可以轻松解决这个问题:

import operator
from functools import reduce

my_int_list = [int(char) for char in my_list]

max(map(lambda *x: reduce(operator.mul, x), 
        my_int_list[0:], 
        my_int_list[1:], 
        my_int_list[2:], 
        my_int_list[3:], 
        my_int_list[4:], 
        my_int_list[5:], 
        my_int_list[6:], 
        my_int_list[7:], 
        my_int_list[8:], 
        my_int_list[9:], 
        my_int_list[10:], 
        my_int_list[11:], 
        my_int_list[12:]))

In case this takes up too much memory you could also use itertools.islice instead of the direct slicing with [idx:] . 如果这占用了太多内存,您也可以使用itertools.islice而不是使用[idx:]直接切片。

Here is an implementation of your sliding window idea, modified so that it only applies to strings which contain no zeros: 以下是您的滑动窗口构思的实现,已修改,以便它仅适用于不包含零的字符串:

def max_product(s,k):
    s = [int(d) for d in s]
    p = 1
    for d in s[:k]:
        p *= d
    m = p
    for i,d in enumerate(s[k:]):
        p *= d
        p //= s[i]
        if p > m: m = p
    return p

In the above s is a string of nonzero digits of length at least k ( k = 13 in your problem). 在上面的s是一串长度至少为k的非零数字(在你的问题中k = 13 )。 It returns the largest product of k successive digits. 它返回k连续数字的最大乘积。 The subtlety is in the way enumerate works. 微妙的方式是枚举作品。 When you use enumerate on s[k:] the index, i , starts at 0 -- which is exactly the factor that you want to remove in the first pass through that loop. 当你在s[k:]上使用enumerate时,索引i0开始 - 这正是你想要在第一次通过该循环时删除的因子。

To apply this to 将此应用于

data = '7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450'

First split into chunks which contain no zeros and are at least 13 digits long: 首先拆分成不包含零的块,并且长度至少为13位:

chunks = [s for s in data.split('0') if len(s) >= 13]

There are 24 such chunks. 有24个这样的块。 To get the overall max, just take the max of the max of each chunk: 要获得总体最大值,只需占用每个块的最大值:

print(max(max_product(s,13) for s in chunks))

which does indeed print 23514624000 确实打印23514624000

Your current code isn't working because it seems to be based on the wrong plan -- or at least on a plan that I do not fully understand. 您当前的代码无法正常工作,因为它似乎是基于错误的计划 - 或者至少是基于我不完全理解的计划。 Here's a different way to think about the algorithm. 这是考虑算法的另一种方式。

Imagine we have this number: 7316717 . 想象一下,我们有这个号码: 7316717 And we are looking for the maximum product of 3 adjacent digits. 我们正在寻找3个相邻数字的最大乘积。 We could solve the problem as follows. 我们可以解决这个问题如下。 I'm hard-coding the result from each step, but you should be able to write Python code to compute each part. 我正在对每一步的结果进行硬编码,但您应该能够编写Python代码来计算每个部分。

  • Find all adjacent 3-digit sequences: 查找所有相邻的3位数序列:

     seqs = [731, 316, 167, 671, 717] 
  • Compute their products: 计算他们的产品:

     products = [21, 18, 42, 42, 49] 
  • Find their maximum. 找到他们的最大值

     answer = max(products) 

I haven't checked your code and in which way it won't work. 我没有检查你的代码,以及它不起作用的方式。

But an easy way to solve your problem, is generating all the possibile slices with 13 adjacent numbers from your input data then find the product of their elements then find the maximum product of them all. 但是解决问题的一种简单方法是,从输入数据中生成所有可能的切片,其中包含13个相邻数字,然后找到其元素的乘积然后找到它们的最大乘积。

Here is a way to do it: 这是一种方法:

data = '7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450'

def product(a):
    prod = 1
    for k in a:
        prod *= int(k)
    return prod

def max_adjacent_number(data, suit=13):
    return max(product(data[k:k+suit]) for k in range(len(data)) if '0' not in data[k:k+suit])


from time import time
start = time()
val = max_adjacent_number(data)
elapsed = time() - start
print("Solution: {0} \telapsed: {1:.5f}ms".format(val, elapsed*1000))

Output: 输出:

# Best time
Solution: 23514624000   elapsed: 1.31226ms

You can improve your code efficiency using list comprehension like this: 您可以使用列表解析来提高代码效率,如下所示:

import time
n = str(x) #x is the long number
a = time.time()
result = max(reduce(lambda x, y: x * y, map(int, n[i:i+13])) for i in xrange(len(n)-12) if '0' not in n[i:i+13])
b = time.time()
print "Maximum adjacent numbers product: %d" % result
print "Time taken:", (b-a)*1000, "ms"

Output: 输出:

Maximum adjacent numbers product: 23514624000
Time taken: 4.34899330139 ms

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Python代码用于将大数的相邻数字相乘并找到最大可能乘积,而不给出期望的结果 - Python code for multiplying adjacent digits of a big number and finding maximum possible product, not giving desired result 用于查找 1000 位数字的 13 个连续数字的最大乘积的代码没有给出所需的输出 - Code for finding largest product of 13 consecutive digits of a 1000 digit number does not give required output 正则表达式:准确输入 4 位数字,检查输入的数字是否出现在前 10,000 个字符中 - Regex: inputs exactly 4 digits, check whether the inputted number appears in the first 10,000 characters 如果 number>=10,000,则用逗号将轴号格式化为千位 - Format axis number to thousands with a comma if number>=10,000 数字的乘积作为一位数字 - product of digits as a single-digit number 错误 output 找到金字塔/三角形中相邻数字的最大和 - Wrong output in finding the maximum sum of adjacent digits in a pyramid/triangle 整数下限至最接近的10,000 - Floor of integer to the nearest 10,000 ISBN 校验位项目查找第 10 位数字 - ISBN Check Digits Project Finding 10th Digit Scrapy搜寻器-创建10,000个蜘蛛还是一个蜘蛛爬行10,000个域? - Scrapy crawler - creating a 10,000 spiders or one spider crawling 10,000 domains? 在 python 中查找数字的总和直到总和变为单个数字 - Finding sum of digits of a number until sum becomes single digit in python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM