Bits of Learning

Learning sometimes happens in big jumps, but mostly in little tiny steps. I share my baby steps of learning here, mostly on topics around programming, programming languages, software engineering, and computing in general. But occasionally, even on other disciplines of engineering or even science. I mostly learn through examples and doing. And this place is a logbook of my experiences in learning something. You may find several things interesting here: little cute snippets of (hopefully useful) code, a bit of backing theory, and a lot of gyan on how learning can be so much fun.

Tuesday, April 16, 2024

Uncompetitive Programming (part 1)

I recently had an interesting discussion with one of my young relatives -- a second year engineering student in computer science -- who, like many of his age, is fascinated by the idea of competitive programming. Competitive programming (CP) involves solving algorithmic problems/puzzles by writing programs. These problems typically involve some CS theory, particularly in data structures and algorithms. There are many online sites which provide practice ground for CP aspirants. The pinnacle of this, to the best of my knowledge, is ICPC. One of our alums went on to the World finals. This contributed in a big way to his getting recruited by Google, USA with a record-breaking salary. This achievement set off a CP culture in our institute which has been going strong since. Some of our brighter students gravitate towards the CP culture, with dreams of becoming the next Google hire.

CP emphasises on CS fundamentals. To rise in the CP community, one needs to be good with algorithms, some basic mathematical thinking and in coding in at least one programming language. As CP happens in time-bound environment, one needs to develop quick thinking skills. Undoubtedly, CP aspirants are closely followed by top hirers. They have their fundamentals right, they are smart and fast, and they function well under extreme pressure -- exactly the qualities top companies are looking for in their new employees, right?

Yet, I believe that CP is not for everyone. And by that, I don't mean that people who can't handle the high pressure and expectation of CP shouldn't do it. That, of course, goes without saying. But what I mean is that, with all its good things, CP ends up testing the programmers for a limited set of skills, and misses out on many others which may be equally or more important than the ones which are tested in CP.

I would like to draw a parallel with academic assessments. Take IIT JEE. About 30 years ago, when we were school students preparing for college entrances, IIT JEE used to be viewed as an ultimate test of academic brilliance. While, its focus was restricted to science and mathematics, it was perceived as a reasonably reliable metric of measuring natural intelligence. To crack JEE, you needed to be someone. Conversely, if you have cracked JEE, you are someone. 

Things have changed since then. IIT JEE, like all assessments, has devolved into a pattern now. Because of the coveted status of IITs, there are millions who dream to crack JEE. And there are people who have made billion-dollar businesses out this aspiration. They have studied the JEE pattern and have developed methods of preparing students so that they can do well in JEE, not because they are very intelligence, but because of hard practice that has drilled the JEE pattern into their minds. Acing JEE is no more a surefire indicator that you are built differently. It's definitely about hard work and a lot of practice. But, to a large extent, it may be an indicator of something negative -- probably, you are more competitive than academically brilliant; and these are two entirely different things. Such high competition may now be routinely excluding brilliant students with potential to become groundbreaking engineers from entering IITs because they are not able to handle the psychological pressure of such high competition. It's a tragedy of unprecedented scale!

CP culture has a not-so-hard-to-see similarity with IIT JEE. With growing demand, CP has been attracting students in whom the competitive part dominates their programmer part. By practice-solving hundreds of similar problems, many of these aspirants develop high degree of pattern matching skills, sharpen a bag of tricks to code something up quickly. They are often like overfitted ML models which will do really well in CP-like environments and will do well in just that kind of environment.

A terrible side-effect of this phenomenon is that programming is now increasingly being viewed as a quick-and-dirty problem-solving activity. And many of our bright students don't even consider the possibility that programming is also a creative exercise that can't always be done in high-pressure timebound manner, but through open-ended exploration. Time pressure and open-ended exploration directly conflict with each other; they are two extremes of a spectrum. People who have trained hard to get close to one of these ends of the spectrum are very unlikely to develop well on the other. And we need people at all points in this spectrum.

In real world, CP-style deadline driven algorithm design and coding is not always realistic. Usually, for a task that matters, the solution is not likely to be very cut-n-dry. In such cases, merely a performant code that gives correct results is far from enough as an output. You have to be able to explain clearly to others how you came up with the solutions and how the whole damn thing works. Happily, you would typically have much more time than in CP to come up with such a solution.

A CP-style programmer has certain skills tuned to perform well in the high pressure setting of CP. There's a tendency of pattern matching (with familiar problems) and to hack it to make it work 'somehow'. This mayn't be a good style in many settings where thinking slowly but thoroughly and clearly is more important.

While designing a solution, there may be many false starts. Writing things down in the language of plain English, pictures and mathematics helps us think ahead and correct our course early. Starting to code right away may give us a mistaken sense of early progress but may lead to difficult-to-correct mistakes down the line, particularly when the problem is challenging.

Part 2 of this article presents an example of solving a problem that appears in a competitive programming site. 

I hope that you will be able to see the differences w.r.t. to CP that I am trying to bring out here. 

To conclude this part of the article:
  • Programming is like an art. It's as much about experience and aesthetics as about output.
  • Ability to do thorough thinking is more important than thinking fast.
  • Ability to communicate through written words and pictures is more important than hacking. 
  • Readability is (more often) a far more important quality of a code than squeezing every cycle out of your processor.
This is a logical point where it's OK to stop reading. But in case you plan to continue please proceed to part 2 in which I discuss with an example how an uncompetitive programmer would approach a CP problem! 😀

No comments: