1.1 What Is the 15-Mark Scenario Question?
The very last question on Paper 2 is always 15 marks and is called the scenario question. You are given a real-world situation — a sports league, a school system, a booking service — and you have to write a complete program to solve it.
- You are allowed to write your answer in pseudocode, Python, Visual Basic, or Java. The question will always say this.
- Logic matters more than perfect syntax — minor errors will not cost you marks.
- Cambridge expects you to spend about 30 minutes on this question.
- That is not much time to write a full program, so having a clear plan before you start writing is essential.
Before you write a single line of code: Read the whole scenario carefully. Identify every named array and variable. Draw out what the array looks like on paper — rows, columns, what is stored where. Only then start writing. Students who jump straight to coding almost always miss tasks and lose marks they should have kept.
What a 15/15 answer looks like: It addresses every bullet point in the task list. It uses the exact array names from the question. Every section has a comment. All variable names are descriptive. Validation uses a re-entry loop. The winner is found with two loops, handling ties. Calculated values are stored in the correct array or column. The output is in a logical order with suitable messages throughout.
1.2 Step 1 — Read the Arrays: Rows & Columns
The scenario will always introduce one or more named arrays. Your first job is to work out exactly what is stored in each array — how many rows, how many columns, and what each position means.
One-dimensional (1D) arrays
A 1D array is a single list. It has one index. Think of it as one column of a spreadsheet.
// A 1D array storing the names of 8 clubs
ClubName[1] <- "Riverside"
ClubName[2] <- "Hillside"
ClubName[3] <- "Lakeside"
// ... up to ClubName[8]ClubName[] — 1D array, 8 elements, one per row (index 1 to 8).
Two-dimensional (2D) arrays
A 2D array has two indexes: Array[row, column]. Think of it as a table. The first index picks the row (usually a person or team or item). The second index picks the column (usually a measurement, a score, or a category). The scenario question always tells you exactly what each column stores — read it carefully.
// Example: "The 2D array ClubScore[] stores the points for each
// club in each of the three events. The first dimension is the
// club index. The second dimension is the event."
//
// ClubScore[club, event] -- 8 rows (clubs) x 3 columns (events)| Index | Event 1 (col 1) | Event 2 (col 2) | Event 3 (col 3) |
|---|---|---|---|
| 1 | 8 | 5 | 3 |
| 2 | 3 | 8 | 5 |
| 3 | 5 | 3 | 8 |
| 4 | 2 | 2 | 2 |
| 5 | 1 | 1 | 1 |
Key rule — identify rows and columns first: Before writing any code, answer these two questions for every 2D array in the question. Rows: what does each row represent? (Usually: one team, one student, one customer.) Columns: what does each column store? (Usually: scores, results, measurements, or calculated values.)
How to find the loop bounds from the question
The scenario always tells you the size of the array through a named variable or a fixed number. This becomes the upper bound of your loop.
| What the question says | What it means for your loop |
|---|---|
| "8 clubs" | FOR Club <- 1 TO 8 |
| "The variable TeamCount stores the number of teams" | FOR Team <- 1 TO TeamCount |
| "ClassSize stores the number of students" | FOR Student <- 1 TO ClassSize |
| "three events" (second dimension) | FOR Event <- 1 TO 3 (inner loop) |
| "seven days" (second dimension) | FOR Day <- 1 TO 7 (inner loop) |
Named variables are your loop bounds: Cambridge almost always introduces a variable like TeamCount, MatchNo, or ClassSize in the scenario. These are not random — they are the upper bounds of your loops. Use them by name, exactly as written in the question. The mark scheme checks for them.
1.3 Step 2 — Understand Parallel Arrays
Almost every 15-mark question uses parallel arrays. This is where two or more arrays are linked together by sharing the same index number.
The question will always spell this out with a sentence like:
The sentence Cambridge always includes: “The position of any team’s data is the same in both arrays. For example, the data in index 3 of Results[] belongs to the team in index 3 of TeamName[].”
This means: index 1 of TeamName[] is the same team as index 1 of Results[]. Index 5 of TeamName[] is the same team as index 5 of Results[]. The index ties them together.
Parallel arrays — same index = same team
| Index | TeamName[] (1D) | Results[,1] Won | Results[,2] Drawn | Results[,3] Lost | TotalPoints[] (calc) |
|---|---|---|---|---|---|
| 1 | "Riverside" | 12 | 3 | 3 | 39 |
| 2 | "Hillside" | 10 | 5 | 3 | 35 |
| 3 | "Lakeside" | 8 | 4 | 6 | 28 |
| 4 | "Oakfield" | 6 | 6 | 6 | 24 |
Green column = separate 1D array TotalPoints[] — same index links it back to TeamName[].
When you want to find out which team has the most points, you search TotalPoints[]. When you find the index, you use that same index in TeamName[] to get the team’s name. The index is the bridge between the arrays.
// Find the highest total -- use the index to link back to the name
FOR Team <- 1 TO TeamCount
IF TotalPoints[Team] > HighScore THEN
HighScore <- TotalPoints[Team]
HighName <- TeamName[Team] // same index -> same team
ENDIF
NEXT TeamThree or more parallel arrays: Some questions use three parallel arrays — for example StudentName[], StepCount[,], and WeeklyTotal[]. The question will say “the position of any student’s data is the same in all three arrays.” The rule is the same — the index ties all three together.
1.4 Step 3 — Build the Nested Loop
Once you know the rows and columns, you know exactly how to structure your loops. The rule is simple:
The nested loop rule: The outer loop goes through the rows — one iteration per person, team, or item. The inner loop goes through the columns — one iteration per measurement, event, or day. So if you have 8 clubs (rows) and 3 events (columns): outer loop 1 to 8, inner loop 1 to 3.
// Outer loop = rows (clubs)
FOR Club <- 1 TO 8
Total <- 0
// Inner loop = columns (events)
FOR Event <- 1 TO 3
Total <- Total + ClubScore[Club, Event]
NEXT Event
TotalPoints[Club] <- Total
NEXT ClubWhat goes in the outer loop vs the inner loop
| Outer loop (one per row) | Inner loop (one per column) |
|---|---|
| Reset counters to zero (e.g. Total <- 0, Wins <- 0) | Read or write one cell: Array[row, col] |
| Input the row-level data (e.g. team name) | Input or process column-level data (e.g. one score, one day) |
| Store the finished total for this row | Add to a running total |
| Output the summary for this row | Count a category (e.g. count wins, count days over limit) |
| Update the maximum or minimum (after inner loop finishes) | Apply validation to one cell's input |
Most common mistake — resetting in the wrong place: If you reset a counter (like Wins <- 0) inside the inner loop, it resets every time you process a column. It must be reset inside the outer loop but before the inner loop starts — once per row, not once per cell.
Correct — reset before the inner loop (once per team)
FOR Team <- 1 TO TeamCount
Wins <- 0 // reset here -- once per team, BEFORE the inner loop
FOR Match <- 1 TO MatchNo
IF MatchResult[Team, Match] = 3 THEN
Wins <- Wins + 1
ENDIF
NEXT Match
OUTPUT TeamName[Team] & " wins: " & Wins
NEXT TeamExam tip: A quick mental check: any per-row counter (Total, Wins, MaxForThisTeam) is initialised inside the outer loop before the inner loop starts. Any per-cell action (read one cell, add to total, validate one input) is inside the inner loop.
Arrays, Loop Bounds & Nested Loops
1.5 Step 4 — Where Does the Data Come From?
Before you write your input loop, check whether the question tells you to input data or whether the data has already been stored. This changes your program significantly.
Data is input by the user
- The question says “allows the scores to be input” or “inputs and validates…”
- You write an
INPUTstatement and a validation loop inside the nested loops - Your nested loop inputs AND processes data in the same pass
Data is already stored
- The question says “The arrays and variables have already been set up and the data stored.”
- You do NOT write any INPUT statements. Start directly with processing
- Your nested loop only reads and processes what is already in the array
When data is already stored — start processing immediately: If the question says the data has already been stored, do not write any INPUT statements for the main array data. Jump straight to the processing loops. Your program will be shorter — but the processing tasks (totalling, counting, finding winners) are just as important.
Validating input data
When you do need to input data, Cambridge always expects a re-entry loop — not just an error message. If the input is invalid, the program must ask again. This requires a REPEAT...UNTIL structure.
// Validation -- must use a re-entry loop, not just an IF
REPEAT
OUTPUT "Enter score for " & CompetitorName[X] & " in event " & Event & " (0-100):"
INPUT Score
IF Score < 0 OR Score > 100 THEN
OUTPUT "Invalid. Please enter a value between 0 and 100."
ENDIF
UNTIL Score >= 0 AND Score <= 100This is NOT enough — it will cost you marks
IF Score < 0 OR Score > 100 THEN OUTPUT "Invalid" ENDIFThis only shows an error message. It does not make the user re-enter the value. Cambridge requires a loop. Without the re-entry loop you cannot reach the top AO2 band.
1.6 Step 5 — Where Do Calculated Values Go?
After you process the data in the inner loop, you usually need to store a result. Cambridge uses two approaches for this, and you need to recognise which one the question is asking for.
Approach A — A separate 1D array stores one calculated value per row
This is the most common approach. A separate 1D array is introduced in the scenario specifically to hold the result of a calculation — one value per team, student, or item. Examples from past papers: TotalPoints[], WeeklyTotal[], Points[], AverageTemp[].
| Index | TotalPoints[] |
|---|---|
| 1 | 39 |
| 2 | 35 |
| 3 | 28 |
| 4 | 24 |
// Store the calculated total in the separate 1D array
FOR Club <- 1 TO 8
TotalPoints[Club] <- 0
FOR Event <- 1 TO 3
TotalPoints[Club] <- TotalPoints[Club] + ClubScore[Club, Event]
NEXT Event
NEXT ClubApproach B — An empty column in the 2D array stores the calculated value
Sometimes the 2D array itself has an extra column left empty on purpose. The question will list the columns and one of them will be a calculated value — for example, “column 4 — total hire cost”.
| Index | Col 1 Days | Col 2 Vehicle | Col 3 Insurance | Col 4 Total cost |
|---|---|---|---|---|
| 1 | 5 | 2 | 1 | 300.00 |
| 2 | 3 | 4 | 3 | 420.00 |
| 3 | "" | "" | "" | "" |
Green cells = calculated and stored by the program. Other cells in row 3 = not yet filled.
// Calculate and store in column 4 of the 2D array
TotalCost <- (DailyRate[VCat] + InsuranceCost[Ins]) * Days
HireDetails[Store, 4] <- TotalCostHow to tell which approach the question is using: If the question introduces a named 1D array alongside the 2D array (e.g. TotalPoints[], WeeklyTotal[]) — use Approach A. Store your result there. If the question lists columns of the 2D array and one of them is described as a calculated value (e.g. “column 4 — total cost”) — use Approach B. Store your result in that column.
Validation & Calculated Values
1.7 Step 6 — The Six Patterns Cambridge Always Uses
After analysing over 20 past paper questions, the same six pseudocode patterns appear again and again. Learn these by heart. If you can write each one from memory, you will handle almost any version of this question.
Pattern 1 — Validation with re-entry loop
Use this whenever the question says “validates” or “checks that the input is valid”.
REPEAT
OUTPUT "Enter a value:"
INPUT Value
IF Value < Min OR Value > Max THEN
OUTPUT "Invalid. Please try again."
ENDIF
UNTIL Value >= Min AND Value <= MaxPattern 2 — Find maximum (then output all tied)
Always two separate loops. Never find and output in the same loop — you would miss ties.
// Loop 1: find the maximum value
HighScore <- 0
FOR i <- 1 TO Count
IF TotalPoints[i] > HighScore THEN
HighScore <- TotalPoints[i]
ENDIF
NEXT i
// Loop 2: output ALL teams with that maximum
FOR i <- 1 TO Count
IF TotalPoints[i] = HighScore THEN
OUTPUT TeamName[i] & " - " & HighScore & " points"
ENDIF
NEXT iPattern 3 — Find minimum
Same two-loop structure. Initialise to the first element, not to zero (zero would always win).
// Initialise to the first element's value
LowScore <- TotalPoints[1]
LowName <- TeamName[1]
FOR i <- 2 TO Count
IF TotalPoints[i] < LowScore THEN
LowScore <- TotalPoints[i]
LowName <- TeamName[i]
ENDIF
NEXT i
OUTPUT "Lowest: " & LowName & " - " & LowScore & " points"Pattern 4 — Find first available empty slot
Use this when you are adding a new record to a partially-filled array.
// Find the first empty position in the array
Store <- 1
REPEAT
IF CustomerName[Store] <> "" THEN
Store <- Store + 1
ENDIF
UNTIL CustomerName[Store] = ""
// Store now holds the index of the first free slot
CustomerName[Store] <- NewNamePattern 5 — Category counting with CASE OF
Use this when you need to count how many times each specific value appears.
// Count match result categories using CASE OF
CASE OF MatchResult[Team, Match]
3 : AwayWins <- AwayWins + 1
2 : HomeWins <- HomeWins + 1
1 : Draws <- Draws + 1
0 : Losses <- Losses + 1
ENDCASEPattern 6 — Initialise a named array at the start
Some questions tell you to initialise a specific array (e.g. DayName[]) at the start. Do this before any loops.
// Initialise DayName array before any processing
DayName[1] <- "Monday"
DayName[2] <- "Tuesday"
DayName[3] <- "Wednesday"
DayName[4] <- "Thursday"
DayName[5] <- "Friday"
DayName[6] <- "Saturday"
DayName[7] <- "Sunday"Exam tip: When you read the scenario, mentally tick off which of the six patterns each task needs. If a task says “validate”, that’s Pattern 1. “Find the winner” is Pattern 2. “Find the smallest” is Pattern 3. “Add a new customer” is Pattern 4. “Count how many of each result” is Pattern 5. “Initialise the day names” is Pattern 6.
The Six Cambridge Patterns
1.8 Step 7 — How Your Answer Is Marked + Final Checklist
The 15 marks are split into two completely separate grids. Understanding this is the most important thing you can do to improve your score.
| Grid | What it tests | Max marks |
|---|---|---|
| AO2 | Programming techniques used. Does your code address each requirement? Do you use the right data structures with the right names? | 9 |
| AO3 | Quality of your solution. Are there comments? Are identifiers meaningful? Is the logic correct and in a sensible order? | 6 |
The AO2 grid — techniques and data structures (0-9)
| Band | Marks | What this means |
|---|---|---|
| Top | 7-9 | All requirements addressed. Full range of techniques used appropriately. All named arrays used correctly. Data structures store all data required by the scenario. |
| Middle | 4-6 | Most requirements addressed. More than one technique used. More than one named data structure used. |
| Low | 1-3 | At least one technique used (any loop, any IF, any input/output). Some data stored, even if incorrectly. |
| Zero | 0 | No creditable response. |
The AO3 grid — quality (0-6)
| Band | Marks | What this means |
|---|---|---|
| Top | 5-6 | Fully commented throughout. All identifiers are meaningful. All data structures have meaningful names. Logical order. Accurate. Performs all tasks. |
| Middle | 3-4 | Some comments. Most identifiers appropriate. Mostly logical. Some inaccuracies. Attempts most requirements. |
| Low | 1-2 | Few or no comments. Some identifiers appropriate. Illogical. Inaccurate. Attempts at least one requirement. |
| Zero | 0 | No creditable response. |
The most important thing most students do not know
AO3 marks are awarded separately from logic. A student who writes perfectly correct code using variable names like x, y, a, and b with no comments will score 9/9 for AO2 but only 1-2 out of 6 for AO3. That is a total of 10-11 out of 15 instead of 15 out of 15 — lost entirely on presentation, not logic. Comments and meaningful names are free marks if you train yourself to write them every time.
Use the exact array names from the question: The mark scheme underlines the required data structure names. If the question says TotalPoints[] and you write Total[] or pts[], the examiner cannot confirm you are using the correct data structure. Use the names exactly as written in the question — copy them character for character.
Final checklist before you stop writing
Run through this list before you put your pen down. Each item is something students commonly forget.
I used the exact array and variable names from the question — I did not rename them.
Every major section has a comment explaining what it does.
All my variable names are meaningful — no single letters like x, y, or a (except conventional loop counters like i).
My validation uses a re-entry loop (REPEAT...UNTIL), not just an IF statement.
I reset counters (e.g. Total <- 0, Wins <- 0) inside the outer loop, before the inner loop.
My "find winner" code uses two loops — one to find the maximum, one to output all tied winners.
My "find minimum" code initialises the low value to the first element, not to zero.
If the question says data is already stored, I did not write INPUT statements for the main array.
If the question says to initialise a named array (e.g. DayName[]), I did it at the very start.
I used ROUND(value, 2) if the question says to round output.
All my OUTPUT statements have a suitable message — not just a number on its own.
I addressed every bullet point in the task list — I did not skip any.
Marking (AO2 / AO3) & Final Checklist
1.9 Practice Tasks
Four full Cambridge-style 15-mark scenario questions. For each, read the question, then click Show Hints for step-by-step guidance or Show Answer for the mark scheme and indicative pseudocode.
Question 9 — Random Number Generator
Scenario
A program is required to test the fairness of a random number generator.
The one-dimensional (1D) array RandomNumber[] is used to store 10,000 random integers.
The two-dimensional (2D) array CountedNumber[] is used to store each of the integers 1 to 6 inclusive, and the frequency of each integer — the number of times each integer was generated.
The first dimension of CountedNumber[] stores the integer value. The second dimension stores the frequency count for that integer.
Write a program that meets the following requirements:
- generate 10,000 random integers between 1 and 6 inclusive and store them in
RandomNumber[] - initialise
CountedNumber[]so that the first column stores the integers 1 to 6 and the second column stores a frequency count of zero for each - calculate the frequency of each of the integers 1 to 6 and store the frequency values in the second column of
CountedNumber[] - calculate the probability of generating each of the integers 1 to 6, rounded to four decimal places, using the formula: Probability = frequency / 10,000
- output each of the integers 1 to 6, along with its frequency and probability.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All arrays, variables or constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.
Question 10 — Student Step Counts
Scenario
A school is recording the daily step counts of students in a physical education class. Each student’s steps are recorded once per day for seven days.
The one-dimensional (1D) array DayName[] contains the names of the seven days of the week.
The one-dimensional (1D) array StudentName[] stores the names of the students in the class. The variable ClassSize stores the number of students in the class.
The two-dimensional (2D) array StepCount[] is used to store the daily step count for each student. The first dimension of StepCount[] is the same index as the student in StudentName[]. The second dimension stores the step count for each day of the week.
The position of any student’s data is the same in StudentName[] and StepCount[]. For example, the student stored at index 3 in StudentName[] has their daily step counts at index 3 of StepCount[].
The one-dimensional (1D) array WeeklyTotal[] is used to store the total steps for the week for each student. The index of WeeklyTotal[] is the same as the index of the student in StudentName[].
Step counts must be between 0 and 50,000 inclusive.
Write a program that meets the following requirements:
- inputs and validates the daily step count for each student for each day of the week
- calculates and stores the total steps for the week for each student in
WeeklyTotal[] - calculates the average weekly step count for the whole class
- converts each student’s weekly total from steps to kilometres using the formula: Kilometres = WeeklyTotal / 1250
- outputs for each student their name, weekly total in steps, and weekly distance in kilometres
- outputs the average weekly step count for the whole class
- outputs the name of the student with the highest weekly total and the name of the student with the lowest weekly total.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. You do not need to declare any arrays, variables or constants; you may assume that this has already been done. Assume that StudentName[] and ClassSize already contain the required data. You will need to initialise and populate the array DayName[] at the start of the program. All data output must be rounded to two decimal places. All inputs and outputs must contain suitable messages.
Predicted Questions 9 & 10
Question 11 — Car Hire Company
Scenario
A car hire company stores the names of customers in a one-dimensional (1D) array CustomerName[]. The system can store details for a maximum of 200 customers.
A two-dimensional (2D) array HireDetails[] stores the following details of each customer’s booking:
- column 1 — number of days hired (whole number)
- column 2 — vehicle category index (whole number)
- column 3 — insurance option index (whole number)
- column 4 — total hire cost in dollars (two decimal places).
The index of any customer’s data is the same in both arrays. For example, a customer stored in index 7 of CustomerName[] corresponds to the data in index 7 of HireDetails[].
The hire period must be between 1 and 30 days inclusive.
The vehicle categories available and their daily rates are stored in two 1D arrays. The index of the vehicle type and daily rate in their arrays share the same index number:
| Index | Vehicle category (VehicleType[]) | Daily rate in $ (DailyRate[]) |
|---|---|---|
| 1 | Economy | 35.00 |
| 2 | Standard | 55.00 |
| 3 | SUV | 80.00 |
| 4 | Luxury | 120.00 |
The insurance options and their fixed daily costs are stored in two 1D arrays. The index of the insurance option and cost in their arrays share the same index number:
| Index | Insurance option (InsuranceType[]) | Daily cost in $ (InsuranceCost[]) |
|---|---|---|
| 1 | Basic | 5.00 |
| 2 | Standard | 12.00 |
| 3 | Comprehensive | 20.00 |
Write a program that meets the following requirements:
- initialises the
CustomerName[]array with the null string ("") for all 200 locations - provides a menu with the options: add a new customer, or stop
- inputs and validates the menu choice
- when adding a new customer:
- inputs the customer’s name, number of hire days, vehicle category index, and insurance option index
- validates the number of hire days is between 1 and 30 inclusive, with re-entry if not valid
- validates the vehicle category index is between 1 and 4 inclusive, with re-entry if not valid
- validates the insurance option index is between 1 and 3 inclusive, with re-entry if not valid
- calculates the total hire cost using the formula: Total cost = (DailyRate + InsuranceCost) × Days
- stores all data in the first available location in the relevant arrays
- outputs the customer’s quotation showing: name, vehicle category, insurance option, number of days, and total cost
- the program continues until the stop option on the menu is selected.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. You do not need to declare any arrays, variables or constants; you may assume that this has already been done. You will need to initialise VehicleType[], DailyRate[], InsuranceType[], and InsuranceCost[]. All inputs and outputs must contain suitable messages.
Question 12 — Currency Converter
Scenario
A program is required to allow users to convert an amount of money from one currency to another. It will use functions to allow additional currencies to be added in the future.
The following three conversions are supported:
| Conversion | Formula |
|---|---|
| USD -> EUR | amount x 0.92 |
| USD -> GBP | amount x 0.79 |
| USD -> JPY | amount x 149.50 |
The exchange rates are fixed constants within the program.
Write a program that meets the following requirements:
- output a menu to ask the user to select a conversion type from the three options given, or to stop the program; the program must validate the input
- input the amount in USD to be converted
- create one function for each conversion to calculate and return the converted amount using the given formulae; each function takes the USD amount as a parameter
- output the converted amount in the main program, rounded to two decimal places
- the program continues until the user selects the stop option from the menu.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All variables and constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.
Predicted Questions 11 & 12
Additional Scenario Questions (Q13–Q25)
Thirteen full 15-mark scenario questions modelled on real Cambridge exam papers. Each includes both Pseudocode and Python solutions, with hints, a mark scheme, and (for Q17, Q19 and Q25) two valid approaches to compare.
Question 13 — Library Book Management System
Scenario
A small community library stores its catalogue of 200 books in a two-dimensional array called Books. Each row of Books represents one book. The columns store: Column 1: BookID (a unique 4-character code, e.g. "A001") Column 2: Title Column 3: Author Column 4: Category (one of "Fiction", "Non-Fiction", "Children", "Reference") Column 5: Status (either "Available" or "Borrowed") The variable NumBooks stores the number of books (200). The library needs a program to let members borrow and return books, and to let the librarian search the catalogue. The data in Books is already populated — you do not need to input it. Write a program that meets the following requirements:
Requirements
- Display all books that are currently Available — output BookID, Title and Author only.
- Allow a member to borrow a book by entering its BookID. If the book exists and is Available, set its Status to "Borrowed"; otherwise output a suitable message.
- Allow a member to return a book by entering its BookID. If the book is currently Borrowed, set its Status back to "Available".
- Allow the librarian to search for all books in a given Category and output each one found, with a count at the end.
- Display a menu offering the five options: Display Available, Borrow, Return, Search by Category, Exit. The menu must repeat until the user chooses Exit.
- Validate the menu choice using a REPEAT...UNTIL loop so that only options 1-5 are accepted.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All arrays, variables or constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.
Question 14 — Student Grade Calculator
Scenario
A teacher needs a program to analyse the exam scores of 25 students across 5 subjects: Maths, English, Science, History and Geography. The maximum mark for each subject is 100. The 2D array StudentScores stores the marks. StudentScores[Student, Subject] holds the mark for student Student (1 to 25) in subject Subject (1 to 5). The 1D array StudentName holds the name of each student. The variable NumStudents stores the number of students (25) and the constant NumSubjects stores the number of subjects (5). Grade boundaries are: A (80-100), B (70-79), C (60-69), D (50-59), F (0-49). A pass is any mark of 50 or above. Write a program that meets the following requirements:
Requirements
- Input and validate each student's name and their 5 subject scores. Scores must be integers from 0 to 100 inclusive; use a REPEAT...UNTIL loop to reject invalid input.
- For each student, calculate their average score (rounded to 1 decimal place) across the 5 subjects and store in a 1D array StudentAverage.
- Assign a grade letter to each student based on their average using the boundaries above and store in a 1D array StudentGrade.
- Find and output the name of the student with the highest average and the student with the lowest average.
- Count and output the total number of passes (scores >= 50) across all students and subjects, and the total number of fails (scores < 50).
- Output a full report showing each student's name, average (1 dp), grade, and pass count.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All arrays, variables or constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.
Question 15 — Cinema Ticket Booking
Scenario
A small cinema has 8 rows of 10 seats (80 seats in total). The 2D array Seats stores the booking status of every seat: Seats[Row, Col] = 0 means free, 1 means booked. Rows are numbered 1 to 8 and columns 1 to 10. Ticket prices depend on the ticket type chosen by the customer for each seat: - Adult: $12.00 - Child: $7.00 - Concession (student / senior): $9.00 The variable TotalRevenue stores the running total of all ticket sales. The program must allow a customer to book one or more seats, then print a receipt and update the seating plan. Multiple customers may be served in a single run.
| Ticket Type | Price ($) |
|---|---|
| Adult | 12.00 |
| Child | 7.00 |
| Concession | 9.00 |
Requirements
- Display the current seating plan as a grid where "-" represents a free seat and "X" represents a booked seat, with row and column numbers.
- Ask the customer how many seats they wish to book (validate >= 1).
- For each seat: ask for the row (1-8) and column (1-10), validate the input, and check that the seat is free; if not, ask again.
- For each seat: ask for the ticket type (1=Adult, 2=Child, 3=Concession) using a CASE OF structure, and add the corresponding price to a running TotalCost.
- Mark each booked seat as 1 in Seats[].
- Output a receipt showing each seat booked, its ticket type, and price; then the total cost.
- Update TotalRevenue and output it after each customer. Repeat the whole process for the next customer until the user types "N" when asked if they want to continue.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All arrays, variables or constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.
Question 16 — Weather Station Analysis
Scenario
A weather station records the temperature at four fixed times each day (06:00, 12:00, 18:00, 00:00) for one week. The 2D array Temperatures stores these readings: Temperatures[Day, Reading] where Day is 1 to 7 (Monday to Sunday) and Reading is 1 to 4 (the four times). The 1D array DayName stores the day names: DayName[1] = "Monday", DayName[2] = "Tuesday", and so on up to DayName[7] = "Sunday". The 1D array DailyAverage stores the average temperature for each day. The variable WeeklyAverage stores the overall weekly average. Temperatures are REAL values (e.g. 23.5). The user inputs all 28 readings at the start of the program. Write a program that meets the following requirements:
Requirements
- Populate DayName[] with the seven day names (Monday to Sunday).
- Input all 28 temperature readings into Temperatures[] (no validation needed for this question — assume valid input).
- Calculate the average temperature for each day and store in DailyAverage[], rounded to 1 decimal place.
- Calculate the overall weekly average and store in WeeklyAverage, rounded to 1 decimal place.
- Find and output the hottest single reading across the whole week (value, day name, and reading number).
- Find and output the coldest single reading (value, day name, and reading number).
- Count and output how many days had a daily average above 25.0 degrees Celsius.
- Output a weekly summary table showing each day's name and its daily average.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All arrays, variables or constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.
Question 17 — Sports League Table
Scenario
A local football league has 6 teams. After the season ends, the league needs a program to calculate the final standings. For each team, the following data is stored in PARALLEL 1D arrays: TeamName[i] — team name (STRING) Won[i] — matches won (INTEGER) Drawn[i] — matches drawn (INTEGER) Lost[i] — matches lost (INTEGER) GoalsFor[i] — goals scored (INTEGER) GoalsAgainst[i] — goals conceded (INTEGER) Points[i] — to be calculated (INTEGER) The variable NumTeams stores 6. Points are awarded as 3 per win, 1 per draw, 0 per loss. The league table must be sorted into DESCENDING order of points (highest first) using bubble sort, so the team with the most points ends up at index 1. Write a program that meets the following requirements:
Requirements
- Input the team name and the five integer values (Won, Drawn, Lost, GoalsFor, GoalsAgainst) for each of the 6 teams. Validate that Won, Drawn, Lost are all >= 0.
- For each team, calculate Points = 3 * Won + 1 * Drawn and store in Points[].
- Use bubble sort to sort all six arrays in descending order of Points (so the team with the most points ends up at index 1).
- Output the sorted league table showing Position, Team Name, Played, Won, Drawn, Lost, GoalsFor, GoalsAgainst, Points.
- Output the name of the champion (the team now at index 1) with a congratulatory message.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All arrays, variables or constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.
Question 18 — Supermarket Checkout System
Scenario
A small supermarket has 20 products in its database. For each product, the following data is stored in PARALLEL arrays: Barcode[i] — STRING, e.g. "5000119" Name[i] — STRING Price[i] — REAL Category[i] — STRING — one of "Dairy", "Bakery", "Meat", "Produce", "Other" The variable NumProducts stores 20. Discounts apply by category: - Dairy: 10% off - Bakery: 5% off - All other categories: no discount A customer brings a basket of items to the checkout. The cashier scans each item's barcode; the program looks up the product and adds it to the running receipt. The data in the arrays is already populated — you do not need to input it.
| Category | Discount |
|---|---|
| Dairy | 10% |
| Bakery | 5% |
| Meat | 0% |
| Produce | 0% |
| Other | 0% |
Requirements
- Repeatedly ask the cashier to scan a barcode. Stop when "END" is entered.
- For each barcode, use linear search to find the matching product. If not found, output "Unknown barcode" and continue.
- For each found product, calculate the discounted price = Price * (1 - DiscountPercent/100) based on its category. Round the discounted price to 2 decimal places.
- Maintain a running SubTotal (sum of original prices) and TotalDiscount (sum of discounts applied).
- Output an itemised receipt showing each scanned item's name, original price, discount amount, and discounted price.
- At the end, output SubTotal, TotalDiscount, and FinalTotal (= SubTotal - TotalDiscount), all rounded to 2 decimal places.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. You do not need to initialise the data in the arrays.
Question 19 — Hotel Room Reservation
Scenario
A boutique hotel has 30 rooms. Each room has the following data: RoomNumber[i] — INTEGER (101-130) RoomType[i] — STRING — "Single", "Double", or "Suite" PricePerNight[i] — REAL Occupied[i] — INTEGER — 0 = free, 1 = occupied The variable NumRooms stores 30. Room rates by type: Single $80, Double $120, Suite $200. The hotel receptionist needs a program to manage bookings, check-outs, and searches. The room data is already populated — you do not need to input it.
| Room Type | Price/Night ($) |
|---|---|
| Single | 80.00 |
| Double | 120.00 |
| Suite | 200.00 |
Requirements
- Display all available (unoccupied) rooms with their number, type, and price.
- Allow a guest to book a room by type. Find the first available room of that type (Pattern 4 — find first empty slot). Mark it as occupied and output the room number.
- Allow a guest to check out: input room number and number of nights stayed. Validate the room number (101-130). Calculate the bill = PricePerNight * Nights, output it, and mark the room as available again.
- Allow the receptionist to search for all rooms of a given type (occupied or not) and display them.
- Use a menu (1=Display Available, 2=Book by Type, 3=Check Out, 4=Search by Type, 5=Exit) with REPEAT...UNTIL validation and CASE OF dispatch. The menu repeats until Exit.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All arrays, variables or constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.
Question 20 — School Attendance Tracker
Scenario
A school class has 30 students. The teacher records attendance for each student across a 5-day school week (Monday to Friday). The 2D array Attendance stores the status of each student on each day: "P" = Present "A" = Absent "L" = Late Attendance[Student, Day] holds the status for student Student (1 to 30) on day Day (1 to 5). The 1D array StudentName holds student names. The 1D array DayName holds day names. The variable NumStudents stores 30 and NumDays stores 5. A student is considered to have "good attendance" if their attendance percentage is 75% or above. Attendance percentage = (Present + Late) / 5 * 100 (Late counts as attended). Write a program that meets the following requirements:
Requirements
- Populate DayName[] with the five day names.
- Input each student's name and their 5 attendance codes. Validate each code using REPEAT...UNTIL so only "P", "A", or "L" is accepted.
- For each student, calculate their attendance percentage (Present + Late counts as attended; absent does not). Round to 1 decimal place. Store in a 1D array AttendancePercent.
- Find and output the names of all students whose attendance is below 75% (warn the teacher).
- For each day, count the number of absences (students with "A" on that day). Output the count per day.
- Output a class summary: each student's name, attendance percentage, and a flag "OK" or "AT RISK" (below 75%).
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All arrays, variables or constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.
Question 21 — Bank Account Manager
Scenario
A small bank stores its 50 customer accounts in parallel arrays: AccountNumber[i] — INTEGER, unique 6-digit number CustomerName[i] — STRING Balance[i] — REAL, in dollars AccountType[i] — STRING — "Savings" or "Current" The variable NumAccounts stores 50. The bank teller needs a program to manage deposits, withdrawals, transfers, and statements. No overdraft is allowed — a withdrawal that would make the balance negative must be rejected. The account data is already populated — you do not need to input it. Write a program that meets the following requirements:
Requirements
- Display a menu: 1=Deposit, 2=Withdraw, 3=Transfer, 4=Statement, 5=Exit. Validate the choice with REPEAT...UNTIL (1-5 only). The menu repeats until Exit.
- Deposit: input an account number, find it with linear search (output "not found" if missing), input a positive amount (validated > 0), and add to Balance.
- Withdraw: input account number, input a positive amount, check that Balance >= amount (no overdraft). If valid, subtract; otherwise output "Insufficient funds".
- Transfer: input two account numbers (source and destination), input a positive amount, validate source balance, then subtract from source and add to destination.
- Statement: input account number, output account number, name, type, and balance (rounded to 2 dp).
- All amounts must be validated as positive (> 0). Use suitable messages for every input and output.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. You do not need to initialise the data in the arrays.
Question 22 — Vending Machine Simulator
Scenario
A vending machine holds 8 different products. Each product has: Name[i] — STRING, e.g. "Cola", "Chips" Price[i] — REAL Stock[i] — INTEGER — number of items remaining The variable NumProducts stores 8. The machine accepts payment in whole dollars (INTEGER). When the customer selects a product: 1. The machine checks the stock — if 0, output "Out of stock" and abort. 2. The customer inserts payment — must be >= price. 3. The machine calculates change = payment - price. 4. The machine dispenses the product and updates stock. 5. The machine outputs the change. At the end of the day, the owner runs a report showing each product's remaining stock and a flag "REORDER" if stock is below 3. The product data is already populated — you do not need to input it. Write a program that meets the following requirements:
Requirements
- Declare Name[], Price[], Stock[] parallel arrays of size 8. Assume they are pre-populated.
- Display a numbered menu of products (1-8) with their names, prices, and current stock.
- Allow a customer to select a product (validate 1-8 using REPEAT...UNTIL). If stock is 0, output "Out of stock" and return to the menu.
- Ask the customer to insert payment (INTEGER dollars). Validate that payment >= price; if not, output "Insufficient payment" and return to the menu.
- Calculate change = payment - price. Update stock (decrement by 1). Output the product name and the change.
- Use an outer REPEAT...UNTIL loop to serve multiple customers until "N" is entered.
- At the end, output an end-of-day report: each product's name, stock remaining, and "REORDER" flag if stock < 3.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. You do not need to initialise the data in the arrays.
Question 23 — Car Park Management System
Scenario
A multi-storey car park has 3 floors, each with 20 parking spaces — 60 spaces in total. The car park uses a 2D array ParkingLot to store the registration plate of the car parked in each space: ParkingLot[Floor, Space] — STRING — Floor 1 to 3, Space 1 to 20 An empty space is represented by "EMPTY". A second 2D array EntryTime[Floor, Space] stores the arrival time of each car as an INTEGER minutes-since-midnight (for example, 09:30 is stored as 570, and 14:15 is stored as 855). The variable NumFloors stores 3, and NumSpacesPerFloor stores 20. The parking fee is $2.50 per hour (or part thereof) — so a stay of 1 hour 1 minute costs $5.00. A running total TotalRevenue stores the total fees collected since the program started. The car park operator needs a program that lets the attendant manage vehicle entry and exit, and report on the current state of the car park. When a car enters, the attendant types in the registration plate and the current time in minutes. When a car leaves, the attendant types in the registration plate and the exit time; the program calculates the fee, adds it to TotalRevenue, and frees the space. The ParkingLot and EntryTime arrays must be initialised by your program — set every cell to "EMPTY" and 0 respectively. Write a program that meets the following requirements:
Requirements
- Declare ParkingLot as a 2D ARRAY[1:3, 1:20] OF STRING and EntryTime as a 2D ARRAY[1:3, 1:20] OF INTEGER. Initialise every cell to "EMPTY" and 0 respectively using nested FOR loops. Set NumFloors <- 3, NumSpacesPerFloor <- 20, TotalRevenue <- 0.0.
- Display the number of available spaces on each floor and the overall total available.
- Allow a car to enter: input the registration plate and the entry time (in minutes since midnight, validated 0-1439 using REPEAT...UNTIL). Find the first empty space scanning Floor 1 to 3, Space 1 to 20 (Pattern 4 — find first empty slot). Store the plate in ParkingLot and the time in EntryTime. Output the floor and space number allocated. If the car park is full, output "Car park full".
- Allow a car to exit: input the registration plate and the exit time (validated > entry time using REPEAT...UNTIL). Search the 2D array for the plate. Calculate the duration in hours (rounded UP — a stay of any part of an hour counts as a full hour). Fee = Hours × $2.50. Output the fee, add it to TotalRevenue, and set the space back to "EMPTY".
- If the registration plate is not found on exit, output "Vehicle not found".
- Use a menu (1=Display Available, 2=Park Car, 3=Remove Car, 4=Display Revenue, 5=Exit) with REPEAT...UNTIL validation (1-5) and CASE OF dispatch. The menu repeats until Exit.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All arrays, variables or constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.
Question 24 — Online Shopping Cart
Scenario
An online shop sells 10 different products. Each product is described by four parallel arrays: ProductID[i] — STRING, e.g. "P001" (i = 1 to 10) Name[i] — STRING, e.g. "Wireless Mouse" Price[i] — REAL Stock[i] — INTEGER — number of items currently in the warehouse The shopping cart holds up to 20 different products and is described by two more parallel arrays: CartID[i] — STRING (the ProductID added) CartQty[i] — INTEGER (the quantity chosen) A third variable, CartSize, stores how many distinct products are currently in the cart (initially 0). If a customer adds a product that is already in the cart, the program should simply increase the quantity for that entry rather than creating a new one. When an item is removed from the cart, any later entries should be shifted down to keep the cart compact, and the stock should be restored. Discount codes are: "SAVE10" gives 10% off the subtotal, "SAVE20" gives 20% off, and any other code (or no code) gives no discount. Shipping is free if the (discounted) subtotal is $50 or more; otherwise a flat $5.00 is added. All money values should be displayed to 2 decimal places. The product data is already populated — you do not need to input it. Write a program that meets the following requirements:
Requirements
- Declare ProductID[1:10], Name[1:10], Price[1:10], Stock[1:10] parallel arrays and CartID[1:20], CartQty[1:20] parallel arrays. Assume the product arrays are pre-populated. Set CartSize <- 0 and DiscountRate <- 0.0.
- Display the product catalogue: ID, Name, Price, Stock for all 10 products.
- Add to cart: input a ProductID and a quantity (validated >= 1 using REPEAT...UNTIL, and not more than the available stock). Use linear search to find the product. If the product is already in the cart, increase CartQty. Otherwise add a new entry to the cart and increment CartSize. Decrement the product's Stock.
- Remove from cart: input a ProductID. If it is in the cart, remove it (shift later entries down to keep the cart compact) and restore the stock. Otherwise output "Item not in cart".
- Apply discount code: input a code. Use CASE OF to set DiscountRate (0.10 for "SAVE10", 0.20 for "SAVE20", 0.00 otherwise). Output the discount rate applied.
- Calculate the order: subtotal = sum of (Price * CartQty) for all cart items; discount = subtotal * DiscountRate; discountedSubtotal = subtotal - discount; shipping = 0 if discountedSubtotal >= 50 else 5.00; total = discountedSubtotal + shipping.
- Generate the order summary: list each cart line (Name, Qty, LineTotal), then the subtotal, discount, shipping, and total. All money values to 2 dp using ROUND.
- Use a menu (1=View Catalogue, 2=Add to Cart, 3=Remove from Cart, 4=Apply Discount, 5=Checkout, 6=Exit) with REPEAT...UNTIL validation (1-6) and CASE OF dispatch. The menu repeats until Exit.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. You do not need to initialise the data in the product arrays.
Question 25 — Hospital Appointment Scheduler
Scenario
A GP surgery needs a program to manage its daily appointment diary. The diary has 20 appointment slots, one per half hour from 08:00 to 17:30. Each slot is described by four parallel arrays: PatientName[i] — STRING (or "FREE" if the slot has never been booked) DoctorName[i] — STRING — one of "Dr Lee", "Dr Patel", "Dr Wong" AppointmentTime[i] — STRING, e.g. "08:00", "08:30", "09:00", ..., "17:30" Status[i] — STRING — "Booked", "Cancelled", or "Free" The variable NumSlots stores 20. Appointment times are pre-set by your program to the 20 half-hour values from "08:00" to "17:30" — you do not need to input them. Initially every slot is Free, with PatientName = "FREE" and DoctorName = "" (empty string). The receptionist needs a program to book, cancel, search, and report on appointments. The status flow is: Free -> Booked (on booking) -> Cancelled (on cancellation). When a patient cancels, the slot's Status is set to "Cancelled" but the PatientName is kept (so the surgery has a record of who cancelled). A Cancelled slot cannot be re-booked through the normal Book flow — the receptionist must instead correct it manually. However, a Free slot can always be booked. Write a program that meets the following requirements:
Requirements
- Declare four parallel arrays of size 20: PatientName[1:20], DoctorName[1:20], AppointmentTime[1:20], Status[1:20]. Pre-set AppointmentTime to "08:00", "08:30", ..., "17:30" using a loop. Initialise every slot as Free: PatientName[i] = "FREE", DoctorName[i] = "", Status[i] = "Free".
- Book appointment: input patient name, doctor name, and the time slot wanted. Use linear search to find the slot with the matching AppointmentTime. If Status is "Free", set PatientName, DoctorName, Status to "Booked" and output a confirmation. If the slot is Booked or Cancelled, output "Slot not available". If the time is not recognised, output "Time slot not recognised".
- Cancel appointment: input patient name. Linear search for a slot with that PatientName AND Status = "Booked". Set Status to "Cancelled" (keep PatientName) and output the cancellation. If not found, output "No booking found".
- Search by patient: input patient name. Linear search all 20 slots and output every appointment (time, doctor, status) matching that patient. If none, output "No appointments found".
- Display daily schedule: output all 20 slots with time, patient, doctor, status in a formatted table.
- Count appointments per doctor: for each of the three doctors, count slots with Status = "Booked" and output the count.
- Use a menu (1=Book, 2=Cancel, 3=Search by Patient, 4=Display Schedule, 5=Doctor Counts, 6=Exit) with REPEAT...UNTIL validation (1-6) and CASE OF dispatch. The menu repeats until Exit.
Closing rules: You must use pseudocode or program code and add comments to explain how your code works. All arrays, variables or constants used must be declared for this algorithm. All inputs and outputs must contain suitable messages.