When I came up with 12 Reasons to Study Competitive Programming, I picked the following for reason #3: Studying competitive programming gives you a way to practice solving hard problems.
(As I pointed out in the article, this is also a reason that some people give for not studying competitive programming. They claim that most software developers work only on trivial problems. So they don’t see any reason to practice solving hard problems. That has always seemed to me like a backwards argument).
What does it mean for a problem to be hard? To answer that, I’ll borrow part of the definition of deep work: a problem is hard if it requires specific training and experience to solve. While some ad-hoc competitive programming problems can be solved by any programmer willing to spend an hour or so thinking and coding, modern contests contain problems that only programmers who have spent considerable effort practicing can solve in a reasonable amount of time.
That’s the type of hard problem that I’m talking about. To be hard, a programming problem doesn’t have to involve an unsolved research question. But it does need to provide a challenge to people who spend a lot of time solving puzzles.
What makes competitive programming hard? Here are some factors.
Its Relationship to Coding Interviews
Many programmers approach competitive programming as a way to prepare for coding interviews. Companies like HackerRank and CodeEval encourage this way of thinking by setting up online judges to help companies find and hire developers.
There’s nothing wrong with associating competitive programming with job interviews, but that association tends to attract developers with a range of skill levels. People who wouldn’t otherwise be interested in coding competitions might decide to participate as a way of getting an interview or job offer. And they may find it difficult to compete with people who have spent years preparing for competitions. That makes competitive programming seem hard in the sense that it’s hard to jump into with minimal preparation.
If your goal is winning competitions, and not just getting better at coding, then competitive programming gets harder as it gets more popular. This is true of any competitive activity. As more people take it up, it’s more likely that the participants will include some who devote a lot of hours to practice. When this happens in programming contests, problem setters respond by increasing problem difficulty to challenge the most dedicated participants. For example, CP3 makes the point that dynamic programming used to be an advanced technique that was only required for the most difficult problems in a contest. Now every competitor has to learn it to avoid getting locked out of otherwise easy problems.
Its Objective Standards
Online judges are unforgiving when it comes to grading. There’s no partial credit. If your code doesn’t pass all of the test cases, it isn’t accepted. Some judges (like UVa OJ) don’t tell you how your code did on each test, or even how many tests the judge is running against it.
Programmers are familiar with having their work interpreted by a literal-minded audience (the computer). But with real-world programs, the ultimate audience is the human user, who may be willing to forgive a few bugs if your program fulfills a need. Not so with online judges. Either your answer is exact, or you’re out of luck. And since problem statements tend to be written in an obscure style (partly by design), you don’t always have all of the information you need to produce the exact answer that the judge is looking for. It takes some practice to get good at debugging with this deficit of information.
The Quality of Programming Instruction in Computer Science Programs
Competitive programming classes are sometimes offered in universities but they’re far from standard in the Computer Science curriculum. Even non-competitive programming is de-emphasized by traditional universities, which are more concerned with teaching theoretical subjects that don’t go out of date rapidly. Students are expected to pick up programming languages and skills on their own time.
Given this background, it’s not surprising that many computer science students and graduates find it difficult to solve programming puzzles on the fly in coding interviews or programming competitions. They just haven’t been taught techniques to do it effectively.
The Need for Active Learning
On many online judges, it’s possible to copy and paste other people’s solutions and submit them as your own. While this might get you imaginary Internet points, it won’t help you get better at programming, even if you read the stolen code before submitting it.
The way to get better at competitive programming is active learning, which in this context means:
- Writing and submitting your own solution.
- If necessary, debugging and re-submitting it until it passes, or until you have spent a reasonable amount of time trying (at least a few hours).
- Then reading someone else’s editorial and/or solution, but not submitting it directly.
- Re-writing your own solution using what you learned, and submitting that to see if it passes and/or runs faster than your original attempt.
This process is hard work, but it’s the only way to get better.
The Need to Build on a Strong Foundation
Everything you learn in competitive programming builds on prior knowledge. Programming language fluency depends on being familiar with language syntax and libraries. Solving ad-hoc problems requires general problem-solving experience plus language fluency. More difficult problems require all of that plus familiarity with the right algorithm. And solving a difficult problem quickly usually requires having solved a similar problem several times in the past.
Trying to skip ahead — for example, attempting algorithm-heavy problems before mastering the art of ad-hoc problem solving — is a recipe for frustration. You have to be willing to go through the training process in the right order.
The Need for Persistence
At this point in its history, competitive programming has a large body of knowledge, and a large group of motivated participants. This means the only way to distinguish yourself is to prepare for a long journey. If you follow the previous advice about building on a foundation, then you may find that topics that seem hard now become easier in the future. Nevertheless, it can be hard to stick with a plan for as long as it takes to become an expert.
Competitive programming and competitive math have a lot in common. I found the popular Quora question Why is mathematics so hard? to be useful as I was writing this list.
The Nature of Hard Subjects
It’s hard to excel in any subject that attracts a group of serious practitioners. Those practitioners quickly solve all of the easy problems, and then they’re ready to tackle more challenging topics. Fields like mathematics research and musical performance have attracted experts for hundreds of years, so doing well in those fields requires significant dedication from a young age.
But even competitive programming, which has only been around for a few decades, has reached the point where doing well (compared to the competition) requires a serious investment of time and a willingness to approach your training in the right way.
(Image credit: Sasquatch I)