3

My problem sees me cycling through a long number in order to find the largest product of 5 consecutive digits within said number. I have a solution, but it currently involves the hard coding of the elements' positions, feels/looks hideous and is not scalable (what if I wanted the the sum of the 10 consecutive terms?). Is there a way to "Python" up this solution and nest it or optimise it in some way?

n = 82166370484403199890008895243450658541227588666881

N = str(n)
Pro = 0
for i in range(0, len(N) - 4):
    TemPro= int(N[i])*int(N[i+1])*int(N[i+2])*int(N[i+3])*int(N[i+4])
    if TemPro> Pro :
        Pro = TemPro
print(Pro )

OS: Windows 7
Language: Python 3

  • It looks like the whole `TemPro= int(N[i])... ` part could be done with a loop. As always, whenever you see repetition, consider reaching for a loop or a function. If you have a for-loop over the range of numbers, and multiplied inside the loop, I could see that working. – Carcigenicate Dec 03 '17 at 19:42
  • That was my exact thought, but I can't seem to get it to work without it going either 1) out of bounds or 2) double counting and hence returning the wrong answer. Hence my asking if anyone is more familiar with this and can prod me in the correct direction of a successful implementation. – Matthew W. Noble Dec 03 '17 at 19:48
  • calculating digits saved me about a ms. Great call, thank you! – Matthew W. Noble Dec 03 '17 at 20:10

2 Answers2

0

perfect case for using reduce on a slice of N:

from functools import reduce # python 3
nb_terms = 5
for i in range(0, len(N) - nb_terms - 1):
    TemPro= reduce(lambda x,y:int(x)*int(y),N[i:i+nb_terms])
    if TemPro> Pro :
        Pro = TemPro
print(Pro)

reduce will multiply all the items together, without visible loop, and without hardcoding the number of terms.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • Spot on, thank you! I know of lambda functions, but we haven't covered them in my online course so I didn't think of applying them. – Matthew W. Noble Dec 03 '17 at 20:00
0

You can do this quite concisely, by first converting the whole integer to a series of digits, and then calculating the products of a sliding window using reduce, mul and a slice.

from functools import reduce
from operator import mul

n = 82166370484403199890008895243450658541227588666881

def largest_prod(n, length=5):
    digits = [int(d) for d in str(n)]
    return max(reduce(mul, digits[i:i + length]) for i in range(len(digits) - length + 1))

print(largest_prod(n))

Note that this method of finding the digits is theoretically kind of slow - for all intents and purposes it's fast enough, but it involves some unnecessary object creation. If you really care about performance you can use an arithmetic approach similar to what I discussed in my answer here.

Izaak van Dongen
  • 2,450
  • 13
  • 23