Exam Preparation

AS Level 9618

Practical Tasks - Advanced

110 exam-style AS Level programming tasks across 6 modules, covering every topic in the Cambridge 9618 Paper 2 Pseudocode Checklist. For every task, click Show Hints for progressive nudges or Show Pseudocode for the worked solution (Easy questions show the complete pseudocode; Medium-to-Hard questions add a step-by-step breakdown; the hardest Hard questions show two valid approaches to compare).

M1

Module 1

Syntax & Data Types

Cambridge non-negotiable conventions: keywords, identifiers, the six data types, DECLARE/CONSTANT, the <- arrow, literals and all operators.

1EasyVariable Declarations (DECLARE)

A hospital's patient record stores: the patient's full name, their date of birth, their weight in kilograms (to 1 decimal place), their blood type as a single letter, and whether they are an organ donor. Write pseudocode to DECLARE these five variables with the most appropriate Cambridge data types.

2EasyConstant Declarations (CONSTANT) + Assignment (<-)

A physics simulator uses the gravitational acceleration constant 9.81 m/s^2. The current velocity (REAL) of a falling object is then computed and stored. Write pseudocode to declare the gravitational constant using CONSTANT syntax, then declare a REAL variable Velocity and assign it the value 0.0 using the Cambridge assignment arrow.

3MediumUppercase Keywords + Indentation

A student has written the following pseudocode with incorrect keyword casing and no indentation. Rewrite the snippet using correct Cambridge conventions: ALL keywords in UPPER CASE and consistent four-space indentation inside each control structure.

declare age : integer
input age
if age >= 18 then
output "Adult"
else
output "Minor"
endif
4MediumMixed Case Identifiers

A library system needs variables for: the number of books on loan, the maximum books a member can borrow, the name of the current member, and whether the member has any overdue items. Using Cambridge mixed-case identifier conventions (camelCase or PascalCase, no underscores, no hyphens), write DECLARE statements for these four variables with the most appropriate data types.

5MediumLiterals (CHAR/STRING/BOOLEAN/REAL)

A vending machine stores the product code (a single letter such as 'A'), the product name, the price in pounds (with pence), and whether the product is currently in stock. Write four assignment statements using correctly typed literals for the variables ProductCode : CHAR, ProductName : STRING, Price : REAL, and InStock : BOOLEAN.

6MediumArithmetic Operators (+ - * / DIV MOD ^)

A cinema sells tickets in batches. A batch contains a known number of tickets; any remainder after batching is sold individually at the door. Write pseudocode to input a total number of tickets sold (INTEGER), and output how many full batches were sold and how many individual tickets remained, assuming each batch holds 12 tickets. Use DIV and MOD.

7MediumRelational + Logical Operators

A theme park ride admits a visitor only when ALL of the following are true: the visitor is at least 120 cm tall, the visitor is at most 16 years old, and the visitor is NOT accompanied by an adult who has paid for a VIP fast-pass. Given the variables Height : INTEGER, Age : INTEGER, and HasFastPass : BOOLEAN already declared and assigned, write a single BOOLEAN expression that evaluates to TRUE when the visitor is admitted. Do NOT use IF; just write the expression assigned to a BOOLEAN variable AllowEntry.

8MediumDATE Type + Arithmetic

A driving licence expires 50 years after the holder's date of birth. Given a variable DateOfBirth : DATE that has already been declared and assigned, write pseudocode to declare ExpiryDate : DATE and assign it a value demonstrating the convention that Cambridge DATE arithmetic can add a number of years. Then OUTPUT the expiry date.

9HardUppercase Keywords + Indentation + Relational Ops

A student wrote the following buggy temperature-monitoring snippet for a freezer alarm. Rewrite it using Cambridge conventions (UPPER CASE keywords, four-space indentation) AND fix the assignment symbol so that all three threshold comparisons store their result in BOOLEAN variables.

declare temp : real
input temp
freeze = temp <= -18
warn = temp > -18 and temp <= 0
safe = temp > 0
output freeze, warn, safe
10HardData Types + Variable Declarations

A school information system stores a single student's record with the following fields: their unique 4-digit student ID (e.g. 0427), their full name, their form tutor's initial (a single letter), their average grade as a percentage to 2 decimal places, the date they enrolled, and whether they have paid the optional trip deposit. Write pseudocode to DECLARE all six variables with the most appropriate Cambridge data type. Justify in a comment why StudentID is a STRING despite looking like a number.

11HardArithmetic Precedence (DIV MOD ^)

A water tank is shaped like a cube with side length Side (INTEGER cm). The tank is filled with water to a depth of DepthCm (INTEGER cm). Write pseudocode to: (1) declare Side and DepthCm as INTEGER, (2) declare Volume (REAL) and WaterVolume (REAL), (3) compute the total tank volume using the ^ operator, and (4) compute the water volume as Side * Side * DepthCm. Finally output both volumes.

12HardRelational + Logical Operators

A bank approves a customer for a loan when ALL the following hold: the customer is aged 21 or over; the customer's annual income is at least 25000; the customer is NOT currently bankrupt; AND EITHER the customer owns a property OR the customer has a guarantor. Given Age : INTEGER, Income : REAL, IsBankrupt : BOOLEAN, OwnsProperty : BOOLEAN, HasGuarantor : BOOLEAN (all already declared and assigned), write a single BOOLEAN expression assigned to Approve : BOOLEAN.

13HardConstants + Arithmetic (^)

A bank pays a fixed annual interest rate of 5%. A customer deposits Principal (REAL pounds) for exactly 3 years (no withdrawals). Using a CONSTANT named RATE = 1.05 (the growth factor), write pseudocode to declare Principal (REAL) and FinalAmount (REAL), input Principal, compute FinalAmount = Principal * (RATE ^ 3), and output the result to 2 decimal places using ROUND.

14HardMixed Case Identifiers + Literals

A weather station records the following readings for one observation: the station's three-letter code (e.g. 'LHR'), the wind direction as a single character (e.g. 'N'), the temperature in Celsius (REAL), the barometric pressure in hPa (INTEGER), whether it is raining, and the timestamp as a DATE. Write pseudocode to DECLARE all six variables using clear mixed-case identifiers, then assign each a correctly-typed literal value of your choice.

15HardLogical + Relational Operators (Leap Year)

A leap year in the Gregorian calendar is divisible by 4, EXCEPT for end-of-century years which must be divisible by 400. Given Year : INTEGER already declared and assigned, write a single BOOLEAN expression assigned to IsLeap : BOOLEAN that evaluates to TRUE when Year is a leap year. Use DIV, MOD, AND, OR, NOT and brackets as needed.

16HardCHAR + Relational + Logical Operators

A spelling app needs to test whether a single character stored in Letter : CHAR is a vowel (upper or lower case). Write pseudocode to declare IsVowel : BOOLEAN and assign it TRUE when Letter is one of A, E, I, O, U (in either case). Use only relational operators (=), logical OR, and the UCASE function. Do NOT use IF.

17HardRelational + Logical Operators (Triangle Inequality)

Three side lengths A, B, C (all REAL) form a valid triangle only when the sum of any two sides is greater than the third. Given A, B and C already declared and assigned, write pseudocode to declare IsValid : BOOLEAN and assign it the result of the triangle inequality test using three relational conditions joined by AND.

18HardArithmetic (DIV/MOD) — Time Conversion

A marathon timer records TotalSeconds (INTEGER). Write pseudocode to input TotalSeconds and output the equivalent time in HH:MM:SS form, where HH is the number of whole hours, MM is the remaining whole minutes (00-59) and SS is the remaining whole seconds (00-59). Use only DIV, MOD, INTEGER variables and string concatenation (&).

19HardArithmetic + Relational (^ and roots)

A quadratic equation ax^2 + bx + c = 0 (coefficients a, b, c all REAL, a <> 0) has a discriminant D = b^2 - 4ac. Write pseudocode to: input a, b, c; compute D; then output "Two real roots" when D > 0, "One repeated root" when D = 0, and "No real roots" when D < 0. Provide TWO valid approaches — one using nested IF/ELSE, one using an ELSEIF chain.

20HardConstants + Arithmetic + Relational/Literals

An electricity company charges a fixed daily standing charge of 0.40 pounds and 0.18 pounds per kWh used. The bill is reduced by 5% if usage is 200 kWh or less; otherwise a 2% surcharge applies. Write pseudocode to: declare CONSTANT STANDING = 0.40 and CONSTANT RATE = 0.18, declare Usage (REAL) and Bill (REAL), input Usage, then compute and output the final bill rounded to 2 decimal places. Provide TWO valid approaches — one using IF/ELSE, one using a CASE OF structure on a discount code.

M2

Module 2

Control Flow — Selection & Iteration

The engine of pseudocode: IF/ELSE, ELSEIF, CASE OF, FOR, WHILE and REPEAT — the six constructs that drive every algorithm.

1EasyIF...THEN...ELSE...ENDIF

A teacher awards a PASS when a student's exam score is 50 or above; otherwise the student FAILS. Write pseudocode to input Score (INTEGER) and output either "PASS" or "FAIL" using a single IF/ELSE.

2EasyFOR...TO...NEXT

A primary school classroom displays the 5 times table on the board. Write pseudocode using a FOR loop to output the 5 times table from 5 x 1 up to 5 x 12.

3MediumELSEIF Chain (Grade Boundaries)

A college assigns letter grades from a percentage score: A for 80-100, B for 70-79, C for 60-69, D for 50-59, F for 0-49. Write pseudocode to input Score (INTEGER, 0-100) and output the grade letter using an ELSEIF chain.

4MediumCASE...OF...OTHERWISE...ENDCASE

A scheduling app receives a DayNum (INTEGER 1-7). Write pseudocode using CASE OF to output the corresponding weekday name (1 = Monday ... 7 = Sunday) and use OTHERWISE to handle invalid inputs by outputting "Invalid day".

5MediumWHILE...DO...ENDWHILE

A rocket launch system counts down from 10 to 1, outputting each number, before outputting "LIFT OFF!". Write pseudocode using a WHILE loop (not FOR) and a Counter variable that starts at 10 and decreases by 1 each iteration.

6MediumREPEAT...UNTIL

A quiz application asks the user to enter their age (INTEGER), but the user must be aged between 5 and 120 inclusive. Write pseudocode using a REPEAT...UNTIL loop that keeps prompting until a valid age is entered. After the loop, output "Age accepted".

7MediumFOR...TO...STEP...NEXT

A countdown timer displays every even number from 20 down to 2 (i.e. 20, 18, 16, ..., 2). Write pseudocode using a single FOR loop with a NEGATIVE STEP value.

8MediumNested IF (Leap Year)

A calendar app must report whether a Year (INTEGER) is a leap year. Write pseudocode using NESTED IF statements (no compound AND/OR): if Year is divisible by 4, check if it is divisible by 100; if so, also check if divisible by 400. Output "Leap year" or "Not a leap year".

9HardWHILE / REPEAT Comparison (Menu Loop)

A text-based calculator repeatedly shows a menu (1 = Add, 2 = Subtract, 3 = Quit) until the user picks 3. Write pseudocode using a WHILE loop that handles one of the two arithmetic options on each pass. Display the menu, INPUT Choice, and use IF/ELSEIF inside the loop. Quit cleanly when Choice = 3.

10HardFOR + Accumulator (Sum of Squares)

A maths drill asks students to compute the sum 1^2 + 2^2 + ... + 10^2 using pseudocode. Write pseudocode that uses an accumulator Sum (INTEGER) initialised to 0 and a FOR loop from 1 to 10. Output the final sum.

11HardCASE OF with arithmetic

A simple calculator inputs two REAL numbers (Num1, Num2) and an operator character Op (CHAR: +, -, *, /). Use CASE OF to perform the selected operation and output the result. Use OTHERWISE for an invalid operator and include a guard inside the "/" case so that division by zero outputs "Cannot divide by zero" rather than crashing.

12HardELSEIF Chain (Tax Brackets)

A simplified income tax system levies: 0% on the first 12500 pounds; 20% on the portion from 12501 to 50000; 40% on the portion from 50001 to 150000; 45% on the portion above 150000. Write pseudocode to input Salary (REAL) and output the total tax due, rounded to 2 decimals. Use an ELSEIF chain to choose the formula for each band.

13HardWHILE + Sentinel (Running Total)

A teacher enters a class of students' test scores one at a time. A score of -1 indicates the end of input (the sentinel — do not include it in the total). Write pseudocode using a WHILE loop to read scores, accumulate the total, count how many were entered, and finally output the average to 2 decimals. Guard against dividing by zero if no scores were entered.

14HardREPEAT...UNTIL (Multiple Validation Conditions)

A new account system requires a username that is between 5 and 15 characters in length (use the LENGTH function) AND does not contain spaces. The user keeps re-entering the username until both conditions hold. Write pseudocode using a REPEAT...UNTIL loop. After acceptance, output "Username accepted".

15HardNested FOR (Multiplication Table)

A classroom display prints a 12x12 multiplication table. Write pseudocode using two NESTED FOR loops (outer loop = row 1..12, inner loop = column 1..12) that outputs the product Row * Column for each cell, separated by a tab character "\t". Output a newline after each row.

16HardFOR + IF/ELSEIF (FizzBuzz)

A children's counting game prints numbers from 1 to 30 with the following twist: for multiples of 3 output "Fizz" instead of the number; for multiples of 5 output "Buzz"; for multiples of both 3 AND 5 output "FizzBuzz". Otherwise output the number itself. Write pseudocode using a FOR loop and a chain of IF/ELSEIF inside.

17HardCASE OF + OTHERWISE + Validation

A loyalty programme assigns a tier from a Points value (INTEGER): 0-99 = Bronze, 100-499 = Silver, 500-999 = Gold, 1000+ = Platinum. Negative points are invalid. Because Cambridge CASE OF cannot range-test, derive a CategoryCode (INTEGER 1-5) using IF/ELSEIF, then use CASE OF to print the tier. Use OTHERWISE to handle the invalid case.

18HardWHILE + Counter + Accumulator

A teacher knows there are exactly 25 students in a class. Using a WHILE loop with a Counter from 1 to 25, input each student's mark (INTEGER 0-100), accumulate the total, and at the end output the class average to 2 decimal places. Use REAL for the average.

19HardFOR / WHILE + Flag (Prime Check)

A number N (INTEGER >= 2) is prime if it has no whole-number divisor other than 1 and itself. Write pseudocode to input N and output "Prime" or "Not prime". Provide TWO valid approaches — one using a FOR loop with a Boolean flag (checks every divisor from 2 to N-1), and one using a WHILE loop with EARLY EXIT (stops as soon as a divisor is found).

20HardWHILE / DIV-MOD (Change Calculator)

A vending machine must return change of C pence (INTEGER) using the fewest coins. Available denominations: 50p, 20p, 10p, 5p, 2p, 1p. Write pseudocode to input C and output how many of EACH coin to dispense. Provide TWO valid approaches — one using a WHILE loop that subtracts each denomination in turn (greedy), and one using DIV and MOD to compute the counts arithmetically.

M3

Module 3

Working with Data — Arrays, Files & Subprograms

Where most AS Level marks live: 1D/2D arrays, traversal/search/sort, file I/O, procedures, functions and BYVAL/BYREF parameters.

1Easy1D Arrays (DECLARE)

A school stores the names of 30 students in a class. Write pseudocode to DECLARE a 1D array ClassList that uses indices 1 to 30 and holds STRING values.

2Easy2D Arrays (DECLARE)

A cinema has 8 rows (numbered 1 to 8) with 12 seats per row (numbered 1 to 12). Each seat stores "E" if empty or "O" if occupied. Write pseudocode to DECLARE a 2D array Seats with the appropriate dimensions and element type.

3EasyProcedures (PROCEDURE/CALL)

A greeting utility needs a PROCEDURE called Welcome that takes no parameters and outputs "Welcome to the system!". Write pseudocode to define the procedure and then CALL it from the main program.

4Medium1D Array Input/Output (FOR)

A teacher wants to input the marks of 5 students into a 1D array Marks (INTEGER, indices 1..5), then output each mark on its own line. Write pseudocode using two separate FOR loops — one for input, one for output.

5Medium2D Array Input/Output (Nested FOR)

A weather station records the daily temperature for 7 days across 4 weeks. Declare a 2D array Temps[1:4, 1:7] OF REAL. Use nested FOR loops to input every temperature, then use a second pair of nested FOR loops to output each week's temperatures on one line.

6MediumFUNCTION ... RETURNS

A geometry helper needs a function that takes the side length of a square (REAL) and RETURNS its area. Write pseudocode to define a FUNCTION SquareArea that takes one REAL parameter, computes side^2, and RETURNS the result. Then declare Side (REAL), input it, call SquareArea, and output the result.

7MediumProcedures with BYVAL Parameter

A billing system has a PROCEDURE PrintReceipt that takes the total amount (REAL) BYVAL and outputs a formatted receipt. Write pseudocode to define PrintReceipt, then declare Total : REAL, input it, and CALL PrintReceipt passing Total. After the CALL, output Total again to confirm BYVAL did NOT modify the original.

8MediumBYREF Parameter (Swap)

A sorting routine needs a PROCEDURE Swap that exchanges the values of two INTEGER variables using BYREF parameters. Write pseudocode to define Swap(X : INTEGER BYREF, Y : INTEGER BYREF), then declare A and B, input them, CALL Swap(A, B), and output them to confirm the values were exchanged.

9MediumLinear Search (1D Array)

A loyalty app stores 100 customer IDs (INTEGER) in a 1D array CustomerIDs[1:100]. Write pseudocode to input a Target ID, then perform a linear search to find the index of Target. Output the index if found, or "Not found" if Target is not in the array.

10MediumBubble Sort (Single Pass)

A teacher has 5 student marks in a 1D array Marks[1:5] OF INTEGER. Write pseudocode to perform ONE pass of bubble sort (compare each adjacent pair from index 1 to 4, swapping if out of order) and then output the array. Do NOT loop until sorted — just one pass.

11MediumFile Handling (OPENFILE/READFILE/EOF/CLOSEFILE)

A log file "sales.txt" contains an unknown number of sale amounts (REAL), one per line. Write pseudocode to OPENFILE for READ, then loop using WHILE NOT EOF("sales.txt") to READFILE each amount and OUTPUT it, and finally CLOSEFILE.

12MediumFile Handling (WRITEFILE/APPEND)

A registration system asks the user to input a new customer's name (STRING) and email (STRING), then APPENDs both as separate lines to an existing file "customers.txt". Write pseudocode to OPENFILE for APPEND, INPUT the two values, WRITEFILE each on its own line, then CLOSEFILE.

13HardMax/Min in Single Pass

A weather station has 365 daily temperatures (REAL) in array Temps[1:365]. Write pseudocode to find BOTH the highest and the lowest temperatures in a SINGLE pass through the array (one FOR loop), and output them with labels.

14HardTotalling + Average (REAL)

A class of 30 students has INTEGER marks in array Marks[1:30]. Write pseudocode to compute the sum (INTEGER) and the average (REAL, to 2 decimal places). Output both. Ensure that integer division is avoided when computing the average.

15HardBubble Sort (Full with Swapped Flag)

A leaderboard stores 8 player scores (INTEGER) in Scores[1:8]. Write pseudocode to fully sort the array in DESCENDING order (highest first) using bubble sort with a Swapped flag so the algorithm exits early once the array is sorted. Output the sorted array.

16Hard2D Array Totals (Rows vs Columns)

A shop has 4 branches (rows 1-4) and 7 days of sales (columns 1-7) in a 2D array Sales[1:4, 1:7] OF INTEGER. Write pseudocode to compute and output the total sales for EACH branch (row total), and the total sales for EACH day (column total). Use two separate nested-FOR accumulations.

17HardLinear Search Returning Index

A library stores 500 book titles (STRING) in Books[1:500]. Write pseudocode to input a Target title and perform a linear search. If found, output the index. If not found, output -1. Use a Found flag and break out of the loop early once the target is found.

18HardFUNCTION Returning Array Average

A statistics module needs a FUNCTION AverageOf that takes a 1D array of 20 INTEGER values and RETURNS the average as a REAL. Write the function definition, then declare an array Marks[1:20] OF INTEGER (assume populated), call AverageOf, and output the result to 2 decimals.

19HardPROCEDURE BYREF Array Parameter

A data-cleaning routine has a PROCEDURE DoubleAll that takes a 1D array of 10 INTEGERs BYREF and doubles every element in place. Write pseudocode to define DoubleAll, then declare an array Nums[1:10] OF INTEGER (assume populated), CALL DoubleAll(Nums), and output the array to confirm each value was doubled.

20HardBYVAL vs BYREF Demonstration

A demonstration has TWO procedures: IncrementByVal(BYVAL N : INTEGER) which adds 1 to N inside (no effect on caller), and IncrementByRef(BYREF N : INTEGER) which adds 1 to N inside (affects caller). Write pseudocode to declare Counter : INTEGER = 0, call IncrementByVal(Counter) and output Counter (still 0), then call IncrementByRef(Counter) and output Counter (now 1).

21HardFile Read + Count + Total

A file "rainfall.txt" contains an unknown number of daily rainfall measurements (REAL, in mm). Write pseudocode to OPENFILE for READ, loop until EOF, READFILE each value, count the days, accumulate the total rainfall, and finally CLOSEFILE and output both count and total to 2 decimals.

22HardFile Write from Array

A teacher has 25 student marks (INTEGER) in Marks[1:25]. Write pseudocode to OPENFILE "marks.txt" FOR WRITE, then use a FOR loop to WRITEFILE each mark on its own line, then CLOSEFILE. (Note: WRITE mode overwrites any existing file.)

23HardParallel Arrays (Top Scorer)

A game leaderboard stores 50 players' names (STRING) in Names[1:50] and their scores (INTEGER) in Scores[1:50] (the parallel arrays are aligned by index). Write pseudocode to find the player with the highest score and output their name and score. Handle ties by outputting the first player who achieved that score.

24Hard2D Array Diagonal Sum

A 4x4 matrix of INTEGERs is stored in Matrix[1:4, 1:4]. Write pseudocode to compute and output the sum of the MAIN diagonal (where row = column, i.e. Matrix[1,1] + Matrix[2,2] + Matrix[3,3] + Matrix[4,4]).

25HardSearch 2D Array (Seating Chart)

A theatre has 10 rows of 20 seats stored as SeatChart[1:10, 1:20] OF STRING where each cell is "E" (empty) or "O" (occupied). Write pseudocode to find the FIRST empty seat (scanning row by row, seat by seat from row 1 seat 1) and output its row and seat numbers. If no seat is empty, output "Sold out".

26HardFUNCTION Returning BOOLEAN (Sorted Check)

A data-validation module needs a FUNCTION IsSorted that takes a 1D array of 10 INTEGERs and RETURNS TRUE if the array is sorted in ASCENDING order (each element <= the next), FALSE otherwise. Write the function definition, then call it on an array Nums[1:10] and output "Sorted" or "Not sorted".

27HardPROCEDURE BYREF Array (Sort in Place)

A reusable utility needs a PROCEDURE SortAscending that takes a 1D array of 6 INTEGERs BYREF and sorts it in ascending order using bubble sort. Write pseudocode to define SortAscending, then declare an array Nums[1:6] OF INTEGER (assume populated), CALL SortAscending(Nums), and output the sorted array.

28HardFrequency Count (Two Approaches)

A teacher has 30 marks (INTEGER, range 0-100) in Marks[1:30]. The teacher wants to count how many students scored each mark from 0 to 100. Provide TWO valid approaches — one using a frequency array Freq[0:100] indexed directly by the mark value, and one using two parallel arrays (UniqueMark[1:101] and Count[1:101]) with a linear search to find or insert each mark.

29HardFile + Array (Sort and Rewrite, Two Approaches)

A file "nums.txt" contains up to 100 INTEGER values, one per line. Write pseudocode to read all values into an array, sort the array in ascending order, then write the sorted values back to the same file (overwriting it). Provide TWO valid approaches — one uses the SAME file for read and rewrite (close then reopen in WRITE mode); the other writes to a TEMPORARY file "sorted.txt" first, then could be renamed.

30Hard2D Array Cinema Booking (Two Approaches)

A cinema has 8 rows of 12 seats. Write pseudocode to declare a 2D array representing the seating, initialise every seat as available, then INPUT a row (1-8) and seat (1-12) and book that seat by marking it as occupied (output "Booked" or "Already taken"). Provide TWO valid approaches — one using a 2D array of STRING ("E"/"O"), one using a 2D array of BOOLEAN (TRUE = available).

M4

Module 4

Strings & Built-in Functions

The Cambridge built-in toolkit: LENGTH, MID, RIGHT, UCASE/LCASE, & concatenation, plus INT(x) for truncation and RAND(x) for random integers.

1EasyLENGTH( )

A website form asks a user to type a tweet (STRING). The site limits tweets to 280 characters. Write pseudocode to input the tweet and OUTPUT its character count using the LENGTH built-in.

2EasyConcatenation (&)

A login system stores a user's first name and last name in two separate STRING variables FirstName and LastName. Write pseudocode to declare a third STRING variable FullName and build it by joining FirstName, a single space, and LastName using the & operator. OUTPUT the result.

3MediumMID( )

A 7-character product code is stored in Code (STRING). The middle three characters (positions 3, 4 and 5) identify the product category. Write pseudocode to extract those three characters into a STRING variable Category using the MID built-in, and OUTPUT the category. (Cambridge MID takes the start position and the number of characters.)

4MediumRIGHT( )

A bank stores a customer's 16-digit card number as a STRING in CardNumber. For security, only the last 4 digits should be displayed on receipts. Write pseudocode to extract the last 4 characters into a STRING variable LastFour using the RIGHT built-in and OUTPUT them.

5MediumUCASE( ) / LCASE( )

A login form is case-insensitive for usernames: "Alice", "alice" and "ALICE" should all match the stored value "ALICE". Write pseudocode to INPUT a username (STRING), convert it to UPPER CASE using UCASE, and OUTPUT a welcome message showing the upper-cased username.

6MediumINT(x)

A shop prices items in dollars and cents but its receipt printer can only print whole-dollar amounts. Given Price : REAL already declared and assigned, write pseudocode to declare WholeDollars : INTEGER and use the INT built-in to truncate the price to a whole number. OUTPUT the result. (Note: INT truncates toward zero, so 9.99 becomes 9, not 10.)

7MediumRAND(x)

A board game needs to simulate a fair six-sided die. Cambridge's RAND(x) returns a random INTEGER from 0 to x-1 inclusive. Write pseudocode to roll the die and OUTPUT a value from 1 to 6.

8MediumLENGTH + IF (validation)

A phone number validator requires the user to enter exactly 10 digits. Write pseudocode to INPUT a phone number (STRING), check its length with LENGTH, and OUTPUT "Valid" if the length is 10 or "Invalid: must be 10 digits" otherwise.

9HardLENGTH + MID + UCASE (capitalise)

A name is stored in Name (STRING) with words separated by single spaces. Every word starts with a lower-case letter. Write pseudocode to build a new string in which the first letter of EVERY word is converted to UPPER CASE, and OUTPUT it. (Hint: capitalise position 1, then any character that follows a space.)

10HardMID + LENGTH (initials)

A full name is stored as "FirstName MiddleName LastName" in FullName (STRING) — three words separated by single spaces. Write pseudocode to extract the first letter of each word and build a string of initials separated by full stops, e.g. "John Robert Smith" → "J.R.S.". OUTPUT the result.

11HardRIGHT + UCASE (file extension)

A file-upload system accepts only text files with the extension ".txt" (case-insensitive — ".TXT", ".Txt" and ".txt" should all be accepted). Given FileName : STRING already declared and assigned, write pseudocode to extract the last 4 characters with RIGHT, convert them to UPPER CASE with UCASE, and OUTPUT "Accepted" if they equal ".TXT" or "Rejected" otherwise.

12HardLENGTH + MID (palindrome)

A palindrome is a word that reads the same forwards and backwards (e.g. "racecar"). Write pseudocode to INPUT a single word (STRING) and check whether it is a palindrome. OUTPUT "Palindrome" or "Not a palindrome". Use LENGTH and MID — do NOT reverse the string.

13HardINT + arithmetic (rounding)

A teacher has computed a class average as a REAL value in Average (e.g. 73.6). Cambridge's INT truncates toward zero, so INT(73.6) = 73, not 74. Write pseudocode to declare Rounded : INTEGER and round Average to the nearest whole number using INT and arithmetic only (no ROUND built-in). OUTPUT the result. (Hint: add 0.5 before truncating.)

14HardRAND + INT (lottery)

A lottery draws 6 unique numbers, each between 1 and 49 inclusive. Write pseudocode to fill an array Balls[1:6] of INTEGER with 6 unique random numbers (no repeats). OUTPUT each number on its own line. (Hint: before adding a new number, check it is not already in the array; if it is, draw again.)

15HardLENGTH + & (email builder)

A school assigns every student an email of the form: first initial + last name + "@school.edu" — all in LOWER CASE. Given FirstName and LastName (both STRING, already declared), write pseudocode to build Email and OUTPUT it. If LastName is longer than 10 characters, use only the first 10 characters of it (use MID).

16HardUCASE + MID (count vowels)

A sentence is stored in Sentence (STRING). Write pseudocode to count how many vowels (A, E, I, O, U) it contains. Output the count. Use MID to extract each character, UCASE to handle both cases, and a CASE OF to test the character.

17HardMID + & (Caesar shift)

A Caesar cipher with a shift of 1 turns "ABC" into "BCD" (every letter is replaced by the next one in the alphabet; "Z" wraps to "A"). A plaintext message is stored in PlainText (STRING, UPPER CASE letters only). Write pseudocode to build CipherText by shifting each character one position forward and OUTPUT the result.

18HardINT + DIV/MOD (time conversion)

A stopwatch records the total seconds elapsed as an INTEGER in TotalSeconds. Write pseudocode to convert this into hours, minutes and seconds (three INTEGER outputs). Use INT, DIV and MOD. OUTPUT in the form "Hh Mm Ss" (e.g. "1h 5m 12s" for 3912 seconds).

19HardLENGTH + MID + LCASE (snake_case → camelCase, Two Approaches)

A programmer stores variable names in snake_case (words separated by underscores, e.g. "user_first_name"). Write pseudocode to convert snake_case Snake (STRING) into camelCase and OUTPUT the result. Provide TWO valid approaches — Approach 1 scans character-by-character building the result; Approach 2 first removes underscores by replacing them with spaces, then capitalises the first letter of each word after the first.

20HardRAND + INT + IF (2-player dice game, Two Approaches)

Two players each roll a six-sided die three times. The player with the higher total wins; on a tie, output "Draw". Write pseudocode to play one round and OUTPUT the winner ("Player 1 wins", "Player 2 wins" or "Draw"). Provide TWO valid approaches — Approach 1 uses two parallel arrays Rolls1[1:3] and Rolls2[1:3] plus a FOR loop; Approach 2 uses scalar variables (Roll1_Total and Roll2_Total) and a REPEAT...UNTIL counter.

M5

Module 5

Abstract Data Types (Conceptual)

AS Level theory in action: Stacks (LIFO), Queues (FIFO) and Linked Lists — explained, traced and implemented with arrays.

1EasyStack — LIFO definition

Explain what is meant by a Stack data structure, state what the acronym LIFO stands for, and give ONE real-world analogy for it.

2MediumStack — Push operation trace

