Loading....
|
Press & Hold to Drag Around |
|||
|
Click Here to Close |
|||
Question 1 Report
A UK postcode follows one of these formats (where A = letter, 9 = digit):
All postcodes have a space separating the outward and inward parts, and the inward part is always 9AA (digit then two letters).
(a) Write pseudocode for a function IsLetter that returns TRUE if a character is an uppercase letter. [2]
(b) Write pseudocode for a function IsDigit that returns TRUE if a character is a digit. [2]
(c) Write pseudocode for a function ValidateInward that checks the inward part (last 3 characters) follows the pattern: digit, letter, letter. [3]
(a) The IsLetter function checks whether a character falls within the range of uppercase letters 'A' to 'Z' by comparing its value against both boundaries. [2]
FUNCTION IsLetter(Ch : CHAR) RETURNS BOOLEAN
IF Ch >= 'A' AND Ch <= 'Z' THEN
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTIONCharacter comparisons work because characters are stored as numeric codes (e.g. ASCII), where 'A' through 'Z' are consecutive values 65 through 90. If Ch is greater than or equal to 'A' and less than or equal to 'Z', it must be an uppercase letter. Any character outside this range (digits, lowercase letters, punctuation, spaces) returns FALSE.
(b) The IsDigit function works on the same principle, checking whether a character falls within the range '0' to '9'. [2]
FUNCTION IsDigit(Ch : CHAR) RETURNS BOOLEAN
IF Ch >= '0' AND Ch <= '9' THEN
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTIONThe digit characters '0' through '9' occupy consecutive codes (ASCII 48-57). A character that is both >= '0' and <= '9' is guaranteed to be a digit.
(c) The ValidateInward function checks that the inward part of a UK postcode follows the required pattern: one digit followed by two letters (9AA). [3]
FUNCTION ValidateInward(Inward : STRING) RETURNS BOOLEAN
IF LENGTH(Inward) <> 3 THEN
RETURN FALSE
ENDIF
IF IsDigit(Inward[1]) AND IsLetter(Inward[2]) AND IsLetter(Inward[3]) THEN
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTIONThe function performs two checks:
(a) The IsLetter function checks whether a character falls within the range of uppercase letters 'A' to 'Z' by comparing its value against both boundaries. [2]
FUNCTION IsLetter(Ch : CHAR) RETURNS BOOLEAN
IF Ch >= 'A' AND Ch <= 'Z' THEN
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTIONCharacter comparisons work because characters are stored as numeric codes (e.g. ASCII), where 'A' through 'Z' are consecutive values 65 through 90. If Ch is greater than or equal to 'A' and less than or equal to 'Z', it must be an uppercase letter. Any character outside this range (digits, lowercase letters, punctuation, spaces) returns FALSE.
(b) The IsDigit function works on the same principle, checking whether a character falls within the range '0' to '9'. [2]
FUNCTION IsDigit(Ch : CHAR) RETURNS BOOLEAN
IF Ch >= '0' AND Ch <= '9' THEN
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTIONThe digit characters '0' through '9' occupy consecutive codes (ASCII 48-57). A character that is both >= '0' and <= '9' is guaranteed to be a digit.
(c) The ValidateInward function checks that the inward part of a UK postcode follows the required pattern: one digit followed by two letters (9AA). [3]
FUNCTION ValidateInward(Inward : STRING) RETURNS BOOLEAN
IF LENGTH(Inward) <> 3 THEN
RETURN FALSE
ENDIF
IF IsDigit(Inward[1]) AND IsLetter(Inward[2]) AND IsLetter(Inward[3]) THEN
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTIONThe function performs two checks:
Question 2 Report
A program needs to analyse a string entered by the user and count the number of uppercase letters, lowercase letters, digits and other characters.
(a) Write pseudocode for this algorithm. The program should output the count for each category. [5]
(b) Complete the table showing the expected output for the input "Ab3! xY". [3]
| Category | Count |
|---|---|
| Uppercase letters | |
| Lowercase letters | |
| Digits | |
| Other characters |
(a) The algorithm examines each character in the string and classifies it into one of four categories using ASCII range checks. The nested IF structure ensures each character is counted in exactly one category:
DECLARE Text : STRING
DECLARE UpperCount : INTEGER
DECLARE LowerCount : INTEGER
DECLARE DigitCount : INTEGER
DECLARE OtherCount : INTEGER
DECLARE i : INTEGER
DECLARE Ch : CHAR
INPUT Text
UpperCount <- 0
LowerCount <- 0
DigitCount <- 0
OtherCount <- 0
FOR i <- 1 TO LENGTH(Text)
Ch <- Text[i]
IF Ch >= 'A' AND Ch <= 'Z' THEN
UpperCount <- UpperCount + 1
ELSE
IF Ch >= 'a' AND Ch <= 'z' THEN
LowerCount <- LowerCount + 1
ELSE
IF Ch >= '0' AND Ch <= '9' THEN
DigitCount <- DigitCount + 1
ELSE
OtherCount <- OtherCount + 1
ENDIF
ENDIF
ENDIF
NEXT i
OUTPUT "Uppercase: ", UpperCount
OUTPUT "Lowercase: ", LowerCount
OUTPUT "Digits: ", DigitCount
OUTPUT "Other: ", OtherCountAll counters are initialised to 0 [1]. The loop iterates through each character [1]. The uppercase check uses 'A' to 'Z' [1]. Lowercase and digit checks are in the ELSE branches so no character is double-counted [1]. Everything that is not a letter or digit falls into "Other" [1]. [5]
(b) Analysing "Ab3! xY" character by character:
| Character | Category |
|---|---|
| A | Uppercase |
| b | Lowercase |
| 3 | Digit |
| ! | Other |
| (space) | Other |
| x | Lowercase |
| Y | Uppercase |
| Category | Count |
|---|---|
| Uppercase letters | 2 (A, Y) |
| Lowercase letters | 2 (b, x) |
| Digits | 1 (3) |
| Other characters | 2 (!, space) |
[3]
(a) The algorithm examines each character in the string and classifies it into one of four categories using ASCII range checks. The nested IF structure ensures each character is counted in exactly one category:
DECLARE Text : STRING
DECLARE UpperCount : INTEGER
DECLARE LowerCount : INTEGER
DECLARE DigitCount : INTEGER
DECLARE OtherCount : INTEGER
DECLARE i : INTEGER
DECLARE Ch : CHAR
INPUT Text
UpperCount <- 0
LowerCount <- 0
DigitCount <- 0
OtherCount <- 0
FOR i <- 1 TO LENGTH(Text)
Ch <- Text[i]
IF Ch >= 'A' AND Ch <= 'Z' THEN
UpperCount <- UpperCount + 1
ELSE
IF Ch >= 'a' AND Ch <= 'z' THEN
LowerCount <- LowerCount + 1
ELSE
IF Ch >= '0' AND Ch <= '9' THEN
DigitCount <- DigitCount + 1
ELSE
OtherCount <- OtherCount + 1
ENDIF
ENDIF
ENDIF
NEXT i
OUTPUT "Uppercase: ", UpperCount
OUTPUT "Lowercase: ", LowerCount
OUTPUT "Digits: ", DigitCount
OUTPUT "Other: ", OtherCountAll counters are initialised to 0 [1]. The loop iterates through each character [1]. The uppercase check uses 'A' to 'Z' [1]. Lowercase and digit checks are in the ELSE branches so no character is double-counted [1]. Everything that is not a letter or digit falls into "Other" [1]. [5]
(b) Analysing "Ab3! xY" character by character:
| Character | Category |
|---|---|
| A | Uppercase |
| b | Lowercase |
| 3 | Digit |
| ! | Other |
| (space) | Other |
| x | Lowercase |
| Y | Uppercase |
| Category | Count |
|---|---|
| Uppercase letters | 2 (A, Y) |
| Lowercase letters | 2 (b, x) |
| Digits | 1 (3) |
| Other characters | 2 (!, space) |
[3]
Question 3 Report
Binary shifts move all bits left or right by a specified number of positions.
(a) Perform each shift operation on the 8-bit binary number and state the result. [4]
| Original (denary) | Original (binary) | Shift | Result (binary) | Result (denary) |
|---|---|---|---|---|
| 12 | 00001100 | Left shift by 1 | ||
| 12 | 00001100 | Left shift by 2 | ||
| 12 | 00001100 | Right shift by 1 | ||
| 12 | 00001100 | Right shift by 2 |
(b) State the effect of a left shift by 1 on the denary value. [1]
(c) State the effect of a right shift by 1 on the denary value. [1]
(d) Explain what happens to the denary value when you left-shift the binary number 10000000 by 1 in an 8-bit system. [2]
(e) State the relationship between a left shift by N positions and multiplication. [2]
(f) Convert the denary number 156 to binary. Show your working. [2]
(g) Convert the binary number 11010110 to hexadecimal. Show your working. [2]
(h) Perform binary addition of 01101011 and 00110101. Show the carry row and identify whether overflow has occurred. [3]
(i) Explain why hexadecimal is used as a shorthand for binary in computing. [2]
(j) Convert the hexadecimal values 3F, A2 and 1B to denary. Show your working for each. [1]
(a) Binary shift operations on 00001100 (denary 12). [4]
| Original (denary) | Original (binary) | Shift | Result (binary) | Result (denary) |
|---|---|---|---|---|
| 12 | 00001100 | Left shift by 1 | 00011000 | 24 |
| 12 | 00001100 | Left shift by 2 | 00110000 | 48 |
| 12 | 00001100 | Right shift by 1 | 00000110 | 6 |
| 12 | 00001100 | Right shift by 2 | 00000011 | 3 |
Left shifts move bits towards the most significant end and fill vacated positions with 0. Right shifts move bits towards the least significant end, discarding bits that fall off the right.
(b) A left shift by 1 doubles (multiplies by 2) the denary value: 12 becomes 24. [1]
(c) A right shift by 1 halves (integer division by 2) the denary value: 12 becomes 6. [1] Any fractional part is lost.
(d) Left-shifting 10000000 by 1 pushes the leading 1 beyond the 8-bit boundary. [2] The result is 00000000 (denary 0). The original value (128) is lost because the only set bit has been shifted out of the available storage. This is a form of overflow.
(e) A left shift by N positions is equivalent to multiplying the number by \(2^N\). [2] For example, left shift by 3 multiplies by \(2^3 = 8\). Similarly, a right shift by N divides by \(2^N\) (with truncation).
(f) Converting 156 to binary by repeated division by 2: [2]
| Division | Quotient | Remainder |
|---|---|---|
| 156 / 2 | 78 | 0 |
| 78 / 2 | 39 | 0 |
| 39 / 2 | 19 | 1 |
| 19 / 2 | 9 | 1 |
| 9 / 2 | 4 | 1 |
| 4 / 2 | 2 | 0 |
| 2 / 2 | 1 | 0 |
| 1 / 2 | 0 | 1 |
Reading remainders from bottom to top: 10011100.
(g) Converting 11010110 to hexadecimal: [2]
Split into nibbles: 1101 and 0110.
Hexadecimal: D6.
(h) Binary addition of 01101011 + 00110101: [3]
Carry: 0 1 1 1 1 1 0 0
0 1 1 0 1 0 1 1
+ 0 0 1 1 0 1 0 1
------------------
1 0 1 0 0 0 0 0Result: 10100000. Denary check: 107 + 53 = 160, and 10100000 = 128+32 = 160. No overflow has occurred because both operands are positive (MSB = 0) and the result (160) fits within an 8-bit unsigned range (0-255).
(i) Hexadecimal is used as shorthand for binary because each hex digit represents exactly 4 binary bits. [2] This makes conversion trivial and reduces long binary strings to a much shorter, more readable form. For example, the 8-bit binary 11111111 becomes simply FF, which is easier for programmers to read and less error-prone to transcribe.
(j) Hex to denary conversions: [1]
(a) Binary shift operations on 00001100 (denary 12). [4]
| Original (denary) | Original (binary) | Shift | Result (binary) | Result (denary) |
|---|---|---|---|---|
| 12 | 00001100 | Left shift by 1 | 00011000 | 24 |
| 12 | 00001100 | Left shift by 2 | 00110000 | 48 |
| 12 | 00001100 | Right shift by 1 | 00000110 | 6 |
| 12 | 00001100 | Right shift by 2 | 00000011 | 3 |
Left shifts move bits towards the most significant end and fill vacated positions with 0. Right shifts move bits towards the least significant end, discarding bits that fall off the right.
(b) A left shift by 1 doubles (multiplies by 2) the denary value: 12 becomes 24. [1]
(c) A right shift by 1 halves (integer division by 2) the denary value: 12 becomes 6. [1] Any fractional part is lost.
(d) Left-shifting 10000000 by 1 pushes the leading 1 beyond the 8-bit boundary. [2] The result is 00000000 (denary 0). The original value (128) is lost because the only set bit has been shifted out of the available storage. This is a form of overflow.
(e) A left shift by N positions is equivalent to multiplying the number by \(2^N\). [2] For example, left shift by 3 multiplies by \(2^3 = 8\). Similarly, a right shift by N divides by \(2^N\) (with truncation).
(f) Converting 156 to binary by repeated division by 2: [2]
| Division | Quotient | Remainder |
|---|---|---|
| 156 / 2 | 78 | 0 |
| 78 / 2 | 39 | 0 |
| 39 / 2 | 19 | 1 |
| 19 / 2 | 9 | 1 |
| 9 / 2 | 4 | 1 |
| 4 / 2 | 2 | 0 |
| 2 / 2 | 1 | 0 |
| 1 / 2 | 0 | 1 |
Reading remainders from bottom to top: 10011100.
(g) Converting 11010110 to hexadecimal: [2]
Split into nibbles: 1101 and 0110.
Hexadecimal: D6.
(h) Binary addition of 01101011 + 00110101: [3]
Carry: 0 1 1 1 1 1 0 0
0 1 1 0 1 0 1 1
+ 0 0 1 1 0 1 0 1
------------------
1 0 1 0 0 0 0 0Result: 10100000. Denary check: 107 + 53 = 160, and 10100000 = 128+32 = 160. No overflow has occurred because both operands are positive (MSB = 0) and the result (160) fits within an 8-bit unsigned range (0-255).
(i) Hexadecimal is used as shorthand for binary because each hex digit represents exactly 4 binary bits. [2] This makes conversion trivial and reduces long binary strings to a much shorter, more readable form. For example, the 8-bit binary 11111111 becomes simply FF, which is easier for programmers to read and less error-prone to transcribe.
(j) Hex to denary conversions: [1]
Question 4 Report
A program needs to extract and process numeric data from formatted strings.
(a) Write pseudocode for a function ExtractNumber that takes a string like "Price: 45" and returns the numeric value (45 as an integer). The function should find the first digit and extract all consecutive digits from that point. [4]
(b) State the return value for each input. [2]
| Input | Return value |
|---|---|
| "Score: 95 points" | |
| "Room 204" |
(c) Explain the difference between the string "123" and the integer 123. [2]
(a) The ExtractNumber function scans through a string character by character, collecting consecutive digit characters once the first digit is found, then converting the collected digits to an integer.
FUNCTION ExtractNumber(Text : STRING) RETURNS INTEGER
DECLARE NumStr : STRING
DECLARE i : INTEGER
DECLARE Ch : CHAR
DECLARE InNumber : BOOLEAN
NumStr ← ""
InNumber ← FALSE
FOR i ← 1 TO LENGTH(Text)
Ch ← Text[i]
IF Ch >= '0' AND Ch <= '9' THEN
NumStr ← NumStr & Ch
InNumber ← TRUE
ELSE
IF InNumber = TRUE THEN
RETURN INT(STR_TO_NUM(NumStr))
ENDIF
ENDIF
NEXT i
IF NumStr <> "" THEN
RETURN INT(STR_TO_NUM(NumStr))
ENDIF
RETURN 0
ENDFUNCTIONKey logic: the function skips all non-digit characters until the first digit is found. [1] Once digits begin, it collects them into NumStr. [1] When a non-digit is encountered after digits have started, the collected string is converted to a number and returned. [1] If the number is at the end of the string, the post-loop check handles it. [1]
(b)
| Input | Return value |
|---|---|
| "Score: 95 points" | 95 |
| "Room 204" | 204 |
For "Score: 95 points": the function skips non-digits, then finds '9','5', then encounters ' ', so it returns 95. [1]
For "Room 204": the function skips non-digits, then finds '2','0','4'. The post-loop check returns 204. [1]
(c) The string "123" is a sequence of three characters ('1', '2', '3') stored as text data. It cannot be used directly in arithmetic operations. [1] The integer 123 is a single numeric value stored in binary format that can be used directly in calculations such as addition and multiplication. To perform arithmetic on the string, it must first be converted using a function like STR_TO_NUM. [1]
(a) The ExtractNumber function scans through a string character by character, collecting consecutive digit characters once the first digit is found, then converting the collected digits to an integer.
FUNCTION ExtractNumber(Text : STRING) RETURNS INTEGER
DECLARE NumStr : STRING
DECLARE i : INTEGER
DECLARE Ch : CHAR
DECLARE InNumber : BOOLEAN
NumStr ← ""
InNumber ← FALSE
FOR i ← 1 TO LENGTH(Text)
Ch ← Text[i]
IF Ch >= '0' AND Ch <= '9' THEN
NumStr ← NumStr & Ch
InNumber ← TRUE
ELSE
IF InNumber = TRUE THEN
RETURN INT(STR_TO_NUM(NumStr))
ENDIF
ENDIF
NEXT i
IF NumStr <> "" THEN
RETURN INT(STR_TO_NUM(NumStr))
ENDIF
RETURN 0
ENDFUNCTIONKey logic: the function skips all non-digit characters until the first digit is found. [1] Once digits begin, it collects them into NumStr. [1] When a non-digit is encountered after digits have started, the collected string is converted to a number and returned. [1] If the number is at the end of the string, the post-loop check handles it. [1]
(b)
| Input | Return value |
|---|---|
| "Score: 95 points" | 95 |
| "Room 204" | 204 |
For "Score: 95 points": the function skips non-digits, then finds '9','5', then encounters ' ', so it returns 95. [1]
For "Room 204": the function skips non-digits, then finds '2','0','4'. The post-loop check returns 204. [1]
(c) The string "123" is a sequence of three characters ('1', '2', '3') stored as text data. It cannot be used directly in arithmetic operations. [1] The integer 123 is a single numeric value stored in binary format that can be used directly in calculations such as addition and multiplication. To perform arithmetic on the string, it must first be converted using a function like STR_TO_NUM. [1]
Question 5 Report
A system transmits ASCII characters using 7 data bits plus 1 even parity bit (8 bits total). The parity bit is the most significant (leftmost) bit.
(a) The ASCII codes for the characters A, B, C are 1000001, 1000010, 1000011. Add the even parity bit to each and show the complete 8-bit code. [3]
| Character | ASCII (7 bits) | Number of 1s | Parity bit | Complete byte |
|---|---|---|---|---|
| A | 1000001 | |||
| B | 1000010 | |||
| C | 1000011 |
(a) Adding even parity bits to ASCII codes (parity bit is the leftmost bit): [3]
| Character | ASCII (7 bits) | Number of 1s | Parity bit | Complete byte |
|---|---|---|---|---|
| A | 1000001 | 2 (even) | 0 | 01000001 |
| B | 1000010 | 2 (even) | 0 | 01000010 |
| C | 1000011 | 3 (odd) | 1 | 11000011 |
[1] for A (parity 0, byte 01000001), [1] for B (parity 0, byte 01000010), [1] for C (parity 1, byte 11000011).
For even parity, the total number of 1s in the complete 8-bit byte (including the parity bit) must be even. Characters A and B each have two 1s in their ASCII codes (already even), so the parity bit is 0. Character C has three 1s (odd), so the parity bit must be 1 to bring the total to four (even).
(a) Adding even parity bits to ASCII codes (parity bit is the leftmost bit): [3]
| Character | ASCII (7 bits) | Number of 1s | Parity bit | Complete byte |
|---|---|---|---|---|
| A | 1000001 | 2 (even) | 0 | 01000001 |
| B | 1000010 | 2 (even) | 0 | 01000010 |
| C | 1000011 | 3 (odd) | 1 | 11000011 |
[1] for A (parity 0, byte 01000001), [1] for B (parity 0, byte 01000010), [1] for C (parity 1, byte 11000011).
For even parity, the total number of 1s in the complete 8-bit byte (including the parity bit) must be even. Characters A and B each have two 1s in their ASCII codes (already even), so the parity bit is 0. Character C has three 1s (odd), so the parity bit must be 1 to bring the total to four (even).
Question 6 Report
A class of 10 students has taken a test. Their marks are stored in an array Marks[1:10].
DECLARE Marks : ARRAY[1:10] OF INTEGER
Marks ← {72, 85, 63, 91, 45, 78, 56, 88, 70, 65}(a) Write pseudocode to calculate and output the mean (average) mark. [3]
(a) To find the mean, sum all elements using a FOR loop and divide by the count: [3]
DECLARE Total : INTEGER
DECLARE Mean : REAL
DECLARE i : INTEGER
Total ← 0
FOR i ← 1 TO 10
Total ← Total + Marks[i]
NEXT i
Mean ← Total / 10
OUTPUT "Mean mark: ", MeanThe marks are {72, 85, 63, 91, 45, 78, 56, 88, 70, 65}. Their sum is 72 + 85 + 63 + 91 + 45 + 78 + 56 + 88 + 70 + 65 = 713. The mean is 713 / 10 = 71.3. [1 mark for loop summing, 1 mark for division by 10, 1 mark for output]
(a) To find the mean, sum all elements using a FOR loop and divide by the count: [3]
DECLARE Total : INTEGER
DECLARE Mean : REAL
DECLARE i : INTEGER
Total ← 0
FOR i ← 1 TO 10
Total ← Total + Marks[i]
NEXT i
Mean ← Total / 10
OUTPUT "Mean mark: ", MeanThe marks are {72, 85, 63, 91, 45, 78, 56, 88, 70, 65}. Their sum is 72 + 85 + 63 + 91 + 45 + 78 + 56 + 88 + 70 + 65 = 713. The mean is 713 / 10 = 71.3. [1 mark for loop summing, 1 mark for division by 10, 1 mark for output]
Question 7 Report
The diagram below shows the stages of translating and running a high-level program.
(a) State what is meant by "source code". [1]
(a) "Source code" is the program written by the programmer in a high-level (or assembly) language before it is translated. [1]
It is the human-readable form of the program, containing keywords, variable names, and structures that make sense to the programmer. The source code must be translated by a compiler, interpreter, or assembler into machine code (object code) before the CPU can execute it. The diagram shows this translation pipeline: Source code -> Translator -> Object code (machine code) -> CPU.
(a) "Source code" is the program written by the programmer in a high-level (or assembly) language before it is translated. [1]
It is the human-readable form of the program, containing keywords, variable names, and structures that make sense to the programmer. The source code must be translated by a compiler, interpreter, or assembler into machine code (object code) before the CPU can execute it. The diagram shows this translation pipeline: Source code -> Translator -> Object code (machine code) -> CPU.
Question 8 Report
The flowchart below shows an algorithm that searches an array of 5 elements for a target value.
The array Data contains: [12, 7, 25, 3, 18]
(a) State the type of search shown in this flowchart. [1]
(b) State the output if the Target is 25. [1]
(c) Explain why this flowchart uses a WHILE-style loop rather than a simple FOR loop. [2]
(a) The flowchart shows a linear search. [1]
A linear search checks each element of an array one by one, starting from the first element and moving sequentially through the array until the target value is found or the end of the array is reached.
(b) If the Target is 25: [1]
The search starts at Index 1. Data[1]=12, not 25. Index becomes 2. Data[2]=7, not 25. Index becomes 3. Data[3]=25, which equals the Target. Found is set to TRUE. The loop exits because Found = TRUE. The final decision box checks Found = TRUE, which is true, so the algorithm outputs that the item was found at position 3.
(c) Why the flowchart uses a WHILE-style loop rather than a simple FOR loop: [2]
The WHILE-style loop has two conditions: Index <= 5 AND Found = FALSE. This allows the search to stop early as soon as the target is found. [1] When Found becomes TRUE, the loop condition fails and the algorithm exits immediately without checking the remaining elements.
A simple FOR loop would continue iterating through all remaining elements even after the target has been located. [1] For an array of 5 elements this is a minor inefficiency, but for large arrays with thousands of elements, stopping early when the target is near the beginning saves significant processing time. The WHILE-style loop is therefore more efficient on average.
(a) The flowchart shows a linear search. [1]
A linear search checks each element of an array one by one, starting from the first element and moving sequentially through the array until the target value is found or the end of the array is reached.
(b) If the Target is 25: [1]
The search starts at Index 1. Data[1]=12, not 25. Index becomes 2. Data[2]=7, not 25. Index becomes 3. Data[3]=25, which equals the Target. Found is set to TRUE. The loop exits because Found = TRUE. The final decision box checks Found = TRUE, which is true, so the algorithm outputs that the item was found at position 3.
(c) Why the flowchart uses a WHILE-style loop rather than a simple FOR loop: [2]
The WHILE-style loop has two conditions: Index <= 5 AND Found = FALSE. This allows the search to stop early as soon as the target is found. [1] When Found becomes TRUE, the loop condition fails and the algorithm exits immediately without checking the remaining elements.
A simple FOR loop would continue iterating through all remaining elements even after the target has been located. [1] For an array of 5 elements this is a minor inefficiency, but for large arrays with thousands of elements, stopping early when the target is near the beginning saves significant processing time. The WHILE-style loop is therefore more efficient on average.
Question 9 Report
A shop records the prices of items sold during a day. The shopkeeper enters prices one at a time, using -1 to indicate the end of input.
(a) Write pseudocode to calculate and output: the total sales, the number of items sold, the average price per item, the most expensive item sold, and the cheapest item sold. [6]
(b) State what the initial value of a variable used to track the "most expensive" item should be. Explain your choice. [2]
(c) Explain why the program should check that at least one item was entered before calculating the average. [2]
(d) Describe the difference between a WHILE loop and a REPEAT...UNTIL loop. [2]
(a) The algorithm uses a sentinel (-1) to end input, tracks the total, count, max, and min. The first valid item initialises both max and min trackers: [6]
DECLARE Price : REAL
DECLARE Total : REAL
DECLARE Count : INTEGER
DECLARE Average : REAL
DECLARE MaxPrice : REAL
DECLARE MinPrice : REAL
Total ← 0
Count ← 0
OUTPUT "Enter price (-1 to finish): "
INPUT Price
IF Price <> -1 THEN
MaxPrice ← Price
MinPrice ← Price
ENDIF
WHILE Price <> -1 DO
Total ← Total + Price
Count ← Count + 1
IF Price > MaxPrice THEN
MaxPrice ← Price
ENDIF
IF Price < MinPrice THEN
MinPrice ← Price
ENDIF
OUTPUT "Enter price (-1 to finish): "
INPUT Price
ENDWHILE
OUTPUT "Total sales: ", Total
OUTPUT "Items sold: ", Count
IF Count > 0 THEN
Average ← Total / Count
OUTPUT "Average price: ", Average
OUTPUT "Most expensive: ", MaxPrice
OUTPUT "Cheapest: ", MinPrice
ELSE
OUTPUT "No items entered"
ENDIF[1 mark for sentinel loop, 1 mark for totalling, 1 mark for counting, 1 mark for max tracking, 1 mark for min tracking with correct initialisation, 1 mark for average with zero check]
(b) The initial value for the maximum tracker should be the first valid item entered, not 0 or an arbitrary large/small number. [1] Initialising with the first actual data value ensures accurate tracking regardless of the data range. If set to 0 and all prices are positive, 0 would never be replaced as the minimum unless the code explicitly handles it. [1]
(c) If no items are entered (Count = 0), calculating the average would require dividing Total by 0. [1] This division by zero would cause a runtime error and crash the program. The check allows the program to display an informative message instead. [1]
(d) A WHILE loop tests the condition before the loop body executes, so the body may never run if the condition is initially false. [1] A REPEAT...UNTIL loop tests the condition after the loop body executes, so the body always runs at least once. [1]
(a) The algorithm uses a sentinel (-1) to end input, tracks the total, count, max, and min. The first valid item initialises both max and min trackers: [6]
DECLARE Price : REAL
DECLARE Total : REAL
DECLARE Count : INTEGER
DECLARE Average : REAL
DECLARE MaxPrice : REAL
DECLARE MinPrice : REAL
Total ← 0
Count ← 0
OUTPUT "Enter price (-1 to finish): "
INPUT Price
IF Price <> -1 THEN
MaxPrice ← Price
MinPrice ← Price
ENDIF
WHILE Price <> -1 DO
Total ← Total + Price
Count ← Count + 1
IF Price > MaxPrice THEN
MaxPrice ← Price
ENDIF
IF Price < MinPrice THEN
MinPrice ← Price
ENDIF
OUTPUT "Enter price (-1 to finish): "
INPUT Price
ENDWHILE
OUTPUT "Total sales: ", Total
OUTPUT "Items sold: ", Count
IF Count > 0 THEN
Average ← Total / Count
OUTPUT "Average price: ", Average
OUTPUT "Most expensive: ", MaxPrice
OUTPUT "Cheapest: ", MinPrice
ELSE
OUTPUT "No items entered"
ENDIF[1 mark for sentinel loop, 1 mark for totalling, 1 mark for counting, 1 mark for max tracking, 1 mark for min tracking with correct initialisation, 1 mark for average with zero check]
(b) The initial value for the maximum tracker should be the first valid item entered, not 0 or an arbitrary large/small number. [1] Initialising with the first actual data value ensures accurate tracking regardless of the data range. If set to 0 and all prices are positive, 0 would never be replaced as the minimum unless the code explicitly handles it. [1]
(c) If no items are entered (Count = 0), calculating the average would require dividing Total by 0. [1] This division by zero would cause a runtime error and crash the program. The check allows the program to display an informative message instead. [1]
(d) A WHILE loop tests the condition before the loop body executes, so the body may never run if the condition is initially false. [1] A REPEAT...UNTIL loop tests the condition after the loop body executes, so the body always runs at least once. [1]
Question 10 Report
The following flowchart represents an algorithm that processes a positive integer.
(a) Trace through the flowchart for N = 16, showing the value of N and Count at each step. [4]
(b) State the output when N = 16. [1]
(c) State what this algorithm calculates for any given positive integer input. [2]
(a) The flowchart repeatedly divides N by 2 (integer division) and increments Count, stopping when N is no longer greater than 1:
| Iteration | N (start) | N > 1? | N DIV 2 | Count |
|---|---|---|---|---|
| Initial | 16 | - | - | 0 |
| 1 | 16 | TRUE | 8 | 1 |
| 2 | 8 | TRUE | 4 | 2 |
| 3 | 4 | TRUE | 2 | 3 |
| 4 | 2 | TRUE | 1 | 4 |
| Check | 1 | FALSE | - | 4 |
Each iteration halves N and adds 1 to Count. After 4 iterations, N reaches 1 and the loop exits. [4]
(b) The output is 4. [1]
(c) The algorithm calculates how many times N can be halved (using integer division by 2) before reaching 1. [1] For inputs that are exact powers of 2, this gives the exponent, equivalent to log base 2 of N. For example, 16 = 24, so Count = 4. For non-powers of 2, integer division still counts the halvings, but the result is the floor of log2(N). [1] [2]
(a) The flowchart repeatedly divides N by 2 (integer division) and increments Count, stopping when N is no longer greater than 1:
| Iteration | N (start) | N > 1? | N DIV 2 | Count |
|---|---|---|---|---|
| Initial | 16 | - | - | 0 |
| 1 | 16 | TRUE | 8 | 1 |
| 2 | 8 | TRUE | 4 | 2 |
| 3 | 4 | TRUE | 2 | 3 |
| 4 | 2 | TRUE | 1 | 4 |
| Check | 1 | FALSE | - | 4 |
Each iteration halves N and adds 1 to Count. After 4 iterations, N reaches 1 and the loop exits. [4]
(b) The output is 4. [1]
(c) The algorithm calculates how many times N can be halved (using integer division by 2) before reaching 1. [1] For inputs that are exact powers of 2, this gives the exponent, equivalent to log base 2 of N. For example, 16 = 24, so Count = 4. For non-powers of 2, integer division still counts the halvings, but the result is the floor of log2(N). [1] [2]
Question 11 Report
The following pseudocode performs a linear search on an array of names to find a target name. Some lines are missing.
DECLARE Names : ARRAY[1:100] OF STRING
DECLARE Target : STRING
DECLARE Found : BOOLEAN
DECLARE Index : INTEGER
DECLARE Size : INTEGER
Size ← 100
OUTPUT "Enter name to search for: "
INPUT Target
Found ← _______________ 'Line 1
Index ← _______________ 'Line 2
WHILE _____________ AND _____________ DO 'Line 3
IF Names[Index] = Target THEN
Found ← _______________ 'Line 4
ELSE
Index ← _______________ 'Line 5
ENDIF
ENDWHILE
IF Found = TRUE THEN
OUTPUT Target, " found at position ", Index
ELSE
OUTPUT Target, " not found"
ENDIF(a) Copy and complete lines 1 to 5 to make the algorithm work correctly. [5]
(b) State the maximum number of comparisons this algorithm would need to make if the name is not in the array. [1]
(c) Explain why a WHILE loop is used rather than a FOR loop for this search. [2]
(a) A linear search initialises a Found flag to FALSE and starts checking from position 1. The WHILE loop continues as long as the target has not been found AND there are still elements to check. When the target is found, Found is set to TRUE (which stops the loop). If it is not found, the index advances to the next position:
Found <- FALSE - the search has not yet found the target. [1]Index <- 1 - begin searching from the first element. [1]WHILE Index <= Size AND Found = FALSE DO - continue while there are elements left to check AND the target has not been found. Both conditions are needed: the first prevents going past the array bounds, the second stops early when found. [1]Found <- TRUE - the current element matches the target. [1]Index <- Index + 1 - move to the next element (only when the current element does not match). [1](b) If the name is not in the array, the algorithm must compare every element before concluding the name is absent. With an array of 100 elements, this means 100 comparisons. [1]
(c) A WHILE loop is used because the number of iterations is not known in advance; the search should stop as soon as the target is found. [1] A FOR loop would iterate through every element regardless, performing unnecessary comparisons after the target has already been located, making it less efficient. [1] [2]
(a) A linear search initialises a Found flag to FALSE and starts checking from position 1. The WHILE loop continues as long as the target has not been found AND there are still elements to check. When the target is found, Found is set to TRUE (which stops the loop). If it is not found, the index advances to the next position:
Found <- FALSE - the search has not yet found the target. [1]Index <- 1 - begin searching from the first element. [1]WHILE Index <= Size AND Found = FALSE DO - continue while there are elements left to check AND the target has not been found. Both conditions are needed: the first prevents going past the array bounds, the second stops early when found. [1]Found <- TRUE - the current element matches the target. [1]Index <- Index + 1 - move to the next element (only when the current element does not match). [1](b) If the name is not in the array, the algorithm must compare every element before concluding the name is absent. With an array of 100 elements, this means 100 comparisons. [1]
(c) A WHILE loop is used because the number of iterations is not known in advance; the search should stop as soon as the target is found. [1] A FOR loop would iterate through every element regardless, performing unnecessary comparisons after the target has already been located, making it less efficient. [1] [2]
Would you like to proceed with this action?