Codeforces и Polygon могут быть недоступны в период с 6 декабря, 22:00 (МСК) по 7 декабря, 00:00 (МСК) в связи с проведением технических работ. ×

Блог пользователя mredigonda

Автор mredigonda, история, 3 года назад, По-английски

Link to blog post in my website: https://mredigonda.github.io/blog/proper-form-in-competitive-programming/

1

I recently started lifting weights and exercising more, I wish I would've done that while I was practicing for IOI / ICPC.

My mind kept telling me that an hour in the gym was an hour I could've spent practicing for competitions, and while that was technically correct, that didn't took into account all of the benefits from exercising, not only to my health but also directly to my performance in competitions.

One important aspect that I think would've benefitted me from exercising more is the analogy of exercise and problem solving. Actually, when practicing for competitive programming competitions, I even call it "training" too.

Not all of the analogies will match perfectly, but I find it interesting to analyze them.

There are the straightforward analogies about challenging yourself. While these are kind of trivial, they can be useful to someone.

For example, the common advice is "practice practice practice", but in the gym, if you "practice practice practice" with the same weights every time, you will have a hard time trying to lift heavier weights.

The same is true for problem solving, if you always solve problems, say, with 1800 rating points on Codeforces, you won't be able to easily solve problems with rating 2300.

So you not only need to practice practice practice, but do so with problems that challenge you enough so that you learn new things, or improve the confidence on already existing knowledge / speed. Something similar is explained in The 'science' of training in competitive programming.


2

I have a less obvious analogy.

When you are lifting weights, it's extremely important that you do so with a proper form. Not only this is needed to avoid injury, but it's also important to make the exercise you are doing, target the exact muscle you are trying to build.

Some exercises are about moving something from position A to position B, but the way you do it is what matters. If you lack mind-muscle connection, it's common that you compensate using much more your, say, biceps and forearms, than using the exact muscle you are trying to train, say, your lats or traps.

One might think that is capable of lifting, 65kg in a certain exercise, but reality might indicate that he can only do so properly with at most, 40kg. Between training 65kg improperly, or lifting 40kg properly, I always prefer the proper option, to avoid injury, but also to more efficiently target the muscles I want to build.

Now how this relates to competitive programming?

I remember when I was practicing for ICPC World Finals, I used to practice with hard problems. Eventually, after about 2 hours of trying, I was able to get a solution.

My solutions to many problems have a certain common pattern, they are usually overkills. Yes, they work, but there is usually a clever idea that would turn an hour of coding into ten minutes.

What's worse is that I felt succeeded after the problem was done, and the accepted verdict was given.

My conjecture is that by reducing the difficulty of the problems I was solving a bit, and making a stronger effort to really understand solutions and clever ideas to problems, even when I already solved them "my way", then practicing those ideas until they become fully automatic, I would've had a much better performance my competitions.

I suggest you to exercise, and learn about it, even while heavily training for competitions.

  • Проголосовать: нравится
  • +144
  • Проголосовать: не нравится

»
3 года назад, # |
  Проголосовать: нравится +69 Проголосовать: не нравится

Anderson Silva approves this!

»
3 года назад, # |
  Проголосовать: нравится +18 Проголосовать: не нравится

How much do you bench?

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    exactly 0310 times

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится +14 Проголосовать: не нравится

    I don't yet bench! It's been three months and my trainer puts lots of focus on the posterior chain. Also intereting to analyze in terms of competitive programming, that seems to be the equivalent to training geometry problems which many people skip because "they are ugly".

»
3 года назад, # |
  Проголосовать: нравится +18 Проголосовать: не нравится

Interesting. I have also noticed these parallels.

I wonder if we should try to apply sports periodization to competitive programming. I guess the analogy would be: a long period where you solve a bunch of standalone hard and slightly hard problems (by standalone I just mean outside a competition environment) and upsolve problems from previous contests you did, followed by a shorter period where you take lots of contests and virtual participations and ignore upsolving/practice of standalone problems.

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится +32 Проголосовать: не нравится

    Based on some published documents I have seen (like papers and other material related to the IOI Russian Team Leaders and Trainers), I am pretty sure many strong teams / delegations already do :P

    One example that comes to mind is https://ioinformatics.org/journal/v14_2020_151_167.pdf

    I totally agree that focusing on "fully understanding a problem and seeking simpler to code, smarter solutions" is a key thing to do, in order to grow stronger mid/long term, as opposed to just overkilling everything. When an important contest is near, then basically there is no time to grow such skills, just code and practice team dynamics / 5hours endurance and get to the contest well slept :P

    • »
      »
      »
      3 года назад, # ^ |
        Проголосовать: нравится +47 Проголосовать: не нравится

      A fragment of such paper:

      "There is a common misconception that participants allegedly grow during participation in various competitions. This is not true. In the competition, they only demonstrate what they have accumulated over many days during hard training. And if there is no good training process, or if the participant himself for some reason does not work well or is not motivated to succeed, then he does not show high results in the competition.

      Frequent participation in competitions indiscriminately, mixing of specifics in competitions without targeted training leads to fixing the participant’s incomplete result on the tasks of the competition, no higher than 50 percent of points and lack of perseverance in training. As a result, the opposite effect is fixed – the inability to work for a full score, the highest result and the unwillingness to hone it in independent constant work. You need to learn how to get a high result, and most importantly, do it at the Junior stage, so that there is time to improve the participant at the peak of his capabilities, that is, to open the child to take off to his own capabilities."

»
3 года назад, # |
  Проголосовать: нравится +67 Проголосовать: не нравится

Along the lines of your post, some examples of what I consider to be "proper form" (and insist a lot to my coachees :) )

  • Avoid "copy paste" like the black plague. If at all possible to not copy paste, do not copy paste. If needed in contest, then it is worthwhile to afterwards rethink the implementation. How could I have avoided this particular copy paste here?

  • Contract based programming. Reason pieces of programs in terms of contracts (exactly what it needs, exactly what it does). Do not just "add a multiply by 2 here because that way it now passes samples" without understanding why. Maybe this function is correctly solving ITS contract, but then somewhere else there is a totally different *2 missing, and just by luck any of those *2 passes samples. Bonus points: this way of doing things allows meaningfully testing different pieces of code separately, allowing faster debugging.

  • Consistent use of "range borders indexes" (for example, closed / open [a,b) which is probably the most common) and thinking in terms of "edges" vs "cells", and which is best for the problem at hand (every index has a "different" meaning depending on whether you think of it as indexing a cell, or indexing an edge between two cells). Probably that will depend on the drawing / geometric intuition involved in the reasoning of the problem. "Guessing whether +1/-1 and changing until it passes samples / gets AC" should feel terrible (and is obviously super bug prone).

  • Make a lot of drawings. Always try to interpret things geometrically as much as possible. Huge amounts of geometrical intuition can be used in most typical "greedy" problems for example, which is very often hidden behind a very algebraic "formal proof of correctness" in an editorial (or just left as exercise).

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится +26 Проголосовать: не нравится

    Often, the very first solution you think about will not have these desirable properties. So it is great exercise to actively keep thinking about an existing solution / implementation, asking whether you can make it better in these terms, until they come naturally.

  • »
    »
    3 года назад, # ^ |
      Проголосовать: нравится +18 Проголосовать: не нравится

    This is good enough advice that it is deserving of its own post