Algorithm Design & Problem Solving 🧩
Break problems down, design solutions with flowcharts and pseudocode, test them properly — and run real Cambridge-style pseudocode right here, with the trace table filled in for you.
🎯 What you'll unlock this chapter
- 🔁 The program development life cycle, abstraction and decomposition
- 🌳 Structure diagrams, flowcharts and pseudocode
- 🧮 Standard methods: totalling, counting, max/min/average, linear search, bubble sort
- ✅ Validation, verification and choosing test data
- 🔍 Trace tables, dry runs, and finding and fixing errors
- 💻 A live pseudocode interpreter — plus all 20 coursebook activities and every worked example
🔁 The program development life cycle 7.1
| Stage | What happens |
|---|---|
| Analysis | The problem is clearly defined — the requirements specification. Uses abstraction (keep the key elements, discard unnecessary detail — like a rail map that only shows stations and lines) and decomposition (break a complex problem into smaller parts). |
| Design | Shows how the program will be developed: every task, how it's done and how the tasks work together — using structure diagrams, flowcharts and pseudocode. |
| Coding (and iterative testing) | Each module is written in a programming language and tested; iterative testing means test → amend → re-test until each module works. |
| Testing | The completed program is run many times with different sets of test data to make sure all the parts work together as specified. |
(The fifth stage, maintenance, happens after the program is in use.)
🧱 Systems, sub-systems and decomposition 7.2
A computer system is made of software, data, hardware, communications and people, and can be divided into sub-systems, then those into smaller ones, until each just performs a single action — top-down design; the process of breaking down is stepwise refinement. Several programmers can then build and test different sub-systems at the same time. Every problem can be decomposed into:
| Inputs | Processes | Outputs | Storage |
|---|---|---|---|
| Data entered while the system is active | Tasks performed using the inputs and stored data | Information displayed or printed for users | Data stored in files for future use |
| Alarm app: set an alarm time, remove one, switch off, snooze | Keep checking whether the time matches an alarm; store/remove alarms; manage snooze | A continuous sound at the alarm time | The alarm times set |
🌳 Structure diagrams 7.2.3
A structure diagram shows top-down design as a hierarchy: each level gives a more detailed breakdown.
🔷 Flowcharts 7.2.3
A flowchart shows the steps of a task and their order — an algorithm — using standard symbols joined by flow lines (arrows, usually top to bottom, left to right).
A process box can also just name a process defined elsewhere (e.g. "Sort list"). Both arrows leaving a decision must be labelled yes/no.
📝 Writing pseudocode 7.2.3
Pseudocode describes an algorithm with English keywords similar to a programming language, but without strict syntax rules. The Cambridge style: a monospaced font; KEYWORDS in capitals; names of variables and subroutines start with a Capital letter; statements inside conditions and loops indented by two spaces.
Assignment uses ←
Cost ← 10 // Cost is 10 Price ← Cost * 2 // 20 Tax ← Price * 0.12 // 2.4 SellingPrice ← Price + Tax // 22.4 Gender ← "M" Chosen ← FALSE
Operators: + − * / ^ ( ) — and DIV (whole-number division) and MOD (remainder).
Comparison and logic
> < = >= <= <> (not equal), and AND OR NOT.
IF ((Height > 1) OR (Weight > 20)) AND (Age < 70) AND (Age > 5)
THEN
OUTPUT "You can ride"
ELSE
OUTPUT "Too small, too young or too old"
ENDIF 🔀 Selection: IF and CASE 7.2.3
IF … THEN … ELSE … ENDIF
THEN runs if the condition is true; ELSE (optional) if it's false. An IF inside another IF's path is a nested IF:
OUTPUT "Please enter a mark "
INPUT PercentageMark
IF PercentageMark < 0 OR PercentageMark > 100
THEN
OUTPUT "Invalid Mark"
ELSE
IF PercentageMark > 49
THEN
OUTPUT "Pass"
ELSE
OUTPUT "Fail"
ENDIF
ENDIF CASE OF … OTHERWISE … ENDCASE
The value of a variable picks the path; OTHERWISE catches every other value:
CASE OF Choice 1 : Answer ← Num1 + Num2 2 : Answer ← Num1 - Num2 3 : Answer ← Num1 * Num2 4 : Answer ← Num1 / Num2 OTHERWISE OUTPUT "Please enter a valid choice" ENDCASE
🔁 Iteration: three kinds of loop 7.2.3
| FOR … TO … NEXT | REPEAT … UNTIL | WHILE … DO … ENDWHILE |
|---|---|---|
| A set number of repetitions; the counter is managed automatically | Number of repeats unknown; always runs at least once — a post-condition loop | Number of repeats unknown; may never run — a pre-condition loop |
FOR Counter ← 1 TO 10 OUTPUT "*" NEXT Counter | Counter ← 0 REPEAT OUTPUT "*" Counter ← Counter + 1 UNTIL Counter > 9 | Counter ← 0 WHILE Counter < 10 DO OUTPUT "*" Counter ← Counter + 1 ENDWHILE |
INPUT stores entered data in a variable; OUTPUT displays a value or a list separated by commas, e.g. OUTPUT "Your name is ", Name. (READ and PRINT are sometimes used for files and printed output.)
💻 Pseudocode runner — with an automatic trace table
Pick an algorithm or write your own, type the test data, and press Run — or Step one line at a time. Use ← or <-.
Trace table
Output
🎯 Explaining the purpose of an algorithm 7.3
To explain an algorithm, state its purpose (what it achieves) and the processes it uses. E.g. this outputs an alarm at the right time — the processes are waiting 10 seconds, getting the current time, comparing it with the alarm time, and outputting the sound when they match:
REPEAT Wait(10) Get(Time) UNTIL Time = AlarmTime OUTPUT AlarmSound
🧮 Totalling, counting, max, min and average 7.4.1–7.4.3
Totalling
Total ← 0 FOR Counter ← 1 TO ClassSize Total ← Total + StudentMark[Counter] NEXT Counter
Counting
PassCount ← 0
FOR Counter ← 1 TO ClassSize
INPUT StudentMark
IF StudentMark > 50
THEN
PassCount ← PassCount + 1
ENDIF
NEXT Counter Counting down works too, e.g. NumberInStock ← NumberInStock - 1, re-ordering when it drops below 20.
Maximum and minimum
MaximumMark ← StudentMark[1]
MinimumMark ← StudentMark[1]
FOR Counter ← 2 TO ClassSize
IF StudentMark[Counter] > MaximumMark
THEN
MaximumMark ← StudentMark[Counter]
ENDIF
IF StudentMark[Counter] < MinimumMark
THEN
MinimumMark ← StudentMark[Counter]
ENDIF
NEXT Counter Setting max and min to the first item works for any list. (If the range is known, you can start max at the lowest possible value — 0 — and min at the highest — 100.)
Average
Total first, then Average ← Total / ClassSize after the loop.
🔎 Linear search 7.4.4
A linear search inspects each item in turn to see if it matches. A Boolean flag (Found) stops the search when there's a match or the whole list has been checked:
OUTPUT "Please enter name to find "
INPUT Name
Found ← FALSE
Counter ← 1
REPEAT
IF Name = StudentName[Counter]
THEN
Found ← TRUE
ELSE
Counter ← Counter + 1
ENDIF
UNTIL Found OR Counter > ClassSize
IF Found
THEN
OUTPUT Name, " found at position ", Counter, " in the list."
ELSE
OUTPUT Name, " not found."
ENDIF To count how many items match (e.g. how many chose "ice cream"), check every item with a FOR loop and a counter instead.
🎮 Linear search
🫧 Bubble sort 7.4.5
Each element is compared with the next and swapped if they're in the wrong order, from the first element to the next-to-last. After one pass the last element is in place, so the next pass can stop one sooner. It stops when a pass makes no swaps (or only one element is left).
First ← 1
Last ← 10
REPEAT
Swap ← FALSE
FOR Index ← First TO Last - 1
IF Temperature[Index] > Temperature[Index + 1]
THEN
Temp ← Temperature[Index]
Temperature[Index] ← Temperature[Index + 1]
Temperature[Index + 1] ← Temp
Swap ← TRUE
ENDIF
NEXT Index
Last ← Last - 1
UNTIL (NOT Swap) OR Last = 1 🎮 Bubble sort, step by step
✅ Validation 7.5.1
Validation is the automated checking by a program that data is reasonable before it is accepted. If it's rejected, a message explains why and the user gets another chance. One input can have several checks.
| Check | What it checks | Example |
|---|---|---|
| Range | A number is between a lower and an upper value | A mark from 0 to 100 |
| Length | An exact number of characters, or a sensible number | A password of exactly 8; a family name of 2–30 |
| Type | The data is the right data type | Number of brothers is a whole number (X = DIV(X, 1)) |
| Presence | Something has been entered — not left blank | An email address for an online order |
| Format | Characters follow a pre-defined pattern | A part number like XXX999 |
| Check digit | The final digit, calculated from the others, still matches | ISBNs and barcodes — catches wrong digits, transpositions, missing/extra digits |
OUTPUT "Please enter the student's mark "
REPEAT
INPUT StudentMark
IF StudentMark < 0 OR StudentMark > 100
THEN
OUTPUT "The mark should be in the range 0 to 100, please re-enter"
ENDIF
UNTIL StudentMark >= 0 AND StudentMark <= 100 🎮 Validation checker
Try entering good and bad data. Each field shows which check accepts or rejects it.
🔁 Verification 7.5.2
Verification checks that data has been accurately copied from one source to another. For input: double entry (typed twice — maybe by different people — and compared; if they differ, it must be re-entered) and a screen/visual check (the user checks the data shown on screen against the original and confirms). Validation can't tell if a valid value is the wrong one — verification can.
🎮 Double entry
🧪 Test data 7.6
A set of test data is all the data needed to work through a solution, with the expected results. For percentage marks (whole numbers 0–100):
| Type | Meaning | Example | Expected |
|---|---|---|---|
| Normal | Data the program should accept | 50, 75, 23 | Accepted |
| Abnormal (erroneous) | Data that should be rejected | −12, eleven, 150 | Rejected |
| Extreme | The largest and smallest values that are accepted | 0, 100 | Accepted |
| Boundary | The largest/smallest accepted value and the value just beyond it, which is rejected | 100 and 101; 0 and −1 | Accepted / rejected |
🔍 Trace tables and dry runs 7.7
A dry run is working through an algorithm by hand, step by step. A trace table records it: a column for each variable and one for OUTPUT. Every time a variable changes, write its new value in its column; every time something is output, write it in the OUTPUT column (without quotation marks). Questions often use single-letter variables and ask what the algorithm is for.
🎮 Flowchart tracer
Step through the flowchart and watch the trace table fill up. Try the three versions — and some negative numbers.
🐞 Identifying errors 7.8
Trace tables and test data reveal errors. Version 1 of the flowchart starts B ← 0 and C ← 100, so it only works for numbers between 0 and 100: with 400, 800, 190… the smallest value is never found (C stays 100), and with negative numbers the largest is wrong. Version 2 widens the starting values but still fails for numbers beyond ±1 000 000. The proper fix is version 3: set B and C to the first value input, then loop for the remaining nine.
✍️ Writing and amending algorithms 7.9
- Make sure the problem is clearly specified — the purpose and the tasks.
- Break it into sub-problems: set-up, input, processing, storage (if needed), output.
- Decide how data is obtained and stored, what happens to it, and how results are output.
- Design the structure (a structure chart), then each part as a flowchart or pseudocode.
- Choose test data and dry run it with a trace table.
For a big problem — like 600 students' marks in 4 tests — dry run a reduced version (e.g. 5 students, 2 subjects) with test data whose results you can work out by hand.
✏️ Practice hub 20 activities · every example
Every activity from the coursebook chapter — auto-marked where there's a single right answer (many checked by the pseudocode interpreter itself), with model pseudocode for the writing tasks. Fresh questions every time you hit 🔀 New questions.
📘 Worked examples
Every type of worked example in the chapter, step by step. Hit 🔀 Another example for a new one.
🃏 Key-term flashcards Tap to flip
🧠 Mini-quiz
📝 Exam-style questions Try, then peek
- ✅ Inputs — data entered while the system is active.
- ✅ Processes — tasks performed on the input and stored data.
- ✅ Outputs — information displayed or printed for users.
- ✅ Storage — data stored in files for future use.
- ✅ Presence check and type check on both; range check 1–12 for diners (whole number) and 10–500 for the bill.
- ✅ Normal: 4, 7 → accepted. Abnormal: 20, "four", −3 → rejected.
- ✅ Extreme: 1 and 12 → accepted. Boundary: 0 and 13 → rejected (with 1 and 12 accepted).
- ✅ Validation is an automatic check by the program that data is reasonable/sensible before it’s accepted.
- ✅ Verification checks data has been copied/entered accurately from its source (double entry, visual check).
Count ← 0
FOR Counter ← 1 TO 10
INPUT Number
IF Number > 50
THEN
Count ← Count + 1
ENDIF
NEXT Counter
OUTPUT "Numbers over 50: ", Count- ✅ The user must enter a value at least once, and a REPEAT loop always runs at least once.
- ✅ It keeps asking UNTIL valid data is entered (the condition is tested at the end).
- ✅ Each item is compared with the next item.
- ✅ If they’re in the wrong order, they’re swapped (using a temporary variable).
- ✅ This repeats through the list (a pass); after each pass the largest unsorted item is in place, so the next pass is one shorter.
- ✅ Passes repeat until a pass makes no swaps.
🚀 Going further A Level preview
An abstract data type (ADT) is a collection of data plus the operations on it. A stack is last in, first out (LIFO): push adds to the top, pop removes from the top; the base pointer never moves. A queue is first in, first out (FIFO): enqueue adds at the end, dequeue removes from the front; both the front and end pointers move.