以下是项目Euler#8:
的更新问题具有最大产品的1000位数字中的四个相邻数字是9×9×8×9 = 5832。
731671765313306249192251196744265747423534919493496983520312774506326239578318016984801869478851843858615607891129494949545959501737958331952853208805511125406987471585238630507156932909632952274433576689664895045245231617318564030987112172238311362229893423380303533333627661428282806444444444444523874930358907296290491560444077239071381051585930796086670172427121883998797979087922749219016972088880937766572733300105336788122022023542180975125454594752243525849077116705560136048395864670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319898900088952434506585412275886668811642717147992442928233086346567481391231628245861786645835912456529476545682848912883142607690042242190226710556263211111093705442175069416589604080719840385096245444444362981230987878799272442849091888458015616609791919133875499200524063689991256076060588611646710940507754100225698315555555593572972571636269561882670428252483600823257530420752963450
在拥有最大产品的1000位数字中找到13个相邻数字。该产品的价值是什么?
我能够为最大的产品解决这个问题。但是我也试图找到13位数字的序列产生的最大产品。如何优化或改进代码以获得最大产品的13位数字序列?
largest_product = 0
# number = '1000 digit number from the question'
for i in number:
if len(number) > 12:
result = 1
for j in range(13):
z = int(number[j])
result = result * z
if result > largest_product:
largest_product = result
number = number[1:]
print(largest_product)
Python版本:3.7。OS:Windows 10。
P.S:这是我在Stackoverflow上询问的第一个问题。如果错过任何规则,请原谅。
保存这些数字的位置是一个简单的事情:
if result > largest_product:
largest_product = result
largest_digits = number[:13]
number = number[1:]
print(largest_product, largest_digits)
正如其他人所指出的那样,有一些"更好"的方法可以做到这一点。一方面,在每次迭代中重新创建列表都是昂贵的。相反,将原始序列保持完整,然后将滑动窗口穿过它。
第二,请注意,您要多次将每个数字转换为int
- 您可以使用滑动窗口(仅转换新数字(,或者在开始时转换所有数字并使用Integers列表来使用所有数字。
您正在重新创建number
每次迭代,这是非常浪费的。您应该在索引上进行循环,而不是元素,以便可以使用相同的number
。您还可以简单地更新result
,而不是重新计算它:每次移动窗口时,您都会丢失一个数字并获得另一个数字,因此您可以只需划分并乘以相应的数字(这确实意味着您的结果将是一个不过,浮动而不是int(。您也可以使用reduce
来获取产品,而不是使用循环。您也可以将number
的元素转换为循环外的数字:
number_as_reals = [float(_) for _ in number]
current_result = reduce((lambda x, y: x * y), number_as_reals[0:13])
best_result = current_result
for i in range(1,len(number)-13):
current_result = current_result*number_as_reals[i+12]/number_as_reals[i-1]
if current_result > best_result:
best_result = current_result # You can also do best_result = max(best_result, current_result)
您可能还需要将所有内容转换为日志,以便您可以使用添加而不是乘法。这确实需要对零的错误处理:
import math
import numpy as np
number_as_logs = [math.log(float(_)) if _ else -np.inf for _ in number] # You can also just use a really negative number, such as -1000, rather than -np.inf
current_result = sum(number_as_logs[0:13])
best_result = current_result
for i in range(1,len(number)-13):
current_result = current_result+number_as_logs[i+12]-number_as_logs[i-1]
if current_result > best_result:
best_result = current_result
,如果您想要没有魔术数字,它将是
import math
import numpy as np
number_as_logs = [math.log(float(_)) if _ else -np.inf for _ in number]
window_size = 13
current_result = sum(number_as_logs[0:window_size])
best_result = current_result
for i in range(1,len(number)-window_size):
current_result = current_result+number_as_logs[i+window_size-1]-number_as_logs[i-1]
if current_result > best_result:
best_result = current_result