Project Euler problem 8

The latest in a series of paired-up problem workings with Greg Bowie. This week we’re looking at Problem 8:

Discover the largest product of five consecutive digits in a the [provided] 1000-digit number

Here’s my response, longhand:

  1. I’ll need a variable to store the (current) value of the greatest product
  2. I’ll need to iterate through the 1000-digit number, reading 5 digits at a time working out the product of each sequence, stepping one digit on with every iteration.
  3. The routine will begin from the 1st digit. The process will stop 5 digits of the final digit
  4. Using variables to store the length of the 1000-digit number and the number of digits we’re deriving the product of would make the solution more adaptable for other numbers and sequences
  5. Each product retrieved from every sequence of 5 digits must be compared to the current greatest product. If this exceeds the current greatest product, we set this as the new greatest product

This should solve the problem, but why stop now?


The presence of zeros in the 1000-digit number is notable – any zero encountered while examining the product of multiple digits will result in a zero product. So I’ll ignore them:

  1. Create an array of smaller numbers by splitting the 1000-digit number by any zero digit – handling sequences of zeros so as to prevent empty array items
  2. Iterate through each of these numbers, deriving the product of each set of 5 digits, and checking this against the current greatest product

Chances are this refinement will not improve the performance of this test on a single number, but as it reduces the number of product-derivation runs by 398 by it may scale well, depending on the language.

ratherLongNumber = 73167176531330624919225...
numDigits = ratherLongNumber.to_s.length
considerRange = 5
totalcomparisons = 0
$greatestProduct = 0
while totalcomparisons range = ratherLongNumber.to_s[totalcomparisons,5]
rangeproduct = range.split(//).map(&:to_i).inject(:*)
$greatestProduct = $greatestProduct>rangeproduct ? $greatestProduct:rangeproduct
puts "#{$greatestProduct}"

Refined version:

ratherLongNumber = 73167176531330624919225...
def getProductOfRange(inputNumber,considerRange)
# puts inputNumber
numberofcomparisons = 0
localGreatestRange = 0
while numberofcomparisons range = inputNumber.to_s[numberofcomparisons,5]
rangeproduct = range.split(//).map(&:to_i).inject(:*)
localGreatestRange = localGreatestRange>rangeproduct ? localGreatestRange:rangeproduct
return localGreatestRange ,numberofcomparisons
$greatestProduct = 0
arrayOfNumbers = ratherLongNumber.to_s.split(/0+/).map(&:to_i)
tmp2,comparisons = getProductOfRange(a,5)
$greatestProduct = $greatestProduct>tmp2 ? $greatestProduct:tmp2
puts "#{$greatestProduct}"

here’s Greg’s response, posted simultaneously today.

update 23/01/2012:

Revisiting this afresh I realise there’re other ways to skip those pesky zeros, rather than drop them into an array, better to simply skip past any such sequence:

ratherLongNumber = 73167176531330624919225...
numDigits = ratherLongNumber.to_s.length
considerRange = 5
greatestProduct = 0
cursor = 0
skipped = 0
while cursor <= numDigits-considerRange
range = ratherLongNumber.to_s[cursor,considerRange]
if range.index('0')
rangeproduct = range.split(//).map(&:to_i).inject(:*)
greatestProduct = greatestProduct>rangeproduct ? greatestProduct:rangeproduct
puts "Greatest Product: #{greatestProduct}"
puts "#{skipped} sequences with zero in the #{considerRange}-digit range skipped"

One thought on “Project Euler problem 8

  1. MovingAlong

    Excellent point about ’0′ – hadn’t even considered that. Did think the other way of only multipling when it contained a 9 but realised that wouldn’t be fool-proof.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>