One of the most important skills you learn in your computer science courses is how to problem solve. Although we cover some general problem solving paradigms in class, the best way to improve these skills is to get practice, practice, and more practice. Different people have different techniques that work best for them; below are some general tips that work for most people.
Please read these suggestions carefully.
Questions the Helpers May Ask You
When you ask a lab helper for their assistance, they will assume you have tried to solve the problem yourself. They will (reasonably) expect that you have tried out the steps outlined in this document; you should therefore be prepared to answer the following questions:
- Did you re-read the prelab and lab?
- Do you understand the problem?
- Have you tried solving some examples by hand?
- (For problems designing a solution) What have you tried? What topic from class does this most ressemble?
- If you can’t solve the problem whole-hog, what small case canyou solve?
- (For syntax errors) What line of your code is causing the error? What do you think the compile error means, and what usually causes this kind of problem?
- (For logical errors) On what example does your program consistently break? Have you traced through the program? Which line of your program is not doing what it should?
Four Main Problem Solving Steps:
1. Understand the Problem.
Solving the right problem is the most important part of problem solving. Be sure, absolutely 100% positively sure, that you understand the problem before attempting a solution. This involves:
- Reading the prelab and labvery carefully (including all bold text, italicized text, and everything else);
- Reviewing class noteson related topics;
- Trying some small examplesto make sure you understand what is being asked; if examples are given to you, make sure you understand them before continuing, as they are usually there to help clarify some common misconceptions; and
- Asking someone to help clarify anything that is still confusing.
2. Design a Solution.
Formulate an algorithm to solve your problem. This involves:
- Understanding what is being asked of you. See step 1.
- Draw out some examples. Use paper. How would you solve these small cases, by hand? Is there a method to what you are doing? Try to formalize the steps you are taking, and try to think about whether they would work more generally, in bigger cases. Then try some bigger cases and convince yourself.
- Reread the prelab. Did you already run some examples by hand? Did you have trouble with it then?
- Write down the stuff you know about the problem and the examples you’ve tried, so that you can more easily find patterns.
- Might a recent topic from class help? Usually at least some, if not most, of the lab will make use of recently covered material. Go over that topic, make sure you understand it, then try to make connections to lab.
- Split the probleminto smaller (more manageable) chunks, and try to solve the simpler problems. Go as small as you need in order to find some solution. Once you have the smaller problem solved, worry about how to generalize it to a slightly larger problem.
- Just try something, anything, even if it is completely random and obviously wrong. When/if your attempt doesn’t work, it may still give you insight into what maywork. It is not as crazy as it initially sounds!
- Use a friend, lab helper, puppet, etc. as a sounding board; sometimes, just voicing your problem will lead you to the “aha!” moment you need.
- If you are still stuck, step away from the keyboard. Take a walk, go eat dinner or have a coffee. Sleep on it. Not literally. Taking a break is sometimes the most productive thing you can do, trust me.
- Finally, stay positive. Even when things don’t work, you can still gain a better understanding of the problem. Don’t give up, just go with the flow and see where it takes you. Struggling is part of the process!
3. Implement your Solution.
Write the code to solve your problem. This involves
- Understanding the problem, and designing a solution on paper. See steps 1 and 2.
- Translating your design into actual code. Rather than doing this linearly, implement small chunks at a time. Break your code into subroutines, and make sure that each subroutine works before proceeding to the next. Compile and save often.
- If you run into syntax errors, determine which line of yourcode is causing the problem. You can do this by systematically commenting out blocks of code until you find the block that causes the problem.
- If you run into logical errors (as in, the program compiles but does not do what it is supposed to), find some examples on which your problem consistently fails. Trace through the programline by line, with one of these examples, to figure out exactly which line is not doing what you intend it to.
- If the output doesn’t match what you expect, use print statements to trace through what your program is doing, and compare that to what your program should be doing. Even better, if you know how to use a debugger (in eclipse, for example, use it!)
4. Check your Solution.
This step is often overlooked, but is absolutely crucial. Your program does not necessarily work because it works on the given test cases on the lab. You have to think critically about what you code. This involves
- Certainly check your programon all test cases given to you on the lab and prelab. The prelab often specifically contains hand-solved test cases precisely for this purpose!
- Thinking about the “boundary cases,” such as, when would this array go out of bounds? For what indices will this for loop start and end?
- Think: how would this program break? Then, that failing: how would I convince my skeptical friend it can’t be broken?
Remember: problem solving is a creative process, which cannot be forced. Don’t get angry if you don’t see the answer right away, or you don’t see it as fast as your friend. You will have different strengths, and you can always improve. You will learn from your mistakes, so that’s always a plus!