..

The problem-solving process


It is better to solve one problem five different ways, than to solve five problems one way. George Polya


The text below is a summary of general problem-solving techniques and principles that can be employed around any kind of problem, I am limiting my scope to just the domain of computer programming, this way we can always have a plan of attack anytime we are burdened with a problem to solve.

Table of contents

Always have a plan

This should be considered as the most important rule when approaching a problem. Having a plan in mind is far more successful than just engaging in a directionless pursuit, hoping for a break at the end. This plan would usually always almost need an alteration along the line or may even need to be abandoned completely when more information about the problem is understood; A problem-solving approach without a plan is the equivalent of a monkey randomly typing out letters in the hope of producing Shakespeare (very unlikely😂). Planning allows us set indeterminate goals and achieve them, If we set out to solve a problem without a plan, our goal is “solve the whole problem”. Until this ambiguous goal is reached, we would not have the feeling of making progress towards a solution (if any exists with this plan). A better approach is to create a plan with a series of minor goals, even if some feel unintuitive to the problem at hand, we would make measurable progress towards a solution and feel our time has been spent far more wisely.

Restate the problem

In some cases, a problem that seems very difficult may turn out to be easy when stated in a different way or using different terms. Restating an issue sometimes shows us a goal we set was not what we initially thought it was or meant in the context of the issue. This can be a very powerful technique, but we tend to skip it because it does not involve writing code or designing a solution to a problem. This is another reason why having a plan is essential. Without a plan, our only goal would be to have working code, and restating a problem is taking time away from writing code. With a plan, we can “formally restate the problem” as our first goal towards a solution to a problem which counts as progress. Restating a problem can be a necessary prerequisite step before using other common techniques like dividing the problem. Restating can transform and bring to light more problem areas we weren’t privy to when we initially started the problem-solving process.

Break-down the problem

When we are faced with a problem we find very difficult to solve, we can try a different approach by either reducing or increasing the constraints to create a new kind of problem we find familiar and have probably solved before. We do this to have as much in common with the original problem when working with this smaller sub-problem. The solution to the main problem is a combination of all the smaller sub problems. Breaking down a problem helps us pinpoint exactly where the major problem lies, we can then isolate that specific sub-problem and possibly seek help or further break it down into smaller problems.

Start with familiar problems

Generally when problem-solving, we should try to start with what we already know how to do and work outward from there. Once we have broken down the problems into pieces (sub-problems), we can look out for pieces we already know how to solve. Having a partial solution may spark ideas about the rest of the problem. A common theme with problem-solving is making useful progress towards solutions, so we can build our confidence and momentum that we would ultimately need to complete the task. At every point in our development as programmers, there are many skills we can do well, some with some effort, and then some others we don’t know yet. A particular problem may be entirely solvable with the skills we already have, or it may not, but we should fully investigate the problem using the skills we already know before looking elsewhere. When we begin our investigation of a problem by applying the skills we already have, we may learn more about the problem and its ultimate solution.

Look for analogies(similarities)

An analogy in our case is a similarity between the current problem and a problem already solved that we can exploit to our advantage for the problem at hand. This is not always the case as these similarities can take on many forms; sometimes, these really could just be similar problems, but in a lot of cases we can find similarities only in sub problems (after we have taken the time and effort to break down these problems). Although recognising analogies is an important way to improve our problem-solving skills, it’s also a difficult skill to develop. The reason it’s so difficult at first is that we can’t look out for analogies until we have a lot of solutions to problems under our belts, which a lot of programmers don’t have because it takes some time and effort to accomplish this. Working through the techniques we have discussed in when faced with difficult problems is a step towards gaining this skill.

Experiment

Sometimes the best way to make progress is to try things and observe the results. Note, experimentation isn’t the same as guessing. When we guess we type some code or even copy some code from the internet and hope it works having no strong belief that it will. An experiment is s controlled process, we hypothesize what will happen when certain code is executed, try it out and see whether our hypothesis is correct. From these observations, we gain information that will help us solve the original problem. The basic idea here is to expose any gaps in our understanding by experimenting with the problem on a far smaller scale than the original.

Don’t get frustrated

I cannot stress this enough, we should not allow ourselves get frustrated (easier said than done😌). When we allow ourselves get frustrated, we cannot think clearly, we cannot work efficiently and everything will take longer and seem harder. Even worse, frustration tends to feed on itself, so that what begins as mild irritation ends as outright anger. When we allow ourselves to get frustrated, we are in effect, giving ourselves an excuse to continue to fail. We are deciding that giving in to our anger was easier than facing the difficult problem. Ultimately then, avoiding frustration is a decision we must consciously make. When we feel ourselves starting to get frustrated, we should talk ourselves into remembering the techniques we have discussed, we should always have a plan, no plans are set in stone, if one fails, we should not hesitate to employ another, while writing code that solves a particular problem is the goal of a plan, it is not the only step of in that process. Thus, if we have a plan and are following it, then we are making progress and must believe this. If we run through all the steps in our original plan and are still not ready to start coding, then it’s time to make another plan. Also, when it comes down to getting frustrated or taking a break, we should take break. A neat trick is to have multiple problems we are working on so that if we get stuck on one, we can jump to another one and direct our efforts there. Note that if we have successfully broken down our problem, we can block out the part we got stuck on and work on a different portion. If we don’t have any other issues to solve we can always take a break by getting off our sit, doing a stretch, going on a walk, having a glass of water (we should always stay hydrated) the choice is ours to take.


Hey superstar problem solver! You made it to the end.

What do you think about the post? Have you noticed any mistakes? Did you enjoy the post? I’d love to hear from you: if you feel like it, just reach out to me through my email.

Moreover, I want to remind you of subscribing to my newsletter or RSS feed, in case you don’t want to miss future posts.

Thanks for reading, see you soon!



No spam, unsubscribe at any time (or use RSS feed)