[英]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
时,索引i
从0
开始 - 这正是你想要在第一次通过该循环时删除的因子。
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.