EugeneJudo's blog

By EugeneJudo, history, 3 years ago, In English

I've found that I frequently engage in the following anti-pattern:

  1. I read the problem description and start writing out some details on paper (to better visualize what's happening.)
  2. I get the right idea for how to solve the problem and start implementing it before figuring out every detail.
  3. I test the program and find it (shockingly) misses some sample cases.
  4. I go back to the paper and notice something I missed.
  5. return to step 2.

For Div 2 A/B problems, this process tends to be sufficient to get the right answer, but it fails badly beyond that, and it also very quickly eats up huge amounts of time. I know I should write out all of the details, but there's always some details that get left out. I'm really curious to hear what others processes are when solving problems they consider hard. E.g. do you prove every bound beforehand? Do you write out pseducode and then implement it?

  • Vote: I like it
  • +34
  • Vote: I do not like it

| Write comment?
»
3 years ago, # |
  Vote: I like it 0 Vote: I do not like it

Sounds like lack of practice to me.

Some advice would be to Replicate the same thing during practice and find out what are you lacking?

»
3 years ago, # |
  Vote: I like it +12 Vote: I do not like it

Take the time to figure out details before you implement. It may help to do some practice where you physically don't have a computer in front of you, so you couldn't rush to start coding even if you wanted to. Sometimes I'll take a walk when solving problems to give myself more time to think. This isn't something I'd do in a contest, but it gets me into the habit of fleshing out ideas more before I implement them.

I don't prove bounds (or anything at all, to be honest) before I code, but I do enough thinking to be reasonably confident that an idea will work. I might be in the minority when it comes to this, but I'm not sure.

I also don't write pseudocode, and I can't think of anybody who does off the top of my head. You should take that with a grain of salt though, since I don't know the problem-solving habits of more than a few people. As long as you know how your idea will work, I don't think pseudocode is necessary.

»
3 years ago, # |
  Vote: I like it +24 Vote: I do not like it

This is a good question, and that "anti-pattern" also happens to me.

For example, yesterday I spent 1:30 hours on 1556C - Compressed Bracket Sequence because I wasn't able to consider all the details at once (so I always had a mistake somewhere in the code). The same happened while solving 1342C - Yet Another Counting Problem and 1543D2 - RPD and Rap Sheet (Hard Version).

I think you can fix this by considering the details one by one (this is the reason why I feel quite comfortable when casework is involved). For example, this is how I solved 1556C - Compressed Bracket Sequence at the end: for two fixed blocks of brackets,

  • there should be between $$$a$$$ and $$$b$$$ brackets on the left
  • there should be between $$$c$$$ and $$$d$$$ brackets on the right
  • there are $$$k$$$ more brackets on the left than on the right

So the problem became

  • Find $$$a$$$, $$$b$$$, $$$c$$$, $$$d$$$, $$$k$$$ (difficulty: Div2A)
  • Count the pairs $$$(x, y)$$$ with $$$a \leq x \leq b$$$, $$$c \leq y \leq d$$$, $$$x-y = k$$$ (difficulty: Div2A)

Now the problem should be easy both to solve and to debug. So don't try to consider many details all together, start immediately to split the problem into simpler tasks.

  • »
    »
    3 years ago, # ^ |
      Vote: I like it +8 Vote: I do not like it

    Thanks, this was the exact problem that I got frustrated at for having 2 hours left to solve and failing. Focusing on breaking into subproblems sounds like the right idea.

»
3 years ago, # |
  Vote: I like it 0 Vote: I do not like it

watch death note and think like L

»
3 years ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

what programming language is mental? i think adding a break statement is enought.(it's a joke)

  • »
    »
    3 years ago, # ^ |
      Vote: I like it +8 Vote: I do not like it

    Sorry, mental doesn't contain a break statement, and return definitely doesn't do what you want it to. Although a similar effect can be achieved by raising an exception and catching it outside of the loop, this process is tedious and error-prone, and usually doesn't work well with the design of the language. Locally performing the analogous construction with an error-passing monad fares a bit better, not least because the type system will force you to handle the error.

    But the idiomatic approach to breaking out of a loop is callCC: Before entering a loop construct that you may need to break out of, take note of what you are going to do when done looping (the "current continuation"). Then, when you need to break out of the loop, ignore the next action the loop construct would have you perform and skip to what you were going to do after the loop.