An empty stack S supports the PUSH and POP operations. Show the contents of S (top on the right) after each of these operations: PUSH(S, 10), PUSH(S, 20), PUSH(S, 30). Then state which value POP(S) would return if called next.

3MediumQueue — FIFO enqueue/dequeue

An empty queue Q supports the ENQUEUE and DEQUEUE operations. Show the contents of Q (front on the left) after each of these operations: ENQUEUE(Q, "A"), ENQUEUE(Q, "B"), ENQUEUE(Q, "C"), DEQUEUE(Q). State which value DEQUEUE removed and the final queue contents.

4MediumLinked list — node structure

A singly linked list is built from nodes. Each node has two fields. (a) Name the two fields and explain what each stores. (b) Explain what it means for the pointer field of the LAST node to be NULL. (c) State the name of the special pointer that identifies the start of the list.

5HardStack — Push/Pop/Peek trace

An empty stack S supports PUSH, POP and PEEK (PEEK returns the top value WITHOUT removing it). Trace the following sequence of operations and list the value returned by each POP and PEEK, and the final stack contents: PUSH(S, 5); PUSH(S, 8); POP(S); PUSH(S, 3); PEEK(S); POP(S); POP(S).

6HardQueue — Enqueue/Dequeue trace

An empty queue Q supports ENQUEUE and DEQUEUE. Trace the following operations and list the value returned by each DEQUEUE, and the final queue contents: ENQUEUE(Q, "A"); ENQUEUE(Q, "B"); DEQUEUE(Q); ENQUEUE(Q, "C"); ENQUEUE(Q, "D"); DEQUEUE(Q); DEQUEUE(Q). (Front of queue is shown on the left.)

7HardLinked list — pointer traversal

A singly linked list has HEAD pointing to the first node. The list contains three nodes: Node1 (Data=10, Next=Node2), Node2 (Data=20, Next=Node3), Node3 (Data=30, Next=NULL). Write pseudocode (using a pointer variable Current) to traverse the list from HEAD and OUTPUT every Data value. Then state what value Current holds when the traversal ends.

8HardStack — overflow and underflow

A stack is implemented using a fixed-size array of capacity 5. (a) Explain what is meant by "stack overflow" and give the condition that triggers it. (b) Explain what is meant by "stack underflow" and give the condition that triggers it. (c) State the value of the Top pointer in each case.

9HardStack — array implementation (Two Approaches)

A stack is implemented using a 1D array Stack[1:5] of INTEGER. Write pseudocode for a PUSH procedure that takes a value and adds it to the top of the stack. Provide TWO valid approaches — Approach 1 uses a Top pointer that starts at 0 (increment FIRST, then store); Approach 2 uses a Top pointer that starts at 1 (store FIRST, then increment). Both must reject overflow correctly.

10HardQueue — array implementation (Two Approaches)

A queue is implemented using a 1D array Queue[1:5] of INTEGER. Write pseudocode for a DEQUEUE procedure that removes and outputs the front item. Provide TWO valid approaches — Approach 1 uses a LINEAR queue: shift every remaining item one slot to the left after removing the front; Approach 2 uses a CIRCULAR queue with Front and Rear pointers that wrap around using MOD.

M6

Module 6

Exam Technique

The skills examiners actually test: tracing, designing from briefs, choosing test data, judging efficiency and commenting code.

