In preparation for a job interview I’ve been playing around a bit on Project Euler, which poses a lot of nice programming and mathematics challenges. Trying out problems at random (and solving them ^^) I eventually stumbled onto Problem 201. And that’s where I stayed.
After some thinking I got a logically sound solution to the problem, but my algorithm was terrible. I basically ignored all the mathematical clues that were staring me in the face and chose to solve the problem programmatically. Having finished the naive algorithm I quickly realized that it would take eons for the bloody program to finish. I managed to devise a different algorithm that was faster than my original, and after optimizing it I shaved another few millennia off the runtime, but I was basically getting nowhere.
A friend then pointed me to the obvious math clues, which was that the array contained the squares of the first 100 natural numbers. Combining that with the fact that the obvious algorithm was obviously not the solution I thought about a better solution for a while. Unfortunately I couldn’t find one, and I needed to move on, so I cheated. I looked up the solution online. I know, that’s not a very educative thing to do, but I did use the opportunity to understand the correct algorithm and implement it myself.
Looking for a solution online, I first came across this Haskell implementation. I installed Haskell to confirm that it worked, which confirmed that this solution was just as slow as my flawed algorithm. It works on a list of 30 elements, but on a list of 100 elements you’ll be waiting forever. Next I came across this ActionScript solution, which is absolutely brilliant. I would explain the algorithm here but I won’t, for two reasons: 1. I’m not sure if I can explain it correctly and 2. if you see it in action you will realize why it’s brilliant.
I ported the algorithm to Java (my ‘home’ language), added a GUI that shows the contents of the array and a Next button that allows you to skip through the program step by step. You can give this a try for yourself: here’s the WebStart version. The program shows you step by step what happens for a list of 30 elements. I added some colors to make it more clear what’s happening. The yellow blocks at the bottom of the array are the values that are used to get the final answer in the end. (Note that the scrolling is quite buggy. If you scroll back left, resize the window a bit to make it refresh properly >_<;)
Click here to see the Java source code.
Doing this problem made me realize that in some cases the choice of algorithm is absolutely vital, and understanding the problem and extracting the right bits of information is very important. A healthy background in math can also save your day, in this case the formula for the sum of the square of the first n integers. I leave you with this quote, which I will not soon forget:
Work with the definition of a set, not with the set itself.