Learning How to Learn Competitive Programming


Last week, Quora hosted a session with Barbara Oakley, one of the two instructors for Learning How to Learn, “the world’s largest online course.” During the Quora session, people asked her questions about learning techniques, public speaking, online courses, and other topics. I took the Learning How to Learn class when it was first offered on Coursera, and found it to be a good survey of current learning research, combined with plenty of advice on how to apply it. So when Oakley’s session popped up on Quora, it caught my eye.

It’s worth taking the whole course on Coursera, but the Quora session offers a concentrated summary of a few key ideas. I thought it would be interesting to apply some of Oakley’s advice from the session to the type of learning that goes on here at Red-Green-Code.

The Most Effective Learning Technique #

The textbook for Learning How to Learn is Oakley’s 2014 book, A Mind for Numbers. In the book, she introduces the concept of conceptual chunks, which she defines as “pieces of information that are bound together through meaning.” A simple example is an English word. If you wanted to memorize the sequence of characters qzjsyp, you would first have to split it into six characters. However, if you were memorizing the sequence queens, you could remember it as a single entity. That single entity is a chunk. It consists of six characters in a particular order which combine to form an English word. Since human working memory consists of a limited number of slots (about four, according to Oakley), it’s critical to chunk information that you need to have available while you’re working on related problems.

In the Quora session, Oakley contends that all learning techniques are ultimately a way to facilitate the development of conceptual chunks. She gives the example of learning how to solve a math homework problem, using the following process:

  • Study an example of the problem to learn the correct procedure.
  • Apply the procedure to another problem, working through it until you get the answer.
  • The next day, solve the problem again without looking at your first solution,
  • Repeat this process until you can solve the problem easily.
  • Next, practice solving the problem in your head without writing down the steps.

The goal of this process is to turn the act of solving this type of problem into a single conceptual chunk. Then when you encounter the problem as part of a more complex problem, you can recall in a single step the procedure for solving it.

Application to competitive programming

Applying the theory of conceptual chunking, learning to program consists of forming larger and larger chunks. When you’re first starting, you might learn what the statement for (int i=0; i<n; i++) means by reading a tutorial that explains each of the three sections between the parentheses. At this point, you might see each section as a separate chunk: initialize, check a condition, increment.

Later, you learn about other types of loops, and how to choose the best one for a particular task. Now you can recall a loop definition is a single chunk, without having to remember the sections individually. Eventually you reach the point where you can recall a simple loop-based algorithm, like binary search, in one step.

Competitive programming study provides a structured way to expose yourself to different algorithms and problem-solving techniques. By repeatedly using programming language features, applying problem-solving techniques, and implementing algorithms, you can create neural chunks. Once you have chunked something useful, you can apply it to future problems without using much of your limited working memory. For example, consider a problem like UVa 12192 that requires adapting binary search for a new purpose. If you have chunked the baseline binary search algorithm, you can recall it into your working memory, and then modify it as required by the problem.

The Best Approach for Learning New Things #

In another Quora answer, Oakley covers some learning tips, including these:

  • Repeatedly recalling information is key to learning it: When studying, it’s easy to rely on techniques like underlining, highlighting, and rereading. But it’s more effective to use techniques that force you to recall information. For example, read a textbook page or watch a video, and then try to recall the main idea by writing or drawing it.

  • Explain a concept in the simplest terms you can: Explaining a concept in fundamental terms has several advantages: You prove to yourself that you really understand it. You identify any areas that need more study. And you create a reference artifact that you can use to refresh your memory in the future. Oakley attributes this technique to Charles Darwin. It is also often associated with Richard Feynman.

Application to competitive programming

Practicing competitive programming is a constant process of recalling what you know about a topic, and applying that knowledge to a problem. The key is to keep solving problems of a given type until you can do so without looking anything up or copying and pasting code from previous solutions. After enough iterations of this process, you’ll be familiar with all of the standard competitive programming algorithms and how to adapt them to new problems.

To explain what you know about a concept, you could just write a note to yourself. But since people always have questions about how to solve competitive programming problems, there are plenty of opportunities to explain things in public. You can answer these types of questions on message boards, in blog posts, and on Quora (but usually not on Stack Overflow). This is another type of practice, and it exercises different mental muscles than solving problems on an online judge.

The Fastest and Most Effective Learning Process #

It’s a Quora tradition to ask the same question in as many different ways as possible. In this third variation on the theme, Oakley provides yet more hints for effective learning. Here are a couple:

  • Spread out your learning over time: Some things take time to learn, and can’t be rushed. At a minimum, it’s a good idea to spread learning over two days instead of one, since sleep is an important step in the learning process.

  • Break the material you’re learning into small bits: If a topic is too difficult, you can make it easier to grasp by tackling it in smaller pieces. This also helps implement a deliberate practice strategy, since you can isolate the parts you have the most trouble with, and practice them until they’re no longer difficult.

Application to competitive programming

Competitive programming practice is perfect for spreading out over time, since the only realistic way to approach it is by solving numerous practice problems. How much you spread out the learning process is up to you, but there are pros and cons to learning at different speeds. Scott Young wrote a post this week on that topic.

Turning small bits of learning into larger ones is also a standard part of competitive programming practice. Every solution to a programming problem is made up of numerous small pieces of code, down to individual statements as described in the discussion of conceptual chunking. If you have trouble understanding a particular piece, you can always extract it into its own program and study it in isolation. Once you do that with all of the pieces you find difficult, it becomes easier to understand the program as a whole.

(Image credit: Dushan Hanuska)