Methodology of Problem Solving

Methodology of
Problem Solving
Efficiently Solving
Computer Programming Problems
Doncho Minkov
Technical Trainer
Telerik Corporation
www.telerik.com
Problems Solving
From Chaotic to Methodological Approach
How to Solve Problems?
1.
Read and analyze the problems
2.
Use a sheet of paper and a pen for sketching
3.
Think up, invent and try ideas
4.
Break the problem into subproblems
5.
Check up your ideas
6.
Choose appropriate data structures
7.
Think about the efficiency
8.
Implement your algorithm step-by-step
9.
Thoroughly test your solution
3
Understanding the
Requirements
Read and Analyze the Problems

Consider you are at traditional computer
programming exam or contest
 You have 5 problems to solve in 6 hours

First read carefully all problems and try to
estimate how complex each of them is
 Read the requirements, don't invent them!

Start solving the most easy problem first
 Leave the most complex problem last

Approach the next problem when the previous is
completely solved and well tested
5
Analyzing the Problems
 Example: we are given 3 problems:
1. Set of Numbers
 Count the occurrences of a number in set of
numbers
2. Students
 Read a set of students and print the name of the
student with the highest mark
3. Binary Representation
 Find the 'ones' and 'zeros' of a set of numbers in
their binary representation
6
Analyzing the Problems (2)
 Read carefully the problems and think a bit
 Order the problems from the easiest
to the
most complex:
1. Set of Numbers
 Whenever find the number increase a count
variable with one
2. Students
 Temporary student with current highest mark
3. Binary representation
 If we know the 'ones', we can easily find the zeros
7
Using a Paper
and a Pen
Visualizing and Sketching
Your Ideas
Use a Sheet of Paper and a Pen
 Never start
solving a problem without a sheet
of paper and a pen
 You need to sketch your ideas
 Paper and pen is the best visualization tool
 Allows your brain to think efficiently
 Paper works faster
than keyboard / screen
 Other visualization tool
could also work well
9
Paper and Pen
 Consider the "Binary
representation" problem
 We can sketch it to start thinking
 Some ideas immediately come, e.g.
 Divide by 2 and check for the remainder
 Bitwise shift right and check for the rightmost bit
 Bitwise shift left and check for the leftmost bit
 Count only the "zeros"
 Count only the "ones"
 Count both "ones" and "zeros"
10
Invent Ideas
Think-up, Invent Ideas and Check Them
Think up, Invent and Try Ideas
 First
take an example of the problem
 Sketch it on the sheet of paper
 Next try to invent some idea that works for
your example
 Check if your
idea will work for other examples
 Try to find a case that breaks your idea
 Try challenging examples and unusual cases
 If you find your
idea incorrect, try to fix it or
just invent a new idea
12
Invent and Try Ideas – Example
 Consider the "Binary
Representation" problem
 Idea #1: divide by 2 and check the remainder
 How many times to do this?
 Where to check?
 Idea #2: Bitwise
shift and check the
left/rightmost bit
 Left shift or right shift?
 How many times to repeat this?
 Is this fast enough?
13
Check-up Your Ideas
Don't go Ahead before Checking Your Ideas
Check-up Your Ideas
 Check-up your
ideas with examples
 It is better to find a problem before the idea is
implemented
 When the code is written, changing radically
your ideas costs a lot of time and effort
 Carefully select examples for check-up
 Examples should be simple enough to be
checked by hand in a minute
 Examples should be complex enough to cover
the most general case, not just an isolated case
15
Invent New Idea If Needed
 What to do when you find your idea is not
working in all cases?
 Try to fix your idea
 Sometime a small change could fix the problem
 Invent new idea and carefully check it
 Iterate
 It is usual that your first idea is not the best
 Invent ideas, check them, try various cases, find
problems, fix them, invent better idea, etc.
16
Efficiency and Performance
Is Your Algorithm Fast Enough?
Think About the Efficiency
 Think about efficiency before writing
the first
line of code
 Estimate the expected running time
(e.g. using asymptotic complexity)
 Check the requirements
 Will your algorithm be fast enough to conform
with them
 You don't want to implement your algorithm
and find that it is slow when testing
 You will lose your time
18
Efficiency is not Always Required
 Best solution
is sometimes just not needed
 Read carefully your problem statement
 Sometimes ugly solution could work for your
requirements and it will cost you less time
 Example: if you need to sort n numbers, any
algorithm will work when n ∈ [0..500]
 Implement complex algorithms
only when the
problem really needs them!
19
Implementation
Coding and Testing Step-by-Step
Start Coding: Check List
 Never start
coding before you find correct idea
that will meet the requirements
 What you will write before you invent a correct
idea to solve the problem?
 Checklist to follow before start
of coding:
 Ensure you understand well the requirements
 Ensure you have invented a good idea
 Ensure your idea is correct
 Ensure you know what data structures to use
 Ensure the performance will be sufficient
21
Coding Check List – Example
 Checklist before start of coding:
 Ensure you understand well the requirements
 Yes, counts values of bits
 Ensure you have invented a correct idea
 Yes, the idea seems correct and is tested
 Ensure the performance will be sufficient
 Linear running time  good performance
22
Implement your
Algorithm Step-by-Step
 "Step-by-step" approach is always
better than
"build all, then test"
 Implement a piece of your program and test it
 Then implement another piece of the program
and test it
 Finally put together all pieces and test it
 Small increments (steps) reveal errors
early
 "Big-boom" integration takes more time
23
Step #1 – Check The Value
Of The First Bit
 Now we have the value of the first bit
int number=10;
int firstBit = number & 1;
 What happens to the number?
 Do we need the first bit anymore?
 Remove it by right shift
int number=10;
int firstBit = number & 1;
number >>= 1;
24
Step #1 – Test
 Testing if the correct bit is
extracted and
checked
 Get feedback as early as possible:
int number = 10;
int firstBit = number & 1;
number >>= 1;
Console.WriteLine(firstBit);
Console.WriteLine(number);
 The result is
0
5
as expected:
// the first bit
// the number without the first bit
25
Step #2 – Get All The Bits
Of a Number
 How many bits we want to check?
 All for the number
 But how many are they
 Example: the number 10
 10(10) = 8 + 2 = 1010(2) – 4 bits
 How the find out when to stop the checking?
 When right shifting the zeros in the front get
more and more
 At some point the number will become zero
26
Step #2 – Get All The Bits
Of a Number
 Until the number becomes equal to 0
1. Check the value of the bit
2. Right shift the number
while (number != 0)
{
int firstBit = number & 1;
number >>= 1;
Console.Write("{0} ", firstBit);
}
27
Step #2 – Test
 Testing with 10
0 1 0 1
 Testing with 1111
1 1 1 0 1 0 1 0 0 0 1
1111 = 1024 + 64 + 16 + 4 + 2 + 1 = 210 + 26 + 24 + 22 + 21 + 20
 Seems correct
28
 So far:
Step #3 – Check For The
Occurrences Of Bit Value
 We can get the values of all the bits of a number
 Lets count the number of ones and zeros
while (number != 0)
{
int firstBit = number & 1;
number >>= 1;
if (firstBit == 1)
{
oneCount++;
}
else
{
zeroCount++;
}
}
29
Step #3 – Test
 Test with number 111
(1101111(2))
ones:6 zeros:1
 The result is correct
 Test with number 1234
(10011010010(2))
ones:5 zeros:6
 The result is correct
30
Step #4 – Count The Bits Of
The Whole Set
 Pass
through all the numbers
 Count their bits
int zeroCount = 0, oneCount = 0, n = 5;
for (int i = 0; i < n; i++)
{
int number = int.Parse(Console.ReadLine());
while (number != 0)
{
int firstBit = number & 1;
number >>= 1;
if (firstBit == 1) { oneCount++; }
else { zeroCount++; }
}
Console.WriteLine("ones:{0};zeros:{1}",
oneCount,zeroCount);
}
31
Step #4 – Count The Bits Of
The Whole Set (2)
 The result is
surprisingly incorrect:
Input:
1
2
3
4
5
Output:
ones:1;
ones:2;
ones:4;
ones:5;
ones:7;
 The result is surprisingly
zeros:0
zeros:1
zeros:1
zeros:3
zeros:4
incorrect:
 The count of ones and zeros appears as to stack
for all the numbers of the set!
 We defined the counters outside the iteration of
the set loop
 Put them inside
32
Step #4 – Fixing the Bug
int n = 5;
for (int i = 0; i < n; i++)
{
int zeroCount = 0, oneCount = 0;
int number = int.Parse(Console.ReadLine());
while (number != 0)
{
int firstBit = number & 1;
number >>= 1;
if (firstBit == 1) { oneCount++; }
else { zeroCount++; }
}
Console.WriteLine("ones:{0}; zeros:{1}",
oneCount,zeroCount);
}
 Now it is OK
33
Testing
Thoroughly Test Your Solution
Thoroughly Test your Solution
 Wise software engineers say that:
 Inventing a good idea and implementing it is
half of the solution
 Testing is the second half of the solution
 Always
test thoroughly your solution
 Invest in testing
 One 100% solved problem is better than 2 or 3
partially solved
 Testing existing problem takes less time than
solving another problem from scratch
35
How to Test?
 Testing could not certify absence of defects
 It just reduces the defects rate
 Well tested solutions are more likely to be
correct
 Start testing with a good representative of the
general case
 Not a small isolated case
 Large and complex test, but
 Small enough to be easily checkable
36
How to Test? (2)
 Test the border cases
 E.g. if n ∈ [0..500]  try n=0 , n=1, n=2, n=499,
n=500
 If a bug is found, repeat all tests after fixing
it
to avoid regressions
 Run a load
test
 How to be sure that your algorithm is fast
enough to meet the requirements?
 Use copy-pasting to generate large test data
37
Read the Problem Statement
 Read carefully the problem statement
 Does your solution print exactly what is
expected?
 Does your output follow the requested format?
 Did you remove your debug printouts?
 Be sure to solve the requested problem, not
the problem you think is requested!
 Example: "Write a program to print the number
of permutations on n elements" means to print
a single number, not a set of permutations!
38
Testing – Example

Test with a set of 10 numbers
 Serious error found  change the algorithm

Change the algorithm
 The counters never reset to zero
 Test whether the new algorithm works

Test with 1 number

Test with 2 numbers

Test with 0 numbers

Load test with 52 000 numbers
39
Test With 10000 Numbers –
Example
int n = 10000, startNumber=111;
for (int i = startNumber; i < startNumber + n; i++)
{
int zeroCount = 0;
int oneCount = 0;
//int number = int.Parse(Console.ReadLine());
int number = i;
Replace the reading from the
int originalNumber = number;
console with a easier type of check
while (number != 0)
{
int firstBit = number & 1;
number >>= 1;
if (firstBit == 1){ oneCount++; }
else { zeroCount++; }
}
}
40
Test With 10000 Numbers –
Example (2)

The result is perfect:
111(10) = 1101111(2) -> ones:6;zeros:1
…
10110(10) = 10011101111110(2) -> ones:10;zeros:4
41
Testing Tips
 You are given the task of the binary
representation
 The program must read from the console
 Integer numbers N and B
 N integer numbers
 While writing
and testing the program
 Don't read from the console
 First hardcode the numbers
 Later make it
 When you are sure it works
42
Hard-Coded Input – Example
// Hardcoded input data – for testing purposes
int n = 5;
int num1 = 11;
int num2 = 127;
int num3 = 0;
int num4 = 255;
int num5 = 24;
// Read the input from the console
//int n = int.Parse(Console.ReadLine());
//for (int i=0; i<n; i++)
//{
// int num = int.Parse(Console.ReadLine());
// // Process the number …
// // …
//}
// Now count the bits for these n numbers …
43
Summary
Problems solving needs methodology:
 Understanding and analyzing problems
 Using a sheet of paper and a pen for sketching
 Thinking up, inventing and trying ideas
 Decomposing problems into subproblems
 Selecting appropriate data structures
 Thinking about the efficiency and performance
 Implementing step-by-step
 Testing the nominal case, border cases and
efficiency
44
Methodology of
Problem Solving
Questions?
http://academy.telerik.com