MobME Code Jam and the Craft of Programming

I’ve always been of the strong opinion that we don’t write programs just for computers to understand: we write them for other programmers too, the ones who come after us, who maintain the code that we chug out, but also the ones who read our programs to understand how to approach a problem, how to design reusable components or perhaps even how to frame thoughts about a problem domain. Programmers are craftsmen: the good ones amongst us are artisans and the best of us are artists.

This is why I’m amazed at how much emphasis programming contests place on the correctness of a program or its time and space complexity (for the non-programmers amongst us, this is how long it takes to run and how much memory it uses). Are these the only measure of a good program that contests can evaluate? While framing questions for MobME CodeJam, we wanted to test out the other bits of what makes a good programmer too: how fast your program runs and how much memory it uses are important, yes, but there are several other criteria that we think deserves more merit.

Again, this is an area where we differ strongly from other contests. Let’s compare with Google’s Code Jam (whose name we unabashedly borrowed):

  1. Questions are strictly timebound.
  2. Questions are algorithmic.
  3. A clear input and output format is provided.
  4. A computer looks at your program correctness.

In contrast, for MobME Code Jam:

  1. The time available is a relaxed 24 hours to solve a single question. Having done questions of these nature ourselves, we estimate that it would take a good programmer just about 2 or 3 hours to correctly compute a question.
  2. Questions are exploratory.
  3. We leave it to the programmer to design and describe input and output formats.
  4. A human looks at your program correctness and clarity.

So why these differences? What are we trying to gauge here? To describe this, I’ve worked on a solution for our sample question (title “hollywood”):

Write a program that ranks Hollywood actors based on the number of their appearances in a list of top 100 top movies. There are a number of top movie lists on the Internet and it’s up to you to choose one. We prefer you choose one that has an open API.

So you have to:

  1. program a correct solution within 24 hours.
  2. explore and find out an open API.
  3. design a clear and efficient solution, and,
  4. write a program that we can understand (because we have to figure out how well it works)

The codejam-hollywood-mobme repository illustrates what we consider a good solution to the problem. The code is idiomatic ruby, is well tested, has clear generated documentation as well as a concise README and defined RESULT, and runs reasonably fast.

Let’s go over that again. So at MobME, what we prioritise are these things in order:

Code is Idiomatic

A programming language has a definite well-defined syntax that its compiler or interpreter understands. The language also however has lots of conventions, evolved (and often changing) over the course of time that most programmers who use the language adopt. We consider adopting these the first test of a well-written program. This doesn’t in any way constraint your originality, but it provides a strong structure for framing your solution.

In my hollywood solution for e.g., a lot of such conventions are followed that are adopted from the parent language (Ruby):

For naming:

  1. Underscores separate variable_names and file_names.
  2. Classes are CamelCased.
  3. Constants are ALL_UPPERCASE.

For documentation:

  1. There are inline comments in code.
  2. A clear README is provided.
  3. Rdoc is used

For writing code “the Ruby way”:

  1. Using a functional construct inject instead of less elegant methods for a custom sort.
  2. Using Ruby modules for namespacing.
  3. Code folder structure: all code in lib/, all documentation in doc/ and all tests (or rather, specifications) in spec/

Do note that these conventions are different for every language. This is why we allow people to submit multiple solutions in several different languages: writing one in Ruby for example lets a programmer explore a completely different approach that writing a solution in Java.

Code should be Well Tested

Having good test coverage and writing testable code is a fundamental need. The virtues of writing tests have been covered extensively in several other places, so I’m not going to go over them again. We encourage people to program using TDD, but any tests are better than none, and it’s up to you how to write them.

In my Ruby solution, we use RSpec for doing TDD. Do note all the specs available in spec/. Let’s take an example:

And the beginnings of the corresponding code:

Read up on BDD for more, but please be aware: do test the behaviour, not your implementation and mock away all your dependencies. Assume your libraries work: we’re only interested in the code you write yourself.

Code should be Well Documented

Good programmers document their code well. Great ones write self documenting code. This means choosing good variable and function names, styling your program flow into small, composable (and easily understandable) functions, and writing comments when necessary. Useful comments are those that add meaning and structure to your composition. If you are an author, you would think of them as footnotes: nobody wants to read a story full of them, but for dense material, it sometimes helps to have them around.

In our Ruby example, we have:

  1. Good documented code
  2. Small functions composed to form the solution. (There are places where this can be improved.)
  3. Generated documentation from our code comments.

Code should be Efficient

Note that this is our last evaluation criteria. We would definitely like your code to be efficient—in both time and space utilisation. We would love it if it runs like a whiz-bang rocket. But if your corresponding code is horribly written and not understandable, you will not win our Code Jam.

I initially developed our Ruby solution in Ruby 1.9.2. Ruby is a slow language, not known for its terribly efficient computation or speed. 1.9 does make it better, but my program does run faster by leveraging another Ruby implementation: JRuby 1.6.2 runs on the JVM and can be as fast as Java, but more importantly for this particular problem, has real native threads that allow you to parallelise the dozens of API calls that need to be made.

Because it’s an elegant language, and because you’ve written code in a modularised way, you end up with an addition of 6 lines of code to make your program considerably faster. And of course, since we have good test coverage, it’s easy to find regressions.

In Short

For MobME Code Jam, we value code that is clear and concise, idiomatic, well tested and documented and finally, efficient. I hope this clears up a lot of questions we have been getting about how to submit answers for Code Jam. We realise it’s not the usual run-of-the-mill programming contest, but do give it a try. Programming while keeping just efficiency in mind is so terribly single dimensional. Do not constrain your creativity, come up with solutions that are worthy of a true artist.

Vishnu Gopal is CTO, MobME Wireless Solutions Pvt. Ltd. He leads MobME’s vibrant and growing engineering division from Kochi, Kerala.

Vishnu is an engineering graduate and has worked in startups all his life. MobME is his most recent venture after stints at SlideShare Inc. and a course in HCI from UCLIC, London.

Advertisement

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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