Saturday, May 9, 2009

Learning while Coding

There has been a phenomena that has been bugging me for a while, but I just couldn't put my finger on it. A couple days ago my brother (a non programmer) asked about which programming language to use for a little project of his. I asked what the project was, and didn't get more than some vague statements. He said that he wanted to start coding and figure out how to do it on the way. I have been guilty of this many times (including the AI project I am currently having trouble with). I think it is one of the most inefficient ways of going about programming.

For some reason when you code you aren't able to focus on the big picture of the program. I have a very hard time anticipating problems I am going to have 20 lines in the future until I actually get there. There are plenty of TopCoder problems where half way through I realize that my algorithm doesn't work. I have had the same thing happen at my internship over the summer. In a good case I figure out the problem before I am finished coding, occasionally it takes until I start debugging to figure things out.

I think the problem comes from the fact that it is hard to spend the time and understand your algorithm. It's very easy for me to just dive in and start coding. For some reason I am scarred of going through the work to really figure out exactly how things are going to work. I think that being able to plan things out in detail (to the point where what you code doesn't change much between the first draft and the final version) is a crucial skill for both competative programming and for programming in the real world. 

I think you can really see the difference when it comes to debug time. Look at the last problem we solved at the ACM world finals. Alan and I talked it over thoroughly and we really knew exactly what we wanted to do. The code got written in about 15 minutes and the debug time was just a couple of minutes. Contrast that with my performance on the medium problem in the TopCoder open round 4, I recognized it as DP (without grasping the full complexity of it), jumped in and started coding. After an hour I was still debugging a flawed algorithm.

Another example is coding malloc. My friend just jumped in and started coding it. He was well on his way to finishing the code while I was still figuring out how I wanted to setup my #defines. I debugged it for a couple of hours, it took him days to finally get his code correct. Planning is especially important for things like malloc (basically a ton of bit operations, and problems show up way after they occurred). The more complicated the code, the more you need to plan.

When I started TopCoder I always wanted to be really fast. Speed was a huge focus for me as it is for many other competitors. I think that focusing on speed early on doesn't help the learning process at all. The real focus should be on correctness. Plan things out on paper in detail and get things correct (in practice and in the contest). After doing that for a while it is easy to recognize a problem that you can solve quickly without planning and ones you need to spend a half our coding.