Clever Code
As part of an internal effort to dabble with Scala, I sat down yesterday and solved a few of the Project Euler problems. It's been a bit since I did any math-type coding problems, and I enjoyed the hours of flow that coding usually brings me. By the end, I felt pretty good about my solutions and the new language acquisition. And then I searched for solutions, to see what better Scala programmers would have done. Whoa, Nellie!
There were two classes of differences between my solutions and the ones I found online. First, the online solutions used language constructs and APIs I wasn't familiar with. This is what I expected, and why I searched in the first place. But, the other type of difference was what I'll call cleverness. Here's two examples:
My solution for Euler Problem #1:
I admire the cleverness of this code. It uses the language features nicely, is efficient, compact, and the explanation of how the author arrived here is well spoken. But I was really struck by the fact that this code is quite different than most of the code I encounter. My solution was to factor each number into a bag (method 1), then do a union of the bags (method 2), then multiply. The above solution is almost certainly faster, but absent clear and compelling performance reasons, I would strongly prefer the decomposed solution. I don't want to spend the time to be that clever in the first place, and certainly don't want to spend the time to learn what the code does if it ever had to change.
Save the clever code for toy programming assignments, performance-critical blocks, or hacking. If it must exist in a project that needs to be maintained, please provide an explanation like the one the author of the above code did.
There were two classes of differences between my solutions and the ones I found online. First, the online solutions used language constructs and APIs I wasn't familiar with. This is what I expected, and why I searched in the first place. But, the other type of difference was what I'll call cleverness. Here's two examples:
My solution for Euler Problem #1:
def euler1(max : int) : int = {A more elegant solution, demonstrating familiarity with the language syntax and features that I was clearly not familiar with:
var result = 0;
var i = 0;
while (i < max) { if (i % 3 == 0 || i % 5 == 0) result += i; i = i + 1; } return result; } euler1(1000);
(1 until 1000).filter(n => n % 3 == 0 || n % 5 == 0).foldLeft(0)(_ + _)As an example of cleverness, consider this code:
Quick: Without looking at the explanation, what is this code doing?object Euler005 extends Application { def divBy(div:Int)(x:Int) = if(x%div==0) x/div else x def reduceMuls(src:List[Int]):List[Int] = src match { case 1::rest => reduceMuls(rest) case a::rest => a::reduceMuls(rest map divBy(a)) case _ => src } println ((1 /: reduceMuls(1 to 20 toList))(_*_)) }
I admire the cleverness of this code. It uses the language features nicely, is efficient, compact, and the explanation of how the author arrived here is well spoken. But I was really struck by the fact that this code is quite different than most of the code I encounter. My solution was to factor each number into a bag (method 1), then do a union of the bags (method 2), then multiply. The above solution is almost certainly faster, but absent clear and compelling performance reasons, I would strongly prefer the decomposed solution. I don't want to spend the time to be that clever in the first place, and certainly don't want to spend the time to learn what the code does if it ever had to change.
Save the clever code for toy programming assignments, performance-critical blocks, or hacking. If it must exist in a project that needs to be maintained, please provide an explanation like the one the author of the above code did.