Find the greatest product of five consecutive digits in the 1000-digit number. – PROJECT EULER #8
This is both a completely straight forward problem and a nice way to learn about scanning through strings.
In the Racket case, we’ll want to use nested
for loops. The outer loop will use
for/fold to keep track of the best result so far. The inner loop will take an offset into the string and calculate the product. Assuming that the string
n contains the number given in the problem:
(for/fold ([best 0]) ([i (in-range (- (string-length n) 5))]) (max best (for/product ([j (in-range 5)]) (string->number (string (string-ref n (+ i j)))))))
The code in the Python version is pretty much the same:
best = 0 for i in range(len(n) - 5): best = max(best, int(n[i + 0]) * int(n[i + 1]) * int(n[i + 2]) * int(n[i + 3]) * int(n[i + 4])) print best
If you want to get a bit fancy about it, you can take advantage of the
reduce function to rewrite that code in a much more compact (albeit less readable fashion):
from operator import mul print reduce(max, [reduce(mul, map(int, n[i:i+5]), 1) for i in range(len(n) - 5)], 0)
If you work from the inside out:
n[i:i+5]will pull out five digits starting at
ias a string
map(int, n[i:i+5])will convert that into a list of five actual integers
reduce(operator.mul, ..., 1)will basically combine that list into a single number using multiplication as the glue (
*isn’t a function in Python, ergo
[reduce(...) for i in range(len(n) - 5)]will generate all such products
reduce(max, ..., 0)will calculate the maximum of all of these numbers
Each of these versions will give you the expected value of 40824 (and all in less than a millisecond). None too shabby for a day’s work.
As always, you can download my code for this or any Project Euler problem I’ve uploaded here.