codejam, groovy, and refactoring

July 19th, 2008 Leave a reply »

This past Wednesday I entered Google’s code jam 2008. For those that don’t know (as I didn’t before one of my coworkers brought it up), this is a yearly programming competition. You are given a small selection of problems to solve, and a set period of time (hours, not days) to solve it in. When you have your program done, you download their test input, run your code against it, and then upload your results and source code.

Wednesday marked the beginning of the 24-hour qualifying round. After this, the people who made it in (a few thousand contestants) continue to online round 1. After 3 online rounds, there are a few rounds onsite at Google offices.

Having succumbed to evangelism from some other people, I decided to go ahead and code my solutions in Groovy. This was (and is, since I passed the qualifiers. w00t!) a great opportunity to force myself to learn more Groovy. Closures, quick prototyping, static typing… all the things I’ve loved about Python, but with slightly more familiar syntax, the ability to natively use the millions of Java libraries, and, for work, no need to install any new VM/interpreter on target systems.

What with learning some Groovy idiosyncracies and overcoming my own mental roadblocks, it took me about 9 hours to do the first two problems in this round. With some decent lessons learned, I think I can pare my time down to around 2 hours for a problem, which falls within the expected times for the “real” rounds.

Now that I have some breathing room, I’m using these problems as exercises in refactoring; taking my first quick prototypes and making them readable and reasonable. So far, I’ve taken my solution for problem A (the search engines one) from 102 lines to 70, while improving readability. Here is the (working) code I turned in and here is what I have now that I’ve slept on and revisited the code. A couple of the things I change involved not using Groovy-specific bits of sugar just because they were there. For instance, my main() method became much simpler when I switched away from Groovy’s awesome File.eachLine() closure and just used a standard Java Iterator. This allowed me to handle the input in a more straightforward manner. If the input were similar data on each line, I think the closure would have been better, but Google has structured their files more complexly than that.

Now that a wonderful participant has actually gone through and collected stats for the languages used, I can learn from the other Groovy-ers (you can download anyone’s solution from the code jam’s score pages, after each round is complete). One thing I’ve already noticed is that the high-ranking Groovy user, nebolsin, uses several Groovy features I haven’t seen before, but also uses C++/Java-style for loops (for (int i=0; i<10; i++) {) instead of the simpler Groovy way (for (i in 0..<10) { or even 10.times() {).

I expect to post again when I’ve finished the refactor of my solution for problem B. Also doing other quick-coding exercises as practice. Training for a coding race… wow.

3 comments

  1. This is great Sam.
    Good job. Keep us updated.

  2. I got curious so I took at look at your code. Looks excellent. Good work.
    I made a couple of changes, nothing major just some personal preference. Here is the diff http://pastebin.com/pastebin.php?diff=f22de2081

    The main thing is I like declaring lists using the literal like
    engines = []
    vs
    engines = new ArrayList()

  3. sam says:

    That is clearer, thanks. I also went ahead and went from
    new Integer(i.next()).times() {
    to
    i.next().toInteger().times() {

Leave a Reply