One day you came up with a brilliant solution during a contest, implemented it very carefully, and submitted it confidently. The verdict was ...... WA.
Probably most of you have experienced this sad situation. You can start debugging if you know the reason of WA, but what do you do otherwise? I frequently have trouble with this situation, so I'd like to ask your opinion. What should we do when we get WA?
Here are several possibilities:
1. Reread your code.
This is the simplest way of debugging. You may find some stupid typos.
2. Try various manual testcases.
Examples may not be very strong. Try some small tricky cases against your code.
3. Recheck the correctness of your algorithm.
Have you proved your solution? Is the proof correct?
4. Reread the statement.
You may have misunderstood the statement. Read it again to make sure that you understood the task correctly.
5. Stress-testing.
Write a straightforward solution, create lots of testcases by yourself, and compare both solutions. This is a very strong way to debug your solution, but time consuming.
6. Change the coder.
When you compete as a team, ask someone else to solve the problem instead.
7. Doubt the judge.
Judges are humans. They are not 100% correct.
8. Give up.
You may have other tasks to solve. Simply give up the current task and try something else.
6) Maybe instead of asking your teammate to write a code again it's better to ask him to read your code and try to find bugs there?
And it's also useful to think about some extreme cases such as n = 0 or something else.
your teammate will take ages to understand your code, so it's better idea if he coded it again :D
In ICPC we have done both in various situations. Sometimes using another teammate for Rubber duck debugging is enough, sometimes actually walking the other person through the code helps them discover a mistake you've made, and sometimes it's best and fastest to discard everything and have the other person implement the solution from scratch. I would say that the threshold between these is determined mostly by code length and by acceptance rate of the problem -- we would usually go for the "do it all again" plan in situations when everybody around us is getting AC on the problem and we can't see any issue with the current implementation.
In fact, I've actually successfully used the approach in an individual contest once or twice -- I discarded the entire solution and just rewrote it from scratch, more carefully and possibly in a slightly different way.
Thanks I will check this method in future!
I really like stress-testing
I think you could explain more about your first reason...
Maybe a list of usual typos that we should check them first...
1.5 Check for overflows!
I'll add "write it again, differently". If you already had two ideas, maybe one of them involving more casework, then maybe you won't make a mistake in the other.
Also "check for mistakes which you tend to do". One of them is the already mentioned overflow.
My procedure is very similar to yours, though I fail at #4 a lot of times.
I usually do this:
Actually it goes a bit more like this :P
For team competitions, after you have tried standard procedures and failed to find a bug:
Explain your idea to teammate and then go through code line by line explaining it to him.
I would say this has very high success rate, usually other person will spot some corner cases or suspicious parts of code and ask you questions you haven't asked yourself. Also sometimes, while you are talking out your idea and code you will find errors yourself.
I find this very useful too. When I'm reading code by myself to debug, I tend to think my code does what I want it to do, but I see much clearly when I'm explaining it to someone.
I'll let you all in on a secret. There is a little trick that can make the "explain solution to a teammate" approach way more efficient. This is it:
If you are the one listening, say to yourself that the other person is a complete idiot and that you don't believe a word they say.
I shit you not.
The point here is that it's really really easy to just let yourself be convinced. Your teammate is smart, the stuff they are saying makes sense, it's all too easy to just nod after each sentence and let them convince you that what they are saying is true. This is the default what will happen when you start listening to someone. There are two reasons why this is the default. First, it requires almost no effort on your side, so it's really easy to lose focus and slip into this mode of operation. And second, it feels good -- after all, you are agreeing with your friend, you have established a rapport. But that's not why you are there. Instead, you need to focus on finding the bug. And if you don't already have a lot of training and mental discipline, telling yourself "this person is dumb and I'm going to find the bug they made and laugh at them" will help you focus, and it will put you into the right mindset.
"We may be friends outside the game, but right now I'm your enemy."
I use this trick sometimes. Recently I realized one downside it has: you can convince your teammate that his correct solution is wrong. I actually did it a couple of times.
In ICPC World Finals, I convinced my teammate that his (correct) solution was wrong, only to realize it actually made perfect sense about 10 minutes later. But then I couldn't convince him to trust himself again u.u
For reasons such as these going the full route of "he is an idiot" is not very productive for me. I'd say "you know he made a dumb mistake somewhere" is a better mindset.
If that happens in the beginning of the contest and the problem is rather easy, I will print the source code, ask my teammate to read the problem and the solution, then I will proceed to implementing the next problem in the queue. Happened several times.
No one else codes the problems on your team? Or do you send it to someone else because you think they'll find the mistake faster?
Everyone does, I just type faster than others :) So first problem(s) are typically implemented by me, while my teammates can concentrate on looking for simple problems and solving them. Of course, that does not last long: a special problem can come up where one cannot describe his solution in several words and it'll be faster to implement solution himself; I need rest from coding too.
So, the idea here is to send the program back to either its 'author' or that the problem is simple enough to be understandable from the code. If either is the case, we parallel coding of the next problem and 'debugging' of the previous one (by another pair of eyes, which is efficient); and if neither is the case, we know that the problem is not that simple and requires more careful thinking and discussion, which is less fortunate, but it still useful.
If one of my teammates gets many WA during contest he will no longer be my teammate. Actually, I think he will no longer be anybody's teammate too, and will become afraid of Competitive Programming for all his life. That's how hard men sport works.
>implying
he probably meant one of the two following:
1- proof by contradiction: If one of my teammates usually gets many WA during contests he wouldn't be my teammate
2- If one of my teammates gets many WA during contest he will no longer be my teammate.
And I answered
>implying you'd ever have teammates with that attitude
Do you mean that someone will dare to refuse participating with me? Don't think so...
I don't mean to be a joking, but this technique really works: Rubber Duck Debugging
Stress-testing is really a very powerful idea.
I have written a difficult (for me) program recently. After WA with the stress test I found a rare bug and a "minimal" (with 16 input parameters) test case after about 50-60k iterations.
when tourist gets WA, problem setters wonder if they have made any mistake
True story.
Usually, at least the first few submissions on each problem are examined manually by the judges. This way, if there is indeed a problem on the judges' side, they find it sooner rather than later, and may be able to fix it before it is too late.
And it just so happens that the higher rated coders usually get the first few submissions on a problem...
when tourist gets WA, he asks jury whether they are sure tests are correct (happened to me once :) )
were the tests correct? :D
yeah, they were
Congratulations!
as AliB said you have made first anti tourist contest!
You think that you have got WA in a problem that needs to get your answer mod MOD!
How to debug this codes? or better question is that " how to understand the bug is from main algorithm or it is just for not getting mod in some operations!
It's not hard to check if there are some operations where you forgot to get the modulo
I didn't know there are 7 steps in between....
The particular case of "1. Reread your code":
In my case, sometimes I recall past experiences to find the bugs. After solving thousands of problems, we'll be used to predicting which part is likely to cause bugs. For example, when I'm implementing Aho-Corasick, I often forget to mark the nodes which indicate the string whose suffix is a key. So when I use Aho-Corasick algorithm and get WA, I check this point. (Of course I also check other parts because this algorithm is difficult.) So the more problems you solve, the easier you can find where's wrong.
if I get WA in a problem I try first to revise my code to be sure that I have no stupid mistakes after that I try to hack my idea to make sure that it is true
Can we write to rng_58 and ask him for help? :)
I think that falls under points 6. and 8. at the same time.
Totally re-writing the code sometimes helps.
Specially when there are many cases to handle, and you realize you forgot to handle some case in closely-related cases.
Doubting the judge is never a good idea for rookies like me. After WA ... "OMG!!! Judge is stupid! >_<" After contest.... "OMG!!! I am stupid ;_; " If you're less than yellow, absolutely never doubt the judge.
I do like that:
1.First of all i read the statement if i understood problem correctly.
2.If everything is ok with statement i reread the code for small bugs.
3.If there is nothing i rewrite the code.(This is important because sometimes is better to rewrite the code in ~10 minutes instead of debugging in ~30-60 minutes).
4.If this doesn't work then i delete all and begin to think in a complete different way.
I always first check standings to see how many coders got AC between start of typing and my first submit.
When there are recursions in your C/C++ code, please check whether you wrongly use a static variable instead of a ordinary variable, for example:
It's really confusing sometimes, and when you unluckily encounter this mistake, you might spend hours on it. Both I and tgopknight have suffered from this mistake and we all spend lots of time finding it :(
BTW, it is often the case that you can't pass the examples instead of getting WA. But I think this is still a good piece of advice :)