Tuesday, 11 October 2011

The power of three lines of scala

I was looking at this problem on project Euler.net and I was amazed it only take 3 lines of scala code (with one being the number itself)!

val bigNum = "73167176531......"
def product(digits: String) = { digits.map(java.lang.String.valueOf(_).toInt).reduceLeft( (prod, c) => prod*c)}

That's it!
Ok let me try to explain what that code does..
First row is the string copied from the website, so far...so good right
Second row is a definition of a function product that takes a String of digits and returns an Int.
The return type is inferred, the compiler will figure out it is an Int

Let's see what each method call does and where are those methods!

map is a function defined in StringOps and there is an implicit convertion between String and StringOps.
It takes every char in the String and applies the provided function. In our case the function is transforming the char to a number.

is just a short for
c => java.lang.String.valueOf(c).toInt

The result of this first function is a Seq of Int. Then applying the reduceLeft function we calculate the product of those digits.
reduceLeft will take two elements at a time and apply the provided binary function and then moves right and applies the same function again till the last element is reached.
our function is simply multiplying elements.

Cool so we know how to multiply elements.

Now what we need to do is go through the string taking a block of 5 digits at a time, multiply them and calculate the maximum.
That is exactly what the last line is doing. The sliding function in StringOps is taking a block of 5 elements (chars in our case) and returning an iterator over them.
The toSeq method creates a sequence out of the passed iterator.

At this stage we have something like Seq["73167","31671","16717"..]

All we need to do is map this elements to their product using our product function and then calculate the maximum so the last two functions couldn't be more expressive!

This is probably not the best way to solve this problem, if you want to post yours you're welcome!

No comments: