When designing an algorithm for a given problem, sometimes I find it hard to foresee or clarify to myself what the boundary/edge/corner cases are. Not being able to come up with a decent number of the possible boundary/edge/corner cases causes one to make implicit assumptions about the problem at hand, which yields overlooked cases not to be accounted for, which is not good.
When reviewing the classic "Programming Challenges" by Steven S. Skiena and Miguel Revilla, one can read the following:
This is why it is so essential to review the specifications carefully. Even when you may be sure that your program is correct, the judge may keep saying no. Perhaps you are overlooking a boundary case or assuming something which just ain’t so. Resubmitting the program without change does you absolutely no good. Read the problem again to make sure it says what you thought it did.
I think it would be useful to sort come up with a method to, given a problem statement and the problem's input domain, assist the algorithm designer with unveiling boundary cases.
On one hand, knowing the upper and lower boundaries of your input data, helps you choose data types that can represent said values.
Another useful technique I do, is to ask myself, per each explicit assumption I can extract from the problem specification, what must exist for that assumption to be valid? For example, if I am told that all values will be given as a sorted array, does that mean that the given list will never be empty?
I would like to continue putting together a set of thumb rules to assist ourselves in uncovering boundary cases.