1EasyComments (//)

The following pseudocode computes the area of a rectangle. Add a comment on EACH line using the Cambridge // single-line comment symbol to explain what that line does.

DECLARE Length, Width, Area : REAL
INPUT Length
INPUT Width
Area <- Length * Width
OUTPUT Area
2MediumTrace Table (FOR loop)

Complete the trace table for the following pseudocode. Show the values of I and Sum after each iteration of the FOR loop and the final OUTPUT.

DECLARE I, Sum : INTEGER
Sum <- 0
FOR I <- 1 TO 5
    Sum <- Sum + I
NEXT I
OUTPUT Sum
3MediumTest Data (normal / boundary / abnormal)

A program inputs a student's exam mark (INTEGER) and awards a grade. The valid range is 0 to 100 inclusive (marks below 0 or above 100 are invalid). Give ONE example of each of the following types of test data, with a brief reason: (a) normal data, (b) boundary data (give TWO boundary values), (c) abnormal data.

4MediumPseudocode from Design

A program is described as follows: "Input a number N. Then input N more numbers and output their total." Convert this design into Cambridge pseudocode. Use a FOR loop and an INTEGER variable Total to accumulate the sum.

5HardTrace Table (WHILE with sentinel)

The user enters these values in order: 10, 20, 30, -1. Complete the trace table showing Count and Total after each pass of the WHILE loop, and the final OUTPUT values.

DECLARE Value, Count, Total : INTEGER
Count <- 0
Total <- 0
OUTPUT "Enter a value (-1 to stop): "
INPUT Value
WHILE Value <> -1 DO
    Count <- Count + 1
    Total <- Total + Value
    OUTPUT "Enter a value (-1 to stop): "
    INPUT Value
ENDWHILE
OUTPUT "Count: ", Count
OUTPUT "Total: ", Total
6HardTest Data (triangle area validator)

A program inputs three REAL values representing the lengths of the sides of a triangle, then computes and outputs its area. Valid triangles have: all three sides positive (> 0), and the sum of any two sides greater than the third. Give ONE example of each type of test data and explain what each tests: (a) normal, (b) boundary (give TWO values), (c) abnormal (give TWO values).

7HardAlgorithm Efficiency (linear search vs bubble sort)

A student has written two algorithms for an array of n items: a LINEAR SEARCH (looks for a target by comparing each element one-by-one) and a BUBBLE SORT (repeatedly compares adjacent pairs and swaps them until no swaps are needed). (a) State the worst-case time complexity of each in big-O notation. (b) For an array of 1000 items, roughly how many comparisons does each make in the worst case? (c) State ONE situation in which each algorithm is preferred.

8HardPseudocode from Design (multi-step)

A program is described by the following steps: (1) Input the scores of 30 students into an array Scores. (2) Compute the class average. (3) Count how many students scored above the average. (4) Output the average and the count. Convert this design into Cambridge pseudocode. Use INTEGER arrays and a REAL average.

9HardConvert nested FOR to single WHILE (Two Approaches)

The following pseudocode uses NESTED FOR loops to print every ordered pair (R, C) for R = 1 to 2 and C = 1 to 3. Rewrite it using a SINGLE loop. Provide TWO valid approaches — Approach 1 keeps the nested structure but uses nested WHILE loops; Approach 2 uses a SINGLE WHILE loop with a counter K from 1 to 6 and computes R and C from K using DIV and MOD.

DECLARE R, C : INTEGER
FOR R <- 1 TO 2
    FOR C <- 1 TO 3
        OUTPUT R, ", ", C
    NEXT C
NEXT R
10HardTrace iterative factorial (Two Approaches)

The factorial of a non-negative integer n is n! = n * (n-1) * ... * 2 * 1, with 0! = 1. Write pseudocode to compute n! iteratively (no recursion). Provide TWO valid approaches — Approach 1 uses a FORWARD loop from 1 to n accumulating a product; Approach 2 uses a BACKWARD loop from n down to 1. For each, trace the values of the loop counter and the running product when n = 5.

Cambridge Exam Standard

Procedures & Functions

Subroutine Scenario Questions

25 full-length Cambridge AS Level (9618) exam-standard questions on procedures and functions. Each question presents a real-world scenario with a record type or 2D array declaration, a module description table, and sub-questions (a)/(b) — exactly as in the syllabus. For every sub-question, click Show Hints for progressive nudges or Show Pseudocode for the worked solution (step-by-step breakdown + complete pseudocode).

1HardSubroutines Scenario

Online Course Enrollment

An online learning platform is being developed to manage student enrollments in short courses. The platform offers up to 200 different courses. Each course has a unique 5-digit CourseID, a title, a maximum class size, and the current number of students enrolled.

Course IDs are assigned sequentially from 10001 upwards and never reused. The array is sorted in ascending order by CourseID. Rows in the array that are not currently in use have the CourseID set to 99999.

The programmer has defined a record type CourseType and a global array Courses to store the 200 course records. The programmer has also defined three program modules: FindCourse(), EnrollStudent() and DropStudent().

Record Type Definition

TYPE CourseType
    DECLARE CourseID : INTEGER
    DECLARE Title : STRING
    DECLARE MaxStudents : INTEGER
    DECLARE EnrolledCount : INTEGER
ENDTYPE

DECLARE Courses : ARRAY[1:200] OF CourseType

Program Modules

ModuleDescription
FindCourse()
• called with BYVAL parameter CourseID of type INTEGER
• uses a binary search on the Courses array, which is sorted in ascending order by CourseID
• returns the index of the matching course, or -1 if the CourseID is not found
EnrollStudent()
• called with BYVAL parameters CourseID of type INTEGER and StudentName of type STRING
• locates the course by calling FindCourse()
• if the course exists and EnrolledCount < MaxStudents, increments EnrolledCount and outputs a confirmation message
• if the course is full, outputs a "course full" message
• if the course is not found, outputs a "course not found" message
DropStudent()
• called with BYVAL parameter CourseID of type INTEGER
• locates the course by calling FindCourse()
• if found and EnrolledCount > 0, decrements EnrolledCount and outputs a confirmation
• otherwise outputs an appropriate message
(a)[8 marks]

Write efficient pseudocode for the module FindCourse(). [8]

(b)[7 marks]

Write efficient pseudocode for the module EnrollStudent(). [7]

2HardSubroutines Scenario

Hospital Patient Records

A hospital information system is being developed to manage patient admissions across multiple wards. The system stores records for up to 500 patients. Each patient record contains a unique PatientID (an INTEGER), the patient's full name, their age in years, the ward they are admitted to (a STRING such as "Cardiology"), and the date they were admitted.

Unused elements in the array have the PatientID set to 0. The records are not stored in any particular order, so any search must use a linear search.

The programmer has defined a record type PatientType and a global array Patients to store the 500 patient records. Two program modules are required: SearchPatient() returns a patient's name given their ID, and DischargePatient() outputs a discharge summary and frees the slot for reuse.

Record Type Definition

TYPE PatientType
    DECLARE PatientID : INTEGER
    DECLARE Name : STRING
    DECLARE Age : INTEGER
    DECLARE Ward : STRING
    DECLARE AdmittedDate : DATE
ENDTYPE

DECLARE Patients : ARRAY[1:500] OF PatientType

Program Modules

ModuleDescription
SearchPatient()
• called with BYVAL parameter PatientID of type INTEGER
• performs a linear search of the Patients array
• if found, returns the patient's Name as a STRING; otherwise returns "Not found"
DischargePatient()
• called with BYVAL parameter PatientID of type INTEGER
• locates the patient using a linear search
• if found, outputs a discharge summary showing Name, Ward and AdmittedDate, then sets PatientID to 0 to mark the slot as free for reuse
• if not found, outputs "Patient not found"
CountByWard()
• called with BYVAL parameter WardName of type STRING
• counts how many patients are currently in the specified ward
• outputs the count with a suitable message
(a)[7 marks]

Write pseudocode for the module SearchPatient(). [7]

(b)[8 marks]

Write pseudocode for the module DischargePatient(). [8]

3HardSubroutines Scenario

Warehouse Inventory

A warehouse inventory system is being developed to monitor stock levels for 200 different items. Rather than using a record type, the programmer has decided to use a 2D array Inventory of type INTEGER, with 200 rows and 4 columns. Column 1 holds the ItemID (a unique INTEGER), column 2 holds the current quantity in stock, column 3 holds the reorder level (the threshold at which more stock must be ordered), and column 4 holds the unit price in pence.

Rows that are not in use have the ItemID set to -1. The array is not sorted by ItemID.

The programmer has defined three program modules: CheckStock() reports all items below their reorder level, Restock() adds a quantity to a specific item, and CalculateValue() returns the total value of all stock in pence.

Array Declarations

DECLARE Inventory : ARRAY[1:200, 1:4] OF INTEGER
// Column 1 = ItemID, Column 2 = Quantity,
// Column 3 = ReorderLevel, Column 4 = UnitPrice (pence)
// Unused rows have Inventory[Row, 1] = -1

Program Modules

ModuleDescription
CheckStock()
• scans the Inventory array
• for every item whose Quantity (column 2) is less than its ReorderLevel (column 3), outputs the ItemID together with a "needs reorder" message
Restock()
• called with BYVAL parameters ItemID of type INTEGER and AddQty of type INTEGER
• searches the array for the given ItemID
• if found, adds AddQty to the Quantity in column 2 and outputs a confirmation message including the new total
• if not found, outputs "Item not found"
CalculateValue()
• sums (Quantity x UnitPrice) for every used row in the array
• returns the total value in pence as an INTEGER
(a)[8 marks]

Write pseudocode for the module CheckStock(). [8]

(b)[7 marks]

Write pseudocode for the module Restock(). [7]

4HardSubroutines Scenario

Hotel Booking System

A hotel booking system is being developed to manage 150 rooms across several floors. Each room has a unique RoomNumber (an INTEGER), a Type (a STRING such as "Single", "Double" or "Suite"), a nightly Price (a REAL), and an Occupied flag (a BOOLEAN indicating whether the room is currently occupied).

The system needs to support booking rooms by type, checking out (which frees the room and computes the bill), and reporting on availability. Unused slots have the Type set to "None".

The programmer has defined a record type RoomType and a global array Rooms of 150 elements. Two program modules are required: BookRoom() returns the room number of the first available room of a given type, and CheckoutRoom() frees the room and returns the total bill based on the number of nights.

Record Type Definition

TYPE RoomType
    DECLARE RoomNumber : INTEGER
    DECLARE Type : STRING
    DECLARE Price : REAL
    DECLARE Occupied : BOOLEAN
ENDTYPE

DECLARE Rooms : ARRAY[1:150] OF RoomType

Program Modules

ModuleDescription
BookRoom()
• called with BYVAL parameter RoomType of type STRING
• searches for the first available room (Occupied = FALSE) of the given type
• if found, marks it as Occupied and returns the RoomNumber as an INTEGER
• if no matching room is available, returns -1
CheckoutRoom()
• called with BYVAL parameters RoomNumber of type INTEGER and Nights of type INTEGER
• searches for the room with the given RoomNumber
• if found, marks Occupied as FALSE, calculates the bill as Nights x Price, outputs a bill summary and returns the bill total as a REAL
• if not found, outputs an error message and returns 0.0
AvailableCount()
• called with BYVAL parameter RoomType of type STRING
• counts the number of available rooms of the specified type
• returns the count as an INTEGER
(a)[7 marks]

Write pseudocode for the module BookRoom(). [7]

(b)[8 marks]

Write pseudocode for the module CheckoutRoom(). [8]

5HardSubroutines Scenario

School Grade Management

A school grade management system is being developed to track student performance across five subjects. The system stores records for 100 students. Each student record contains a unique StudentID (a STRING), the student's Name, an array of 5 subject Scores (each an INTEGER out of 100), and an Average field (a REAL).

Initially the Average field is set to 0.0; it must be computed by a module before it can be used. Unused elements in the Students array have the StudentID set to an empty string.

The programmer has defined a record type StudentType containing a nested array of scores, and a global array Students of 100 elements. Two program modules are required: CalculateAverage() populates the Average field for every student, and FindTopScorer() returns the name of the student with the highest average.

Record Type Definition

TYPE StudentType
    DECLARE StudentID : STRING
    DECLARE Name : STRING
    DECLARE Scores : ARRAY[1:5] OF INTEGER
    DECLARE Average : REAL
ENDTYPE

DECLARE Students : ARRAY[1:100] OF StudentType

Program Modules

ModuleDescription
CalculateAverage()
• for every student in the array whose StudentID is not an empty string
• computes the mean of the 5 scores
• stores the result in the Average field of the record
FindTopScorer()
• assumes CalculateAverage() has already been called
• searches the array for the student with the highest Average
• returns the Name of that student as a STRING
• if there are no students, returns "No students"
ListByGrade()
• called with BYVAL parameter Threshold of type REAL
• outputs the Name and Average of every student whose Average is greater than or equal to Threshold
• outputs a count of how many students matched
(a)[8 marks]

Write pseudocode for the module CalculateAverage(). [8]

(b)[7 marks]

Write pseudocode for the module FindTopScorer(). Assume CalculateAverage() has already been called. [7]

6HardSubroutines Scenario

Car Rental System

A car rental company is developing a fleet management system. The company owns 80 cars. Each car has a unique registration number (a STRING such as "AB12 CDE"), a Make (a STRING such as "Toyota" or "Ford"), a DailyRate (a REAL), and an Available flag (a BOOLEAN indicating whether the car is currently available for hire).

Unused slots in the array have the RegNumber set to "FREE". The array is not sorted.

The programmer has defined a record type CarType and a global array Cars of 80 elements. Two program modules are required: RentCar() finds and reserves the first available car of a given make, and ReturnCar() frees a car and computes the rental cost.

Record Type Definition

TYPE CarType
    DECLARE RegNumber : STRING
    DECLARE Make : STRING
    DECLARE DailyRate : REAL
    DECLARE Available : BOOLEAN
ENDTYPE

DECLARE Cars : ARRAY[1:80] OF CarType

Program Modules

ModuleDescription
RentCar()
• called with BYVAL parameter Make of type STRING
• searches for the first available car of the given make
• if found, marks it as unavailable (Available = FALSE), outputs a confirmation message and returns the RegNumber
• if no matching car is available, outputs a message and returns "None available"
ReturnCar()
• called with BYVAL parameters RegNumber of type STRING and Days of type INTEGER
• searches for the car with the given RegNumber
• if found, marks it as available (Available = TRUE), calculates the cost as Days x DailyRate, outputs a summary and returns the cost as a REAL
• if not found, outputs "Car not found" and returns 0.0
FleetReport()
• outputs the number of available cars
• outputs the total potential daily revenue (the sum of DailyRate for every available car)
(a)[7 marks]

Write pseudocode for the module RentCar(). [7]

(b)[8 marks]

Write pseudocode for the module ReturnCar(). [8]

7HardSubroutines Scenario

Restaurant Order Management

A restaurant order management system is being developed. The system stores up to 100 orders per day using a 2D INTEGER array Orders with 100 rows and 5 columns. Column 1 holds the OrderID (an INTEGER), column 2 holds the table number, and columns 3, 4 and 5 hold the item numbers of the three items ordered (each is an index into a separate prices array). If an order has fewer than 3 items, the unused columns contain 0.

The menu has 10 items, stored in a 1D REAL array Prices where Prices[I] is the price of menu item I. Unused rows in the Orders array have the OrderID set to 0.

The programmer has defined two program modules: CalculateBill() returns the total cost of a single order (or -1.0 if the order does not exist), and DailyRevenue() sums the totals of every order using CalculateBill().

Array Declarations

DECLARE Orders : ARRAY[1:100, 1:5] OF INTEGER
DECLARE Prices : ARRAY[1:10] OF REAL
// Orders columns: 1=OrderID, 2=TableNum, 3=Item1, 4=Item2, 5=Item3
// Prices[I] = price of menu item I (1..10)
// Unused rows have Orders[Row, 1] = 0
// Item columns contain 0 when no item is ordered in that slot

Program Modules

ModuleDescription
CalculateBill()
• called with BYVAL parameter OrderID of type INTEGER
• searches the Orders array for the given OrderID
• if found, sums the prices of the items in columns 3, 4 and 5 (skipping any 0 values) and returns the total as a REAL
• if not found, returns -1.0
FindOrder()
• called with BYVAL parameter OrderID of type INTEGER
• performs a linear search for the given OrderID
• if found, returns the table number (column 2) as an INTEGER; otherwise returns -1
DailyRevenue()
• sums the totals of every order in the array by calling CalculateBill()
• outputs the daily total revenue with a suitable message
(a)[8 marks]

Write pseudocode for the module CalculateBill(). [8]

(b)[7 marks]

Write pseudocode for the module DailyRevenue(). [7]

8HardSubroutines Scenario

Gym Membership System

A gym membership system is being developed for a chain of fitness centres. The system stores up to 1000 members. Each member has a unique MemberID (an INTEGER assigned sequentially from 50001 upwards), their Name, the JoinDate (a DATE), the MembershipType (a STRING such as "Basic", "Premium" or "VIP"), and an Active flag (a BOOLEAN indicating whether the membership is currently valid).

Unused elements in the array have the MemberID set to 0. The array is sorted in ascending order by MemberID, so the unused (0) slots sit at the start of the array and the valid IDs follow in order.

The programmer has defined a record type MemberType and a global array Members of 1000 elements. Two program modules are required: SearchMember() uses binary search to look up a member by ID, and CountActive() counts active members of a given membership type.

Record Type Definition

TYPE MemberType
    DECLARE MemberID : INTEGER
    DECLARE Name : STRING
    DECLARE JoinDate : DATE
    DECLARE MembershipType : STRING
    DECLARE Active : BOOLEAN
ENDTYPE

DECLARE Members : ARRAY[1:1000] OF MemberType

Program Modules

ModuleDescription
SearchMember()
• called with BYVAL parameter MemberID of type INTEGER
• uses a binary search on the Members array, which is sorted in ascending order by MemberID
• if found, returns the member's Name as a STRING; otherwise returns "Not found"
DeactivateMember()
• called with BYVAL parameter MemberID of type INTEGER
• locates the member using SearchMember() or an equivalent search
• if found, sets Active to FALSE and outputs a confirmation message including the member's name
• if not found, outputs "Member not found"
CountActive()
• called with BYVAL parameter MembershipType of type STRING
• counts how many members with the specified membership type are currently active
• returns the count as an INTEGER
(a)[7 marks]

Write efficient pseudocode for the module SearchMember(). [7]

(b)[8 marks]

Write pseudocode for the module CountActive(). [8]

9HardSubroutines Scenario

Bus Route Tracking

A bus company is developing a system to track passengers waiting at 50 bus stops along a route. The programmer has decided to use three parallel arrays, each with 50 elements, to store the data.

StopIDs[I] holds the unique INTEGER ID of stop I, StopNames[I] holds the stop name (a STRING), and PassengersWaiting[I] holds the number of passengers currently waiting at stop I. The arrays are sorted in ascending order by StopID. Unused slots have the StopID set to 99999, so they sit at the end of the sorted array.

When a bus arrives at a stop, up to BusCapacity passengers can board. Any passengers who cannot board remain waiting for the next bus.

The programmer has defined two program modules: FindStop() returns the name of a stop given its ID (using binary search), and BoardPassengers() handles a bus arriving at a stop.

Array Declarations

DECLARE StopIDs : ARRAY[1:50] OF INTEGER
DECLARE StopNames : ARRAY[1:50] OF STRING
DECLARE PassengersWaiting : ARRAY[1:50] OF INTEGER
// StopIDs is sorted in ascending order
// Unused slots have StopIDs[I] = 99999

Program Modules

ModuleDescription
FindStop()
• called with BYVAL parameter StopID of type INTEGER
• uses a binary search on the StopIDs array (which is sorted in ascending order)
• if found, returns the corresponding StopName as a STRING; otherwise returns "Unknown"
BoardPassengers()
• called with BYVAL parameters StopID of type INTEGER and BusCapacity of type INTEGER
• locates the stop using a binary search
• if found and PassengersWaiting > 0, calculates how many passengers board (the smaller of PassengersWaiting and BusCapacity), subtracts that number from PassengersWaiting, and outputs a message stating how many passengers boarded and how many remain
• if the stop is not found, outputs "Stop not found"
TotalPassengers()
• sums PassengersWaiting across all 50 stops
• returns the total as an INTEGER
(a)[8 marks]

Write efficient pseudocode for the module FindStop(). [8]

(b)[7 marks]

Write pseudocode for the module BoardPassengers(). [7]

10HardSubroutines Scenario

Employee Payroll System

A payroll system is being developed for a company with 300 employees. Each employee record contains a unique EmpID (an INTEGER), their Name, the HoursWorked this week (a REAL), their HourlyRate (a REAL), and their Department (a STRING such as "Sales" or "Engineering").

Unused elements in the array have the EmpID set to 0. The array is not sorted.

The company pays overtime at 1.5 times the normal hourly rate for any hours worked above 40 in a week.

The programmer has defined a record type EmployeeType and a global array Employees of 300 elements. Two program modules are required: CalculatePay() takes an employee record BYREF and returns the weekly pay (with overtime), and FindHighestEarner() returns the name of the employee with the highest pay.

Record Type Definition

TYPE EmployeeType
    DECLARE EmpID : INTEGER
    DECLARE Name : STRING
    DECLARE HoursWorked : REAL
    DECLARE HourlyRate : REAL
    DECLARE Department : STRING
ENDTYPE

DECLARE Employees : ARRAY[1:300] OF EmployeeType

Program Modules

ModuleDescription
CalculatePay()
• called with a BYREF parameter Emp of type EmployeeType
• computes the weekly pay for the given employee
• if HoursWorked <= 40, pay = HoursWorked x HourlyRate
• if HoursWorked > 40, pay = 40 x HourlyRate + (HoursWorked - 40) x HourlyRate x 1.5
• returns the pay as a REAL
SearchByDept()
• called with BYVAL parameter Department of type STRING
• for every employee in the array whose Department matches, calls CalculatePay() and outputs the employee's Name together with their computed pay
• outputs a count of how many employees were found in that department
FindHighestEarner()
• uses CalculatePay() to compute the pay for every employee
• returns the Name of the employee with the highest pay
• if there are no employees, returns "No employees"
(a)[8 marks]

Write pseudocode for the module CalculatePay(). [8]

(b)[7 marks]

Write pseudocode for the module FindHighestEarner(). [7]

11HardSubroutines Scenario

Bank Account Management

A retail bank is developing an account management system. The bank stores records for up to 5000 customer accounts. Each account record contains a unique AccountNumber (an INTEGER of 8 digits), the HolderName (a STRING), the current Balance (a REAL), the AccountType (a STRING such as "Current" or "Savings"), and an IsActive flag (a BOOLEAN indicating whether the account is open or closed).

The accounts are stored in a global array Accounts sorted in ascending order by AccountNumber. Rows that are not in use have the AccountNumber set to 99999999.

The programmer has defined a record type AccountRecord and two program modules: FindAccount() performs a binary search and returns the index of an account given its number, and TransferFunds() transfers money between two accounts, returning TRUE only if the transfer succeeds.

Record Type Definition

TYPE AccountRecord
    DECLARE AccountNumber : INTEGER
    DECLARE HolderName : STRING
    DECLARE Balance : REAL
    DECLARE AccountType : STRING
    DECLARE IsActive : BOOLEAN
ENDTYPE

DECLARE Accounts : ARRAY[1:5000] OF AccountRecord

Program Modules

ModuleDescription
FindAccount()
• called with BYVAL parameter AccountNumber of type INTEGER
• uses a binary search on the Accounts array, which is sorted in ascending order by AccountNumber
• returns the index of the matching account, or -1 if the AccountNumber is not found
TransferFunds()
• called with BYVAL parameters FromAcct, ToAcct (both INTEGER) and Amount (REAL)
• locates both accounts by calling FindAccount()
• returns FALSE if either account is missing, if either is inactive, or if FromAcct has insufficient funds
• otherwise deducts Amount from FromAcct, deposits it into ToAcct and returns TRUE
CloseAccount()
• called with BYVAL parameter AccountNumber of type INTEGER
• locates the account using FindAccount()
• if found and Balance = 0, sets IsActive to FALSE and outputs a confirmation
• otherwise outputs a suitable message
(a)[8 marks]

Write efficient pseudocode for the module FindAccount(). [8]

(b)[7 marks]

Write efficient pseudocode for the module TransferFunds(). [7]

12HardSubroutines Scenario

Movie Theater Seating

A movie theater is developing a seat reservation system. The theater has 10 rows of 20 seats each. The programmer has decided to use a 2D array Seating of type CHAR, with 10 rows and 20 columns. Each element is the character 'A' (Available) or 'B' (Booked).

Initially every seat is 'A'. When a customer requests NumSeats consecutive seats in a given Row, the system must find the first block of NumSeats consecutive available seats in that row and book them. If no such block exists, the booking fails.

The programmer has defined two program modules: CountAvailable() returns the total number of available seats in the theater, and BookSeats() attempts to book a block of consecutive seats in a given row, returning TRUE on success or FALSE on failure.

Array Declarations

DECLARE Seating : ARRAY[1:10, 1:20] OF CHAR
// 'A' = available, 'B' = booked
// Initially all elements are 'A'

Program Modules

ModuleDescription
CountAvailable()
• scans every element of the Seating array
• counts how many elements are equal to 'A'
• returns the count as an INTEGER
BookSeats()
• called with BYVAL parameters Row (INTEGER) and NumSeats (INTEGER)
• searches the specified row for the first block of NumSeats consecutive seats that are all 'A'
• if found, marks each seat in the block as 'B' and returns TRUE
• if no such block exists, returns FALSE
DisplaySeating()
• outputs a simple grid representation of the Seating array, row by row, with row numbers and seat numbers as headers
(a)[7 marks]

Write pseudocode for the module CountAvailable(). [7]

(b)[8 marks]

Write efficient pseudocode for the module BookSeats(). [8]

13HardSubroutines Scenario

Online Shopping Cart

An online shop is developing a product catalogue and shopping cart system. The shop sells up to 200 different products. Each product record contains a unique ProductID (an INTEGER), the product Name (a STRING), the Price (a REAL in pounds), and the current Stock level (an INTEGER).

The product array is not sorted by ProductID, so any lookup must use a linear search. Unused elements in the array have the ProductID set to 0.

The programmer has defined a record type ProductType and two program modules: AddToCart() searches for a product by ProductID, checks that there is stock available, decrements the stock and returns the price (or -1.0 if the product cannot be added); SearchByName() takes a substring and outputs the details of every product whose Name contains that substring.

Record Type Definition

TYPE ProductType
    DECLARE ProductID : INTEGER
    DECLARE Name : STRING
    DECLARE Price : REAL
    DECLARE Stock : INTEGER
ENDTYPE

DECLARE Products : ARRAY[1:200] OF ProductType

Program Modules

ModuleDescription
AddToCart()
• called with BYVAL parameter ProductID of type INTEGER
• performs a linear search for the product
• if found and Stock > 0, decrements Stock by 1 and returns the Price as a REAL
• if the product is not found or out of stock, returns -1.0
SearchByName()
• called with BYVAL parameter Substring of type STRING
• scans the Products array and outputs the ProductID, Name, Price and Stock of every product whose Name contains Substring (case-sensitive)
• outputs a count of how many matches were found
RestockProduct()
• called with BYVAL parameters ProductID and AddQty, both INTEGER
• locates the product, increments Stock by AddQty, outputs a confirmation including the new stock level
(a)[8 marks]

Write pseudocode for the module AddToCart(). [8]

(b)[7 marks]

Write pseudocode for the module SearchByName(). [7]

14HardSubroutines Scenario

University Course Registration

A university is developing a course registration system. The university offers up to 300 modules. Each module record contains a unique ModuleCode (a STRING such as "CS101"), a Title (a STRING), the Credit value (an INTEGER), the maximum Capacity (an INTEGER), and the current Enrolled count (an INTEGER, initially 0).

Unused elements in the array have the ModuleCode set to "NONE". The array is not sorted.

The programmer has defined a record type ModuleType and two program modules: RegisterStudent() attempts to enrol a student in a module by code, returning TRUE if the registration succeeds or FALSE if the module is not found or is full; ListAvailableModules() outputs the details of every module that still has spare capacity.

Record Type Definition

TYPE ModuleType
    DECLARE ModuleCode : STRING
    DECLARE Title : STRING
    DECLARE Credits : INTEGER
    DECLARE Capacity : INTEGER
    DECLARE Enrolled : INTEGER
ENDTYPE

DECLARE Modules : ARRAY[1:300] OF ModuleType

Program Modules

ModuleDescription
RegisterStudent()
• called with BYVAL parameter ModuleCode of type STRING
• performs a linear search for the module
• if found and Enrolled < Capacity, increments Enrolled and returns TRUE
• if the module is not found or is already full, returns FALSE
ListAvailableModules()
• scans the Modules array
• for every used module whose Enrolled < Capacity, outputs the ModuleCode, Title, Credits, and the number of remaining places (Capacity - Enrolled)
• outputs a count of how many modules still have places
WithdrawStudent()
• called with BYVAL parameter ModuleCode of type STRING
• locates the module; if found and Enrolled > 0, decrements Enrolled and outputs a confirmation
(a)[7 marks]

Write pseudocode for the module RegisterStudent(). [7]

(b)[8 marks]

Write pseudocode for the module ListAvailableModules(). [8]

15HardSubroutines Scenario

Pharmacy Prescription System

A pharmacy chain is developing a prescription tracking system. The system stores up to 2000 prescription records. Each prescription record contains a unique PrescriptionID (an INTEGER), the PatientName (a STRING), the MedicineName (a STRING), the Dosage instructions (a STRING such as "Take 2 daily"), the DateFilled (a DATE, set to the date the prescription was filled), and an IsCompleted flag (a BOOLEAN, initially FALSE).

Unused elements in the array have the PrescriptionID set to 0. The array is not sorted.

The programmer has defined a record type PrescriptionType and two program modules: FillPrescription() searches for a prescription by ID, marks it as completed, records today's date and outputs a confirmation; PendingCount() returns the number of prescriptions that have not yet been filled.

Record Type Definition

TYPE PrescriptionType
    DECLARE PrescriptionID : INTEGER
    DECLARE PatientName : STRING
    DECLARE MedicineName : STRING
    DECLARE Dosage : STRING
    DECLARE DateFilled : DATE
    DECLARE IsCompleted : BOOLEAN
ENDTYPE

DECLARE Prescriptions : ARRAY[1:2000] OF PrescriptionType

Program Modules

ModuleDescription
FillPrescription()
• called with BYVAL parameter PrescriptionID of type INTEGER
• performs a linear search for the prescription
• if found, sets IsCompleted to TRUE, sets DateFilled to TODAY, and outputs a confirmation message including the patient name and medicine
• if not found, outputs "Prescription not found"
PendingCount()
• scans the Prescriptions array
• counts how many used records have IsCompleted = FALSE
• returns the count as an INTEGER
SearchByPatient()
• called with BYVAL parameter PatientName of type STRING
• outputs the PrescriptionID and MedicineName of every prescription matching that patient
(a)[8 marks]

Write pseudocode for the module FillPrescription(). [8]

(b)[7 marks]

Write pseudocode for the module PendingCount(). [7]

16HardSubroutines Scenario

Sports Tournament Scoring

A sports league is developing a scoring system for a tournament involving 8 teams. Each team plays 5 matches during the tournament. The programmer has decided to use a 2D array Results of type INTEGER, with 8 rows (one per team) and 5 columns (one per match), storing the score in each match. A parallel 1D array TeamNames stores the 8 team names, indexed from 1 to 8.

Both arrays are 1-indexed and the data is fully populated — no sentinels are used.

The programmer has defined two program modules: FindWinner() computes each team's total score across the 5 matches and returns the name of the team with the highest total; MatchAverage() takes a match number (1 to 5) and returns the average score across all 8 teams for that match as a REAL.

Array Declarations

DECLARE Results : ARRAY[1:8, 1:5] OF INTEGER
DECLARE TeamNames : ARRAY[1:8] OF STRING
// Results[Team, Match] = the score team scored in that match
// TeamNames[Team] = the name of team with that index

Program Modules

ModuleDescription
FindWinner()
• for each of the 8 teams, sums the team's 5 match scores
• returns the Name of the team with the highest total
• in the case of a tie, the first team encountered wins
MatchAverage()
• called with BYVAL parameter MatchNum of type INTEGER
• takes a match number in the range 1 to 5
• sums the scores in column MatchNum across all 8 teams
• returns the average as a REAL
DisplayTable()
• outputs the Results array as a grid with row headers from TeamNames and column headers "Match 1" to "Match 5"
(a)[7 marks]

Write pseudocode for the module MatchAverage(). [7]

(b)[8 marks]

Write efficient pseudocode for the module FindWinner(). [8]

17HardSubroutines Scenario

Library Fine Calculation

A public library is developing a fine calculation system. The system stores up to 5000 loan records. Each loan record contains the BookID (a STRING), the MemberID (a STRING), the BorrowDate (a DATE), the DueDate (a DATE), the ReturnDate (a DATE, which may be in the future if not yet returned), and the FinePaid field (a REAL initialised to 0.0).

Unused elements in the array have the BookID set to "EMPTY". The array is not sorted.

The library charges a fine of 0.50 pounds per day for every day a book is returned late. The programmer has defined a record type LoanRecordType and two program modules: CalculateFine() takes a loan record BYREF, computes the fine if the book was returned after the DueDate, and updates the FinePaid field; OutstandingFines() returns the total of all fines currently owed across every loan in the array.

Record Type Definition

TYPE LoanRecordType
    DECLARE BookID : STRING
    DECLARE MemberID : STRING
    DECLARE BorrowDate : DATE
    DECLARE DueDate : DATE
    DECLARE ReturnDate : DATE
    DECLARE FinePaid : REAL
ENDTYPE

DECLARE Loans : ARRAY[1:5000] OF LoanRecordType

Program Modules

ModuleDescription
CalculateFine()
• called with a BYREF parameter Loan of type LoanRecordType
• if ReturnDate > DueDate, computes the fine as (ReturnDate - DueDate) * 0.50 and updates Loan.FinePaid
• if the book was returned on time, sets Loan.FinePaid to 0.0
OutstandingFines()
• scans the Loans array
• sums the FinePaid field of every used loan whose FinePaid is greater than 0
• returns the total as a REAL
PrintOverdueLoans()
• outputs the BookID, MemberID and FinePaid of every loan with a non-zero fine
(a)[8 marks]

Write pseudocode for the module CalculateFine(). [8]

(b)[7 marks]

Write pseudocode for the module OutstandingFines(). [7]

18HardSubroutines Scenario

Flight Booking System

An airline is developing a flight booking system. The system stores up to 1000 scheduled flights. Each flight record contains a unique FlightNumber (a STRING such as "BA123"), the Origin airport code (a STRING such as "LHR"), the Destination airport code (a STRING such as "JFK"), the DepartureTime (a STRING such as "14:30"), the AvailableSeats (an INTEGER), and the ticket Price (a REAL in pounds).

Unused elements in the array have the FlightNumber set to "NONE". The array is not sorted.

The programmer has defined a record type FlightType and two program modules: SearchFlight() takes an origin and a destination and outputs the details of every matching flight that still has seats; BookFlight() takes a flight number, decrements the available seats if any remain, and returns the ticket price (or -1.0 if the flight does not exist or is full).

Record Type Definition

TYPE FlightType
    DECLARE FlightNumber : STRING
    DECLARE Origin : STRING
    DECLARE Destination : STRING
    DECLARE DepartureTime : STRING
    DECLARE AvailableSeats : INTEGER
    DECLARE Price : REAL
ENDTYPE

DECLARE Flights : ARRAY[1:1000] OF FlightType

Program Modules

ModuleDescription
SearchFlight()
• called with BYVAL parameters Origin and Destination, both STRING
• scans the Flights array
• for every used flight whose Origin and Destination match AND whose AvailableSeats > 0, outputs the FlightNumber, DepartureTime, AvailableSeats and Price
• outputs a count of how many matching flights were found
BookFlight()
• called with BYVAL parameter FlightNumber of type STRING
• performs a linear search for the flight
• if found and AvailableSeats > 0, decrements AvailableSeats and returns the Price
• otherwise returns -1.0
CancelBooking()
• called with BYVAL parameter FlightNumber of type STRING
• locates the flight; if found, increments AvailableSeats and outputs a confirmation
(a)[7 marks]

Write pseudocode for the module SearchFlight(). [7]

(b)[8 marks]

Write efficient pseudocode for the module BookFlight(). [8]

19HardSubroutines Scenario

Supermarket Queue Simulation

A supermarket is developing a queue simulation for its 5 checkout lanes. Each lane can hold up to 10 customers. The programmer has decided to use a 2D array Checkout of type INTEGER, with 5 rows (one per lane) and 10 columns (one per slot in the queue). Each element stores a CustomerID (an INTEGER); an empty slot is represented by 0.

Initially every slot is 0. When a new customer arrives, the system assigns them to the lane with the fewest customers (the shortest queue). When a checkout finishes serving its front customer, all other customers in that lane shift forward by one position.

The programmer has defined two program modules: JoinShortestQueue() takes a CustomerID, finds the lane with the fewest customers, places the customer in the first empty slot of that lane, and returns the lane number; ProcessCustomer() takes a lane number, removes the customer at the front of that lane, and shifts everyone else forward.

Array Declarations

DECLARE Checkout : ARRAY[1:5, 1:10] OF INTEGER
// Checkout[Lane, Slot] = CustomerID, or 0 if empty
// Lane 1 = front-of-queue position 1; slot 1 is served first

Program Modules

ModuleDescription
JoinShortestQueue()
• called with BYVAL parameter CustomerID of type INTEGER
• counts the customers in each of the 5 lanes
• identifies the lane with the fewest customers (lowest index wins ties)
• places CustomerID in the first empty slot of that lane
• returns the lane number; if all lanes are full, returns -1
ProcessCustomer()
• called with BYVAL parameter LaneNum of type INTEGER
• removes the customer at slot 1 of that lane (the front of the queue)
• shifts every remaining customer forward by one slot
• sets the last slot to 0
• if the lane was already empty, outputs a "lane empty" message
DisplayLanes()
• outputs a simple text representation of every lane with its current customer IDs in order
(a)[8 marks]

Write efficient pseudocode for the module JoinShortestQueue(). [8]

(b)[7 marks]

Write pseudocode for the module ProcessCustomer(). [7]

20HardSubroutines Scenario

Vehicle Parking System

A multi-storey car park is developing a parking management system. The car park has 5 floors, each with 20 parking bays. The programmer has decided to use a 2D array ParkingLot of type STRING, with 5 rows (floors) and 20 columns (bays). Each element stores either a vehicle registration number (a STRING such as "AB12 CDE") or the literal "EMPTY".

Initially every bay is "EMPTY". When a vehicle arrives, the system allocates the first available bay (scanning floor 1 bay 1, floor 1 bay 2, ..., floor 5 bay 20) and returns the bay location as the string "Floor,Bay". When a vehicle leaves, the system searches for its registration and clears the bay.

The programmer has defined three program modules: ParkVehicle() allocates the first free bay; RemoveVehicle() searches for a registration and clears it; AvailableSpaces() returns the count of free bays.

Array Declarations

DECLARE ParkingLot : ARRAY[1:5, 1:20] OF STRING
// ParkingLot[Floor, Bay] = vehicle registration or "EMPTY"

Program Modules

ModuleDescription
ParkVehicle()
• called with BYVAL parameter RegNumber of type STRING
• scans the ParkingLot array in row-major order (floor 1 bay 1, floor 1 bay 2, ..., floor 5 bay 20)
• allocates the first bay that is "EMPTY" by storing RegNumber there
• returns the bay location as the STRING "Floor,Bay"
• if no bay is free, returns "FULL"
RemoveVehicle()
• called with BYVAL parameter RegNumber of type STRING
• performs a linear search for the registration
• if found, sets that bay to "EMPTY" and returns TRUE
• otherwise returns FALSE
AvailableSpaces()
• scans the ParkingLot array
• counts how many bays are equal to "EMPTY"
• returns the count as an INTEGER
(a)[7 marks]

Write efficient pseudocode for the module ParkVehicle(). [7]

(b)[8 marks]

Write efficient pseudocode for the module RemoveVehicle(). [8]

21HardSubroutines Scenario

Student Attendance System

A school is developing a student attendance tracking system. The system stores up to 3000 attendance records. Each record contains a StudentID (an INTEGER), the Date the attendance was recorded (a DATE), and the Status (a CHAR: 'P' = Present, 'A' = Absent, 'L' = Late).

Unused elements in the array have the StudentID set to 0. The array is not sorted, and a single student may have many attendance records across different dates.

The programmer has defined a record type AttendanceType and two program modules: MarkAttendance() takes a StudentID and a Status, reads today's date from the system clock, and appends a new attendance record to the first free slot in the array; AttendanceRate() takes a StudentID and returns the percentage of that student's records where Status = 'P', as a REAL in the range 0.0 to 100.0.

Record Type Definition

TYPE AttendanceType
    DECLARE StudentID : INTEGER
    DECLARE Date : DATE
    DECLARE Status : CHAR
ENDTYPE

DECLARE Attendance : ARRAY[1:3000] OF AttendanceType

Program Modules

ModuleDescription
MarkAttendance()
• called with BYVAL parameters StudentID (INTEGER) and Status (CHAR)
• searches the Attendance array for the first slot where StudentID = 0
• if found, sets the slot's StudentID, Date (to TODAY) and Status, and outputs a confirmation
• if no free slot is found, outputs "Attendance log full"
AttendanceRate()
• called with BYVAL parameter StudentID of type INTEGER
• counts the number of records for that student where Status = 'P'
• counts the total number of records for that student
• returns the percentage as a REAL (0.0 to 100.0)
• if the student has no records, returns 0.0
ListAbsences()
• called with BYVAL parameter StudentID of type INTEGER
• outputs the Date of every record for that student where Status = 'A'
(a)[8 marks]

Write pseudocode for the module MarkAttendance(). [8]

(b)[7 marks]

Write pseudocode for the module AttendanceRate(). [7]

22HardSubroutines Scenario

Online Survey System

A market research firm is developing a survey analysis system. The survey has 200 respondents, each of whom answered 10 questions on a 1-to-5 Likert scale. The programmer has decided to use a 2D array Survey of type INTEGER, with 200 rows (one per respondent) and 10 columns (one per question). Each element is an INTEGER in the range 1 to 5.

The data is fully populated — no sentinels are used.

The programmer has defined two program modules: CalculateAverage() takes a question number (1 to 10) and returns the average response for that question as a REAL; FindTopRespondent() sums each respondent's 10 answers and returns the index of the respondent with the highest total (in the case of a tie, the lowest-indexed respondent wins).

Array Declarations

DECLARE Survey : ARRAY[1:200, 1:10] OF INTEGER
// Survey[Respondent, Question] = answer in range 1..5

Program Modules

ModuleDescription
CalculateAverage()
• called with BYVAL parameter QuestionNum of type INTEGER
• validates that QuestionNum is in the range 1 to 10
• sums the answers in column QuestionNum across all 200 respondents
• returns the average as a REAL; returns -1.0 if QuestionNum is out of range
FindTopRespondent()
• for each of the 200 respondents, sums the 10 answers in that row
• returns the index (1 to 200) of the respondent with the highest total
• in the case of a tie, the lowest-indexed respondent wins
DisplaySummary()
• for each of the 10 questions, calls CalculateAverage() and outputs the question number with its average
(a)[7 marks]

Write pseudocode for the module CalculateAverage(). [7]

(b)[8 marks]

Write efficient pseudocode for the module FindTopRespondent(). [8]

23HardSubroutines Scenario

Pet Boarding Kennel

A pet boarding kennel is developing a booking system. The kennel can board up to 100 pets at a time. Each pet record contains a unique PetID (an INTEGER), the pet's Name (a STRING), the Species (a STRING such as "Dog" or "Cat"), the OwnerName (a STRING), the number of DaysBooked (an INTEGER, initially 0), and the DailyRate (a REAL in pounds).

Unused elements in the array have the PetID set to 0. The array is not sorted.

The programmer has defined a record type PetType and two program modules: CheckIn() searches for a pet by ID, sets the DaysBooked field, calculates the total boarding cost as DaysBooked * DailyRate, and outputs a confirmation; FindBySpecies() takes a species string and outputs the Name and OwnerName of every pet of that species currently booked in.

Record Type Definition

TYPE PetType
    DECLARE PetID : INTEGER
    DECLARE Name : STRING
    DECLARE Species : STRING
    DECLARE OwnerName : STRING
    DECLARE DaysBooked : INTEGER
    DECLARE DailyRate : REAL
ENDTYPE

DECLARE Pets : ARRAY[1:100] OF PetType

Program Modules

ModuleDescription
CheckIn()
• called with BYVAL parameters PetID (INTEGER) and DaysBooked (INTEGER)
• performs a linear search for the pet
• if found, sets the record's DaysBooked field, computes the total cost as DaysBooked * DailyRate, and outputs the pet's Name, the OwnerName, and the total cost
• if not found, outputs "Pet not found"
FindBySpecies()
• called with BYVAL parameter Species of type STRING
• scans the Pets array
• for every used record whose Species matches AND whose DaysBooked > 0, outputs the PetID, Name and OwnerName
• outputs a count of how many matches were found
CheckOut()
• called with BYVAL parameter PetID of type INTEGER
• locates the pet, outputs a final summary, then resets DaysBooked to 0
(a)[8 marks]

Write pseudocode for the module CheckIn(). [8]

(b)[7 marks]

Write pseudocode for the module FindBySpecies(). [7]

24HardSubroutines Scenario

Concert Ticket Sales

A concert venue is developing a ticket sales system. The venue has 500 seats. Each ticket record contains a unique SeatNumber (an INTEGER in the range 1 to 500), a Category (a CHAR: 'V' = VIP, 'G' = Gold, 'S' = Standard), the ticket Price (a REAL in pounds), and a Sold flag (a BOOLEAN, initially FALSE).

Unused elements in the array have the SeatNumber set to -1 (for seats that do not exist). The array is sorted in ascending order by SeatNumber, but the sort is irrelevant for this question.

The programmer has defined a record type TicketType and two program modules: SellTicket() takes a seat number, marks the ticket as sold if it is still available, and returns the price (or -1.0 if the seat does not exist or is already sold); RevenueByCategory() takes a category character and returns the total revenue from sold tickets in that category as a REAL.

Record Type Definition

TYPE TicketType
    DECLARE SeatNumber : INTEGER
    DECLARE Category : CHAR
    DECLARE Price : REAL
    DECLARE Sold : BOOLEAN
ENDTYPE

DECLARE Tickets : ARRAY[1:500] OF TicketType

Program Modules

ModuleDescription
SellTicket()
• called with BYVAL parameter SeatNumber of type INTEGER
• performs a linear search for the seat
• if found and Sold = FALSE, sets Sold to TRUE and returns the Price
• if the seat does not exist or is already sold, returns -1.0
RevenueByCategory()
• called with BYVAL parameter Category of type CHAR
• scans the Tickets array
• sums the Price of every ticket whose Category matches AND whose Sold = TRUE
• returns the total revenue as a REAL
AvailableCount()
• counts how many tickets have Sold = FALSE
• returns the count as an INTEGER
(a)[7 marks]

Write pseudocode for the module SellTicket(). [7]

(b)[8 marks]

Write efficient pseudocode for the module RevenueByCategory(). [8]

25HardSubroutines Scenario

Weather Data Analysis

A meteorological office is developing a weather data analysis system. The system records 4 daily readings (Temperature in Celsius, Humidity in percent, Rainfall in millimetres, WindSpeed in km/h) for each of 30 days in a month. The programmer has decided to use a 2D array WeatherData of type REAL, with 30 rows (one per day) and 4 columns: column 1 = Temperature, column 2 = Humidity, column 3 = Rainfall, column 4 = WindSpeed.

The data is fully populated — no sentinels are used.

The programmer has defined two program modules: FindHottestDay() scans the Temperature column (column 1) for the maximum value and returns the day number (1 to 30) on which it occurred; AverageRainfall() sums the Rainfall column (column 3) across all 30 days and returns the average daily rainfall as a REAL.

Array Declarations

DECLARE WeatherData : ARRAY[1:30, 1:4] OF REAL
// Column 1 = Temperature (degrees Celsius)
// Column 2 = Humidity (percent)
// Column 3 = Rainfall (mm)
// Column 4 = WindSpeed (km/h)

Program Modules

ModuleDescription
FindHottestDay()
• scans column 1 (Temperature) of the WeatherData array for the maximum value
• returns the day number (1 to 30) on which the maximum temperature occurred
• in the case of a tie, the earliest day wins
AverageRainfall()
• sums column 3 (Rainfall) of the WeatherData array across all 30 days
• divides by 30 to give the average daily rainfall
• returns the average as a REAL
DisplayReport()
• for each of the 30 days, outputs the day number with all four readings on a single line
(a)[8 marks]

Write efficient pseudocode for the module FindHottestDay(). [8]

(b)[7 marks]

Write pseudocode for the module AverageRainfall(). [7]