Skip to content

Clojure + TopCoder SRM

November 30, 2011

I’ve recently started delving into the interesting world of Functional Programming. This was sparked by an amazing video by Rich Hickey called “Simple Made Easy” – I highly advise every programmer to listen closely, this man has his head screwed on right and has given a lot of thought to his subject matter. Even if you’re not interested in Clojure, as a developer, I believe every one of his talks are highly valuable and worthwhile pondering.

In line with adopting Clojure, I’ve mostly switched to Emacs. I still use PhpStorm for PHP development and Eclipse for Java development – I would prefer to move away from them, but emacs has a rather significant “bootstrap” time, so I don’t think I’d really make much of a return on investment there.

Rather, I’m leveraging the excellent emacs clojure-mode with paredit, slime, lein and swank which really makes clojure development shine. I still can’t get over how amazing on the fly development is with emacs + clojure. I have to remind myself that I’m actually working on a program every now and then and not just having fun.

On that vein, my biggest challenge now is wrapping my head around Functional Programming thinking. And I don’t mean just how to do recursions, but to really get to grips with how to leverage the powerful constructs of Clojure – lazy evaluation, lazy sequences, macro’s, immutability, lambda functions, agents, refs, atoms and so on. There’s a lot of good stuff locked away just behind the doors of FP if I just care to take the time to pick the lock 🙂

To that end, I’ve decided to start doing past TopCoder SRM challenges in Clojure, as thinking practice. I could be doing something, you know, actually useful. But I’m looking for something that’s highly mentally stimulating but small and of a throw-away nature.

I’ve decided to host my solutions at GitHub so that others can see my code, maybe comment and perhaps even learn from the code.. Or at least it’s just there 😛

My first challenge, DropCoins isn’t much to write home about, except that if you look at the code here, there are a few things I’d like to point out that I especially enjoyed.

Notice the (board-empty?), (count-coins), (move-board-left), (move-board-right), (move-board-up), (move-board-down) functions. Notice how incredibly succint those functions are written? I’m loving the power of seq’s – the (count-coins) is my favourite:

In that, I take the board array of strings, concat them together, filter it so that it’s a seq of only “o” characters and then count the elements in that filtered array. Awesome.

I had taken a shortcut with the (move-board-up) and (move-board-down) fn’s which had me revamping my entire solution from a recursive function to a queueing system. I prefer the queueing anyhow. The astute observer will notice that I have a queue ref (which is just really a boxed pointer – the box never changes, but the contents might) that I slap lazy calls to (get-minimum-spin) onto. These calls add more onto the queue, but when a sufficient answer has been found, the rest of the queue doesn’t get evaluated.

I believe there’s a better way than using (delay) though. I’m convinced I could have used a far simpler method for this, but the actual implementation eludes me.

I do like the way I setup the queue with a single lazy call and then just start looping through it for the answer. Obviously, if this queue ends, it’ll just return -1..

It feels like I didn’t use the (recur) quite as effectively as I could have for the loop.. suggestions? Seems a little contrived to have exactly the same code again there :/

Here’s an example of me running a couple of the tests in the REPL on the loaded and ‘running’ code:

Fun and games. Of course.. this all took me a lot longer to develop than the TopCoder SRM match would have allowed – but I’m still a Clojure newbie, so – oh well. I’ll get faster.

From → Coding

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: