1.71 Operations Manual
Your reference for using formal algorithm design techniques that transform a problem brief into a testable algorithm, supporting accurate and efficient implementation.
Designing an algorithm begins with understanding what the program is supposed to do. From this understanding, we use structured design techniques to break the problem into manageable parts and write testable and adaptable logic.
Top-down design
Top-down design starts with the whole problem and breaks it into smaller subproblems. For example, let's decompose a problem where an application processese login credentials.
Brief
Authenticate a user
Top-down approach
BEGIN
GET username and password
IF validate_user(username, password) THEN
DISPLAY "Access granted"
ELSE
DISPLAY "Access denied"
ENDIF
END
Each function like validate_user
would then be broken down into even smaller parts — checking if the user exists, checking password rules, etc.
This method promotes clear structure, simplifies debugging, and supports reuse.
Bottom-up design
In contrast, bottom-up design focuses on developing simple, reusable modules first, then combining them into a complete system. For instance:
Start by creating
check_length(password)
Then create
check_digit(password)
Then create
check_uppercase(password)
Finally build
validate_password(password)
using those modules
This is common in Agile workflows or when libraries of trusted functions already exist.
Structure charts
Structure charts are used to plan the relationships between subroutines.
Main
├── validate_user
│ ├── user_exists
│ └── check_password_rules
│ ├── check_length
│ ├── check_digit
│ └── check_uppercase
Each subroutine does one task, called by the one above it. This helps with test planning and version control.
Refinement
Refinement is the process of expanding each part of your design with more detail as needed. Start simple, then get specific. For example:
Step: Check if password is valid
Refined:
- Must be 8+ characters
- Must include at least one digit
- Must include at least one uppercase letter
This layered approach keeps the mainline logic readable.
Divide and conquer
Some algorithms work best by splitting the problem into smaller versions of themselves. One of the most common examples is binary search:
FUNCTION binary_search(list, target)
SET low = 0
SET high = length(list) - 1
WHILE low <= high
SET mid = (low + high) // 2
IF list[mid] == target THEN
RETURN mid
ELSE IF list[mid] < target THEN
SET low = mid + 1
ELSE
SET high = mid - 1
RETURN -1
END FUNCTION
Each loop reduces the search area by half. This is faster than checking each item.
Backtracking
Backtracking is useful when trying all possible options and abandoning those that fail early. For example, generating a 4-digit PIN code that meets some criteria:
FUNCTION generate_pin(current_pin)
IF length(current_pin) == 4 THEN
IF pin_is_valid(current_pin) THEN
STORE current_pin
RETURN
FOR digit FROM 0 TO 9
CALL generate_pin(current_pin + digit)
This approach explores all possible combinations but doesn't keep going once an invalid path is found.
To simplify the process, consider an example of a two-digit PIN.
Brief
We want to generate all valid 2-digit PINs made from digits 0–9 where:
The first digit is even
The second digit is odd
BEGIN generate_pin(current_pin)
IF LENGTH(current_pin) == 2 THEN
IF is_valid(current_pin) THEN
STORE current_pin
ENDIF
RETURN
ENDIF
FOR digit FROM 0 TO 9
CALL generate_pin(current_pin + digit)
NEXT digit
END generate_pin(current_pin)
BEGIN is_valid(pin)
RETURN (pin[0] MOD 2 == 0) AND (pin[1] MOD 2 == 1)
END is_valid(pin)
BEGIN
CALL generate_pin("")
END
Desk checking and trace tables
Before coding, you can use a desk check or trace table to manually simulate how your algorithm runs. For instance:
Algorithm:
x = 2
y = 3
z = x + y
Trace table:
1
2
2
2
3
3
2
3
5
This helps catch logic errors before you write code.
Linking to software development models
In Waterfall, you complete the algorithm design before coding. In Agile, you may design and refine small sections in iterations. Regardless of the model, a clear algorithm design supports easier testing, revision, and collaboration.
Key concepts
Top-down design: Start with the big picture, then break it into subroutines
Bottom-up design: Build individual modules first, then integrate
Structure charts: Diagrams showing subroutine relationships
Refinement: Expand steps from general to specific
Divide and conquer: Solve a problem by breaking it into smaller parts
Backtracking: Explore all options, abandon invalid ones early
Desk checking: Walk through your logic with sample inputs
Last updated
Was this helpful?