Cambridge IAL · PastPaper.sampleTitle

MetadataPastPaper.sampleTitle

Thinka Jun 2023 (V3) Cambridge International A Level-Style Mock — Computer Science (9618)

300 PastPaper.marks450 PastPaper.minutes2023
An original Thinka practice paper modelled on the structure and difficulty of the Jun 2023 (V3) Cambridge International A Level Computer Science (9618) paper. Not affiliated with or reproduced from Cambridge.

Paper 1 Theory Fundamentals

Answer all questions. Calculators must not be used.
7 PastPaper.question · 75 PastPaper.marks
PastPaper.question 1 · Structured Recall
15 PastPaper.marks
This question is about data representation.

(a) Represent the denary number \(-78\) as an 8-bit two's complement integer. Show your working. [2]

(b) Convert your 8-bit binary answer from part (a) into hexadecimal. Show your working. [2]

(c) State why Binary Coded Decimal (BCD) is used instead of standard binary representation in some electronic systems, and identify one practical application of BCD. [3]

(d) Describe how vector graphics are represented in a computer, and identify three typical drawing objects defined in a vector graphic file. [4]

(e) Compare lossy and lossless compression. Explain why lossless compression is necessary for program source files. [4]
PastPaper.showAnswers

PastPaper.workedSolution

(a) To represent \(-78\) in 8-bit two's complement:
1. Find the binary representation for positive 78:
\(78 = 64 + 8 + 4 + 2 = 01001110_2\)
2. Invert all bits (one's complement):
\(10110001_2\)
3. Add 1 (two's complement):
\(10110001 + 1 = 10110010_2\)

(b) To convert \(10110010_2\) to hexadecimal, split into two 4-bit nibbles:
1. Left nibble: \(1011_2 = 11_{10} = B_{16}\)
2. Right nibble: \(0010_2 = 2_{16}\)
Combined Hexadecimal value: \(B2_{16}\)

(c) BCD is used because each decimal digit is converted individually into 4 binary bits. This prevents rounding/representation errors that occur with floating-point binary when representing certain decimal fractions. It is also easier to decode and display. One common application is digital calculators or digital watch displays.

(d) Vector graphics are stored as a set of mathematical instructions/geometric formulas and parameters (like coordinates, stroke thickness, fill color) rather than mapping individual pixels. Three typical objects are: Line, Circle, Rectangle (or Polygon, Arc).

(e) Lossless compression reduces file size by identifying and encoding patterns without losing any original data, allowing the exact original file to be reconstructed. Lossy compression permanently discards less essential data to achieve much smaller file sizes. Lossless must be used for program source files because even a tiny change (like a single character altered or omitted) will corrupt the program, changing its meaning or causing compile-time syntax errors.

PastPaper.markingScheme

Part (a) [2 marks]:
- 1 mark for showing correct working (e.g., finding representation of +78 or 1's complement).
- 1 mark for correct final binary answer: 10110010.

Part (b) [2 marks]:
- 1 mark for separating into nibbles or demonstrating hex conversion technique.
- 1 mark for correct final answer: B2 (or B2_16).

Part (c) [3 marks]:
- 1 mark for explaining that BCD avoids binary rounding/fraction representation errors.
- 1 mark for explaining that it is easier/faster to convert and display directly on a screen.
- 1 mark for identifying a valid application (e.g., calculator, digital clock, cash register).

Part (d) [4 marks]:
- 1 mark for explaining that vector graphics use mathematical/geometric properties/formulas and attributes (rather than individual pixels).
- 3 marks for identifying three distinct drawing objects (e.g., Line, Circle, Rectangle, Arc, Curve, Polygon).

Part (e) [4 marks]:
- 1 mark for explaining that lossless allows perfect reconstruction with no data lost.
- 1 mark for explaining that lossy permanently discards unnecessary/redundant data.
- 1 mark for stating that losing even one character in a source file ruins the syntax/meaning.
- 1 mark for stating this causes compilation/execution errors.
PastPaper.question 2 · Structured Recall
15 PastPaper.marks
This question is about processor architecture and instruction execution.

(a) Define the purpose of the following registers in the Von Neumann architecture:
(i) Program Counter (PC) [1]
(ii) Memory Address Register (MAR) [1]
(iii) Memory Data Register (MDR) [1]
(iv) Current Instruction Register (CIR) [1]

(b) Describe the steps of the Fetch stage of the Fetch-Execute cycle using register transfer notation (RTN). [5]

(c) Explain the difference between direct addressing and indirect addressing in assembly language, illustrating your explanation with an example of how each accesses data. [4]

(d) State the name of two system buses used in the CPU architecture and specify the direction of data or signal transfer for each. [2]
PastPaper.showAnswers

PastPaper.workedSolution

(a)
(i) Program Counter (PC): Holds the memory address of the next instruction to be fetched.
(ii) Memory Address Register (MAR): Holds the address in memory that is currently being accessed for a read or write operation.
(iii) Memory Data Register (MDR): Temporarily holds data read from memory, or data waiting to be written to memory.
(iv) Current Instruction Register (CIR): Holds the instruction that is currently being decoded and executed.

(b) The Fetch stage represented in RTN is:
1. \(MAR \leftarrow [PC]\) (The address in PC is copied to MAR)
2. \(PC \leftarrow [PC] + 1\) (PC is incremented to point to the next instruction address)
3. \(MDR \leftarrow [[MAR]]\) (The instruction at the address in MAR is loaded into MDR)
4. \(CIR \leftarrow [MDR]\) (The instruction is copied from MDR to CIR for decoding)

(c)
- Direct Addressing: The operand in the instruction is the actual address of the data. For example, `LDD 200` directly loads the accumulator with whatever data value is stored at memory address 200.
- Indirect Addressing: The operand is a memory address that contains the final/actual address of the data. For example, `LDI 200` looks at memory address 200 to find a second address (e.g., 350) and then loads the accumulator with the data value stored at address 350.

(d)
- Address Bus: Unidirectional (travels from CPU to memory/IO components only).
- Data Bus: Bidirectional (carries data back and forth between the CPU, memory, and IO components).

PastPaper.markingScheme

Part (a) [4 marks]:
- 1 mark for correct definition of PC.
- 1 mark for correct definition of MAR.
- 1 mark for correct definition of MDR.
- 1 mark for correct definition of CIR.

Part (b) [5 marks]:
- 1 mark for \(MAR \leftarrow [PC]\)
- 1 mark for \(PC \leftarrow [PC] + 1\)
- 1 mark for loading memory content: \(MDR \leftarrow [[MAR]]\) (or equivalent descriptive notation)
- 1 mark for copying to CIR: \(CIR \leftarrow [MDR]\)
- 1 mark for logical sequential flow linking the fetch steps correctly.

Part (c) [4 marks]:
- 1 mark for defining direct addressing (address points directly to data).
- 1 mark for an accurate direct addressing example (e.g., LDD 200 loads content at 200).
- 1 mark for defining indirect addressing (address points to an address holding the data).
- 1 mark for an accurate indirect addressing example (e.g., LDI 200 fetches value stored at address found in 200).

Part (d) [2 marks]:
- 1 mark for: Address Bus is unidirectional.
- 1 mark for: Data Bus is bidirectional (or Control Bus is bidirectional).
PastPaper.question 3 · Structured Recall
15 PastPaper.marks
This question is about relational databases.

(a) Define the terms *Primary Key*, *Foreign Key*, and *Referential Integrity* within the context of database design. [4]

(b) A company manages training sessions with an unnormalized table:
`CourseBooking(EmployeeID, EmployeeName, CourseCode, CourseTitle, DateEnrolled)`

Assume that an employee can book multiple courses, and courses can have multiple employees.

(i) Explain why this table is not in First Normal Form (1NF) if an employee can sign up for multiple courses on a single row, and describe how to convert it to 1NF. [2]

(ii) Normalize the schema from 1NF into Third Normal Form (3NF). Describe your normalization process and list the resulting table schemas. Clearly indicate all Primary Keys (PK) and Foreign Keys (FK). [6]

(c) Write a SQL Query to retrieve the `EmployeeName` and `CourseTitle` for all enrollments where the `DateEnrolled` is after '2023-01-01'. [3]
PastPaper.showAnswers

PastPaper.workedSolution

(a)
- Primary Key: A field (or group of fields) that uniquely identifies a unique record in a database table.
- Foreign Key: An attribute in one table that references the primary key of another table, creating a relational link.
- Referential Integrity: A database property ensuring that relationships between tables remain consistent. Any foreign key value must have a matching primary key value in the related table (no orphaned records).

(b)
(i) A table is not in 1NF if it contains multi-valued attributes or repeating groups (non-atomic values) in a single row (e.g., multiple courses listed together for one employee ID). To convert it to 1NF, ensure that all attribute values are atomic by creating a separate record/row for each unique combination of employee and course.

(ii) Normalization steps:
- 1NF Schema: `CourseBooking(EmployeeID, EmployeeName, CourseCode, CourseTitle, DateEnrolled)` where the primary key is a composite key: `(EmployeeID, CourseCode)`.
- Convert to 2NF: Eliminate partial dependencies.
- `EmployeeName` depends only on part of the key (`EmployeeID`).
- `CourseTitle` depends only on part of the key (`CourseCode`).
- `DateEnrolled` depends on the full composite key `(EmployeeID, CourseCode)`.
- This yields three tables:
1. `Employee(EmployeeID, EmployeeName)` with PK: `EmployeeID`
2. `Course(CourseCode, CourseTitle)` with PK: `CourseCode`
3. `Booking(EmployeeID, CourseCode, DateEnrolled)` with Composite PK: `(EmployeeID, CourseCode)` and FKs: `EmployeeID` (ref `Employee`), `CourseCode` (ref `Course`).
- Convert to 3NF: Eliminate transitive dependencies. In the 2NF tables, no non-key field depends on another non-key field. Therefore, the tables are already in 3NF.

(c) SQL Query:
```sql
SELECT Employee.EmployeeName, Course.CourseTitle
FROM Booking
JOIN Employee ON Booking.EmployeeID = Employee.EmployeeID
JOIN Course ON Booking.CourseCode = Course.CourseCode
WHERE Booking.DateEnrolled > '2023-01-01';
```

PastPaper.markingScheme

Part (a) [4 marks]:
- 1 mark for defining Primary Key (unique identifier of a row/record).
- 1 mark for defining Foreign Key (field in one table referencing a primary key in another table).
- 2 marks for defining Referential Integrity (ensuring foreign key refers to a valid primary key / no orphaned records).

Part (b)(i) [2 marks]:
- 1 mark for stating that multiple entries in a field violate atomicity/contain repeating groups.
- 1 mark for stating that to resolve it, each row must contain only atomic values (split into multiple rows/records).

Part (b)(ii) [6 marks]:
- 1 mark for explaining partial key dependency removal (transition from 1NF to 2NF).
- 1 mark for explaining transitive dependency check (transition to 3NF).
- 1 mark for `Employee` table with PK `EmployeeID` correctly identified.
- 1 mark for `Course` table with PK `CourseCode` correctly identified.
- 1 mark for `Booking` table with composite PK `(EmployeeID, CourseCode)` correctly identified.
- 1 mark for correctly identifying foreign keys in `Booking` linking to `Employee` and `Course` tables.

Part (c) [3 marks]:
- 1 mark for SELECT clause selecting `EmployeeName` and `CourseTitle` (with table aliases if needed).
- 1 mark for FROM clause containing necessary JOINs (or Cartesian product linking primary-foreign keys in WHERE clause).
- 1 mark for WHERE clause restricting `DateEnrolled > '2023-01-01'`.
PastPaper.question 4 · Structured Recall
15 PastPaper.marks
This question is about computer networks and data communication.

(a) Explain the steps involved in packet switching when transmitting a file across the internet. [5]

(b) Describe three key differences between IPv4 and IPv6 addressing systems. [3]

(c) Explain the difference between a public IP address and a private IP address, and state why private IP addresses are used. [4]

(d) Explain how a Domain Name Service (DNS) server is used to locate a website. [3]
PastPaper.showAnswers

PastPaper.workedSolution

(a) Packet switching steps:
1. The sender splits the data file into smaller chunks called packets.
2. A header is added to each packet containing metadata (source IP, destination IP, packet sequence number, and error-checking/checksum data).
3. Each packet is sent individually across the network.
4. Routers dynamically direct packets along the most efficient path; packets may take completely different routes based on congestion.
5. Packets arrive at the destination, potentially out of order.
6. The receiver uses sequence numbers in the headers to reassemble packets back into the original file, checking for errors and requesting retransmission of lost/corrupt packets.

(b) Differences between IPv4 and IPv6:
- IPv4 uses 32-bit addresses; IPv6 uses 128-bit addresses.
- IPv4 addresses are represented in denary/decimal format (separated by dots); IPv6 addresses are represented in hexadecimal format (separated by colons).
- IPv4 has about 4.3 billion possible unique addresses (leading to address exhaustion); IPv6 has over \(3.4 \times 10^{38}\) unique addresses.

(c)
- Public IP address: An address that is unique across the entire global internet and is directly accessible by other public devices on the internet.
- Private IP address: An address used inside a private local area network (LAN) that is not visible or routable on the public internet.
- Why private IPs are used: They conserve the limited pool of public IPv4 addresses (using Network Address Translation (NAT) to let a whole LAN share one public IP) and improve network security because local devices are shielded from direct external attacks.

(d)
1. The user inputs a human-readable URL (e.g., `www.example.com`) into their web browser.
2. The browser contacts a DNS server to search for the domain name in its distributed database.
3. The DNS server translates/resolves the domain name into its corresponding numerical public IP address and returns this IP address to the browser, allowing it to initiate a direct connection with the web server.

PastPaper.markingScheme

Part (a) [5 marks max]:
- 1 mark for stating that data is split into smaller units called packets.
- 1 mark for explaining that each packet gets a header containing source/destination IPs and sequence numbers.
- 1 mark for stating packets travel independently across the network.
- 1 mark for stating routers determine the optimal route for each packet dynamically.
- 1 mark for stating the destination uses sequence numbers to reassemble packets in order.
- 1 mark for stating that packet errors/losses prompt retransmission.

Part (b) [3 marks]:
- 1 mark per valid difference (address length, number base/notation, total address space size, security features) up to a maximum of 3 marks.

Part (c) [4 marks]:
- 1 mark for defining Public IP (globally unique, accessible over internet).
- 1 mark for defining Private IP (local LAN scope only, not publically routable).
- 1 mark for stating private IPs allow conservation of public IPv4 addresses via NAT.
- 1 mark for stating private IPs enhance security by masking internal network structure.

Part (d) [3 marks]:
- 1 mark for stating DNS maintains a directory of domain names mapped to IP addresses.
- 1 mark for stating that browser queries DNS with the domain name.
- 1 mark for stating DNS returns the IP address, allowing the browser to connect to the target web host.
PastPaper.question 5 · Logic Design
5 PastPaper.marks
Simplify the following Boolean expression using Boolean algebra laws:

\(X = \overline{A \cdot B} \cdot (\overline{A} + B) \cdot (B + \overline{C})\)

Show your working clearly and state at least two Boolean algebraic laws that you used in the simplification process.
PastPaper.showAnswers

PastPaper.workedSolution

Step 1: Apply De Morgan's Law to the first term \(\overline{A \cdot B}\):
\(X = (\overline{A} + \overline{B}) \cdot (\overline{A} + B) \cdot (B + \overline{C})\)

Step 2: Simplify the product of the first two terms \((\overline{A} + \overline{B}) \cdot (\overline{A} + B)\).
Using the Distributive Law in reverse:
\((\overline{A} + \overline{B}) \cdot (\overline{A} + B) = \overline{A} + (\overline{B} \cdot B)\)

Step 3: Apply the Complement Law (\(\overline{B} \cdot B = 0\)) and Identity Law (\(\overline{A} + 0 = \overline{A}\)):
\(\overline{A} + 0 = \overline{A}\)

Step 4: Substitute this back into the expression:
\(X = \overline{A} \cdot (B + \overline{C})\)

Step 5: Apply the Distributive Law to expand the expression into sum-of-products (SOP) form:
\(X = \overline{A}B + \overline{A}\overline{C}\)

PastPaper.markingScheme

- 1 mark: Correct application of De Morgan's Law to get \(\overline{A} + \overline{B}\).
- 1 mark: Correct expansion or distribution of \((\overline{A} + \overline{B}) \cdot (\overline{A} + B)\).
- 1 mark: Correctly simplifying \((\overline{A} + \overline{B}) \cdot (\overline{A} + B)\) to \(\overline{A}\) using Complement/Identity laws.
- 1 mark: Correctly stating at least two laws used (e.g., De Morgan's, Distributive, Complement, or Identity laws).
- 1 mark: Correct final simplified expression in either SOP form \(X = \overline{A}B + \overline{A}\overline{C}\) or factored form \(X = \overline{A}(B + \overline{C})\).
PastPaper.question 6 · Logic Design
5 PastPaper.marks
A digital logic circuit has three inputs, \(A\), \(B\), and \(C\), and an output \(Y\).

The output \(Y\) is 1 under the following input conditions:
- \(A = 0, B = 0, C = 1\)
- \(A = 0, B = 1, C = 0\)
- \(A = 0, B = 1, C = 1\)
- \(A = 1, B = 0, C = 1\)
- \(A = 1, B = 1, C = 1\)

For all other inputs, the output is 0.

(a) Describe or represent the layout of the 1s in a standard 2x4 Karnaugh Map (K-map) where the rows represent \(A\) (0 and 1) and the columns represent \(BC\) (00, 01, 11, 10).
(b) Identify and describe the two optimal groupings (loops) of 1s used to simplify the logic expression.
(c) Write down the final simplified sum-of-products expression for \(Y\).
PastPaper.showAnswers

PastPaper.workedSolution

Part (a):
The Karnaugh Map has rows for A (0, 1) and columns for BC (00, 01, 11, 10):
- Row 0 (A = 0): Columns 00=0, 01=1, 11=1, 10=1
- Row 1 (A = 1): Columns 00=0, 01=1, 11=1, 10=0

Part (b):
- Group 1: A 2x2 group (quad) of 1s in columns 01 and 11 across both rows (A = 0 and A = 1). Since A changes (0 to 1) and B changes (0 to 1), only C remains constant at 1. This loop simplifies to \(C\).
- Group 2: A 1x2 group (pair) of 1s in row A = 0, columns 11 and 10. Since A is constant at 0, B is constant at 1, and C changes (1 to 0), this loop simplifies to \(\overline{A}B\).

Part (c):
Combining the terms gives the simplified sum-of-products expression:
\(Y = C + \overline{A}B\)

PastPaper.markingScheme

- 1 mark: Correctly mapping all five 1s to the K-map grid.
- 1 mark: Identifying the 2x2 group (quad) spanning columns 01 and 11 across both rows.
- 1 mark: Correctly simplifying the quad to \(C\).
- 1 mark: Identifying the 1x2 group (pair) in row 0, columns 11 and 10.
- 1 mark: Correctly simplifying the pair to \(\overline{A}B\) and stating the final expression \(Y = C + \overline{A}B\).
PastPaper.question 7 · Logic Design
5 PastPaper.marks
A Full Adder is a combinational logic circuit used to perform binary addition on three inputs.

(a) State the Boolean algebraic expressions for the two outputs of a Full Adder: Sum (\(S\)) and Carry-out (\(C_{out}\)) in terms of the three inputs \(A\), \(B\), and Carry-in (\(C_{in}\)).

(b) Describe how a Full Adder circuit can be constructed using exactly two Half Adders and one additional logic gate. In your description, specify the inputs to each Half Adder, the type of the additional gate, and the inputs to that additional gate.
PastPaper.showAnswers

PastPaper.workedSolution

Part (a):
- Sum output: \(S = A \oplus B \oplus C_{in}\)
- Carry-out output: \(C_{out} = (A \cdot B) + (C_{in} \cdot (A \oplus B))\) (or equivalent algebraic form, such as \(C_{out} = AB + BC_{in} + AC_{in}\))

Part (b):
- First Half Adder: Takes external inputs \(A\) and \(B\). It outputs an intermediate sum \(S_1 = A \oplus B\) and an intermediate carry \(C_1 = A \cdot B\).
- Second Half Adder: Takes the intermediate sum \(S_1\) from the first Half Adder and the external Carry-in (\(C_{in}\)) as its inputs. It outputs the final Sum (\(S = S_1 \oplus C_{in}\)) and a second intermediate carry \(C_2 = S_1 \cdot C_{in}\).
- Additional Gate: An OR gate is used.
- Inputs to OR Gate: The intermediate carry outputs from both Half Adders (\(C_1\) and \(C_2\)). The output of this OR gate is the final Carry-out (\(C_{out} = C_1 + C_2\)).

PastPaper.markingScheme

- 1 mark: Correct Boolean expression for Sum (\(S\)) output.
- 1 mark: Correct Boolean expression for Carry-out (\(C_{out}\)) output.
- 1 mark: Correct description of the first Half Adder taking inputs \(A\) and \(B\) to produce intermediate sum and carry.
- 1 mark: Correct description of the second Half Adder taking the intermediate sum and \(C_{in}\) to produce the final Sum.
- 1 mark: Correct identification of the OR gate combining both intermediate carry signals to produce the final \(C_{out}\).

Paper 2 Fundamental Problem-solving and Programming Skills

Write your answers in the pseudocode style as defined in the insert.
8 PastPaper.question · 74.97999999999999 PastPaper.marks
PastPaper.question 1 · Algorithmic Analysis
8 PastPaper.marks
Write your answers in the pseudocode style as defined in the insert.

A programmer has written the following pseudocode function `AnalyzePattern` which takes an integer array `DataList` of size `N` (indexed from 1 to `N`) and an integer `Target`.

```
FUNCTION AnalyzePattern(DataList : ARRAY, N : INTEGER, Target : INTEGER) RETURNS INTEGER
DECLARE count, i, j : INTEGER
count <- 0
FOR i <- 1 TO N - 1
j <- i + 1
WHILE j <= N AND (DataList[i] + DataList[j] <= Target)
IF DataList[i] + DataList[j] = Target THEN
count <- count + 1
ENDIF
j <- j + 1
ENDWHILE
ENDFOR
RETURN count
ENDFUNCTION
```

Assume `DataList` is sorted in ascending order.

(a) Dry run the function `AnalyzePattern` with the following parameters:
- `DataList` = [2, 3, 5, 5, 8, 10]
- `N` = 6
- `Target` = 10

Show the trace of variables `i`, `j`, and `count` as they change, and state the final returned value. (4 marks)

(b) Analyze the efficiency of `AnalyzePattern`:
(i) Describe the condition under which the algorithm exhibits its worst-case scenario. (1 mark)
(ii) Calculate the exact number of iterations of the inner `WHILE` loop in this worst-case scenario for `N` = 6, and express the worst-case time complexity using Big O notation in terms of `N`. (3 marks)
PastPaper.showAnswers

PastPaper.workedSolution

(a) Trace of CalcPower:
Initial: count = 0
- i = 1, j = 2: DataList[1] + DataList[2] = 2 + 3 = 5 <= 10. IF is False. j becomes 3.
- i = 1, j = 3: DataList[1] + DataList[3] = 2 + 5 = 7 <= 10. IF is False. j becomes 4.
- i = 1, j = 4: DataList[1] + DataList[4] = 2 + 5 = 7 <= 10. IF is False. j becomes 5.
- i = 1, j = 5: DataList[1] + DataList[5] = 2 + 8 = 10 <= 10. IF is True, count becomes 1. j becomes 6.
- i = 1, j = 6: DataList[1] + DataList[6] = 2 + 10 = 12 > 10. Loop terminates.

- i = 2, j = 3: DataList[2] + DataList[3] = 3 + 5 = 8 <= 10. IF is False. j becomes 4.
- i = 2, j = 4: DataList[2] + DataList[4] = 3 + 5 = 8 <= 10. IF is False. j becomes 5.
- i = 2, j = 5: DataList[2] + DataList[5] = 3 + 8 = 11 > 10. Loop terminates.

- i = 3, j = 4: DataList[3] + DataList[4] = 5 + 5 = 10 <= 10. IF is True, count becomes 2. j becomes 5.
- i = 3, j = 5: DataList[3] + DataList[5] = 5 + 8 = 13 > 10. Loop terminates.

- i = 4, j = 5: DataList[4] + DataList[5] = 5 + 8 = 13 > 10. Loop terminates.

- i = 5, j = 6: DataList[5] + DataList[6] = 8 + 10 = 18 > 10. Loop terminates.

Final returned value: 2.

(b) (i) The worst-case scenario occurs when the condition `(DataList[i] + DataList[j] <= Target)` is always true. This happens when the sum of any two elements in the array is less than or equal to the `Target`.

(ii) For N = 6, the inner loop runs N - i times for each i:
- i = 1: 5 times
- i = 2: 4 times
- i = 3: 3 times
- i = 4: 2 times
- i = 5: 1 time
Total iterations = 5 + 4 + 3 + 2 + 1 = 15.

In general, the number of comparison operations is \( \frac{N(N - 1)}{2} \), which gives a worst-case time complexity of \( O(N^2) \).

PastPaper.markingScheme

(a) Tracing (4 marks):
- 1 mark: Correctly tracing the first outer loop pass (i=1) showing j changing from 2 to 6 and count incrementing to 1.
- 1 mark: Correctly tracing the second outer loop pass (i=2) showing j changing from 3 to 5 and loop terminating when sum > 10.
- 1 mark: Correctly tracing the third outer loop pass (i=3) showing count incrementing to 2.
- 1 mark: Correctly tracing the remaining outer loop passes and identifying final returned value of 2.

(b) (i) Worst-Case Condition (1 mark):
- 1 mark: Identifying that the sum of any two elements must be <= Target (i.e., the loop condition is never False due to the sum comparison).

(ii) Iterations & Complexity (3 marks):
- 1 mark: Showing calculation of iterations: 5 + 4 + 3 + 2 + 1 = 15.
- 1 mark: Stating the general form: \( \frac{N(N-1)}{2} \).
- 1 mark: Correctly identifying Big O complexity as \( O(N^2) \).
PastPaper.question 2 · Algorithmic Analysis
8 PastPaper.marks
Write your answers in the pseudocode style as defined in the insert.

A software engineer is developing a search module for an inventory system. They must choose between two search algorithms, Algorithm A (Linear Search) and Algorithm B (Binary Search), to find a specific key in an array of size \(N\).

(a) If the array is unsorted:
(i) Explain why Algorithm B cannot be used. (1 mark)
(ii) State the worst-case number of key comparisons required by Algorithm A. (1 mark)
(iii) State the average-case number of key comparisons required by Algorithm A if the item is present. (1 mark)

(b) If the array is sorted and has a size of \(N = 1024\):
(i) State the maximum number of key comparisons required by Algorithm A to find an item or determine that it is missing. (1 mark)
(ii) Calculate the maximum number of key comparisons required by Algorithm B to find an item or determine that it is missing. Show your working. (3 marks)
(iii) Describe a scenario where Algorithm A would perform fewer key comparisons than Algorithm B when searching this sorted array. (1 mark)
PastPaper.showAnswers

PastPaper.workedSolution

(a) (i) Algorithm B (Binary Search) relies on the array being sorted because it divides the search space in half based on whether the target key is greater than or less than the midpoint element. If the array is unsorted, this logical division is invalid, and elements might be missed.
(ii) \(N\) comparisons (or 1024 if using the size in part b).
(iii) \( \frac{N + 1}{2} \) (or approximately \( \frac{N}{2} \)).

(b) (i) 1024 comparisons.
(ii) Binary search reduces the search space by half each time. The maximum number of comparisons is calculated using \( \lfloor \log_2(N) \rfloor + 1 \) (or \( \lceil \log_2(N+1) \rceil \)).
For \(N = 1024\):
- 1st comparison: size 1024 -> 512
- 2nd comparison: size 512 -> 256
- 3rd comparison: size 256 -> 128
- 4th comparison: size 128 -> 64
- 5th comparison: size 64 -> 32
- 6th comparison: size 32 -> 16
- 7th comparison: size 16 -> 8
- 8th comparison: size 8 -> 4
- 9th comparison: size 4 -> 2
- 10th comparison: size 2 -> 1
- 11th comparison: size 1 -> 0 (final check fails)
Therefore, the maximum number of comparisons is 11 (accept 10 if assuming immediate termination on finding single element in loop).

(iii) When the search target is located at the very first element of the array (index 1). Algorithm A would find it in 1 comparison, whereas Algorithm B would start searching from the middle of the array, requiring around 10 comparisons.

PastPaper.markingScheme

(a) Unsorted Array (3 marks):
- (i) 1 mark: Mentioning that Binary Search relies on the array being sorted to make a decision about which half to discard.
- (ii) 1 mark: Stating \(N\) comparisons.
- (iii) 1 mark: Stating \( \frac{N+1}{2} \) or \( \frac{N}{2} \).

(b) Sorted Array (5 marks):
- (i) 1 mark: 1024 comparisons.
- (ii) 3 marks:
- 1 mark: Stating the formula or relationship: \( \log_2(N) \) or dividing by 2 successively.
- 1 mark: Showing step-by-step reduction of search space (e.g., 1024 -> 512 -> ... -> 1).
- 1 mark: Correct final answer (11 or 10, depending on implementation/working shown).
- (iii) 1 mark: Stating that the target is at the beginning of the array / first element.
PastPaper.question 3 · Algorithmic Analysis
8 PastPaper.marks
Write your answers in the pseudocode style as defined in the insert.

A recursive function `CalcPower` is defined as follows:

```
FUNCTION CalcPower(Base : INTEGER, Exp : INTEGER) RETURNS INTEGER
IF Exp = 0 THEN
RETURN 1
ELSE
IF Exp MOD 2 = 0 THEN
DECLARE Temp : INTEGER
Temp <- CalcPower(Base, Exp / 2)
RETURN Temp * Temp
ELSE
RETURN Base * CalcPower(Base, Exp - 1)
ENDIF
ENDIF
ENDFUNCTION
```

(a) Complete a trace of the execution of the function call `CalcPower(3, 5)`.
Show each recursive call with its parameters and the returned value once the call stack unwinds. (4 marks)

(b) Analyze the algorithmic efficiency of `CalcPower`:
(i) State the worst-case time complexity of this algorithm using Big O notation in terms of `Exp`. (1 mark)
(ii) Explain how this recursive algorithm is more efficient than a naive recursive algorithm that simply performs `Base * CalcPower(Base, Exp - 1)` at each step, making reference to their respective time complexities. (2 marks)
(iii) State the maximum call stack depth (space complexity) for `CalcPower(Base, Exp)` in terms of `Exp` using Big O notation. (1 mark)
PastPaper.showAnswers

PastPaper.workedSolution

(a) Trace of CalcPower(3, 5):
- Call 1: CalcPower(3, 5) -> Exp is odd. Calls CalcPower(3, 4).
- Call 2: CalcPower(3, 4) -> Exp is even. Calls CalcPower(3, 2).
- Call 3: CalcPower(3, 2) -> Exp is even. Calls CalcPower(3, 1).
- Call 4: CalcPower(3, 1) -> Exp is odd. Calls CalcPower(3, 0).
- Call 5: CalcPower(3, 0) -> Exp is 0. Returns 1.

Unwinding the stack:
- Call 5 returns 1.
- Call 4 returns 3 * 1 = 3.
- Call 3 gets Temp = 3, returns 3 * 3 = 9.
- Call 2 gets Temp = 9, returns 9 * 9 = 81.
- Call 1 returns 3 * 81 = 243.

(b) (i) \( O(\log \text{Exp}) \)
(ii) The naive algorithm decrements the exponent by 1 at each step, resulting in a time complexity of \( O(\text{Exp}) \). The `CalcPower` algorithm halves the exponent (`Exp / 2`) whenever it is even. Since even/odd exponents alternate, the size of the exponent is halved at least every two steps. This reduces the number of recursive calls drastically, giving \( O(\log \text{Exp}) \) time complexity instead of \( O(\text{Exp}) \).
(iii) \( O(\log \text{Exp}) \) space complexity, as the height of the recursive call stack is proportional to the number of active activation records, which is bounded by \( O(\log \text{Exp}) \).

PastPaper.markingScheme

(a) Trace (4 marks):
- 1 mark: Show all recursive calls with correct arguments in sequence: (3, 5) -> (3, 4) -> (3, 2) -> (3, 1) -> (3, 0).
- 1 mark: Correct base case return value (returns 1 for Exp = 0).
- 1 mark: Correct intermediate values returned during unwinding (returns 3 for Exp=1, 9 for Exp=2, 81 for Exp=4).
- 1 mark: Correct final return value of 243.

(b) Efficiency (4 marks):
- (i) 1 mark: \( O(\log \text{Exp}) \).
- (ii) 2 marks:
- 1 mark: Identifying that naive is \( O(\text{Exp}) \) because it decrements by 1 each time.
- 1 mark: Explaining that this algorithm is \( O(\log \text{Exp}) \) because it halves the exponent size on even steps.
- (iii) 1 mark: \( O(\log \text{Exp}) \).
PastPaper.question 4 · Algorithmic Analysis
8 PastPaper.marks
Write your answers in the pseudocode style as defined in the insert.

The following pseudocode procedure implements a sorting algorithm on an array of size `N`.

```
PROCEDURE SortData(BYREF List : ARRAY, N : INTEGER)
DECLARE i, j, minIndex, temp : INTEGER
FOR i <- 1 TO N - 1
minIndex <- i
FOR j <- i + 1 TO N
IF List[j] < List[minIndex] THEN
minIndex <- j
ENDIF
ENDFOR
IF minIndex <> i THEN
temp <- List[i]
List[i] <- List[minIndex]
List[minIndex] <- temp
ENDIF
ENDFOR
ENDPROCEDURE
```

(a) Identify this sorting algorithm. (1 mark)

(b) Analyze the efficiency of `SortData`:
(i) Calculate the exact number of key comparisons (i.e., comparing `List[j] < List[minIndex]`) performed by the algorithm for an array of size `N` = 5. Show your working. (3 marks)
(ii) State the minimum and maximum number of key swaps performed by this algorithm for `N` = 5. Explain your answer. (2 marks)
(iii) Explain whether the initial order of elements in `List` affects the time complexity of this algorithm. (2 marks)
PastPaper.showAnswers

PastPaper.workedSolution

(a) Selection Sort

(b) (i) The outer loop runs with `i` from 1 to 4 (`N-1`). The inner loop runs with `j` from `i+1` to 5 (`N`).
- For i = 1: j runs 2 to 5 -> 4 comparisons.
- For i = 2: j runs 3 to 5 -> 3 comparisons.
- For i = 3: j runs 4 to 5 -> 2 comparisons.
- For i = 4: j runs 5 to 5 -> 1 comparison.
Total comparisons = 4 + 3 + 2 + 1 = 10.

(ii)
- Minimum swaps: 0. This occurs when the array is already sorted. The variable `minIndex` will always be equal to `i` at the end of the inner loop, so `minIndex <> i` is never true.
- Maximum swaps: 4 (or `N - 1`). This occurs when the minimum element is always at a different index from the current search index `i` on every step of the outer loop.

(iii) No, the initial order of elements does not affect the time complexity (specifically the number of comparisons). The nested loop structure runs through to completion regardless of whether the array is fully sorted, reverse-sorted, or random. The comparison count is always \( O(N^2) \).

PastPaper.markingScheme

(a) Identification (1 mark):
- 1 mark: Selection Sort.

(b) (i) Comparisons (3 marks):
- 1 mark: Identifying that the comparisons occur in the inner loop.
- 1 mark: Showing the sum sequence: 4 + 3 + 2 + 1.
- 1 mark: Correct total of 10 comparisons.

(ii) Swaps (2 marks):
- 1 mark: Minimum swaps = 0 (with explanation that no swaps happen when list is already sorted).
- 1 mark: Maximum swaps = 4 (with explanation that one swap occurs per outer loop step if minIndex changes).

(iii) Complexity Independence (2 marks):
- 1 mark: Stating that initial order does NOT affect time complexity / number of comparisons.
- 1 mark: Explaining that the loops always run to completion regardless of array values.
PastPaper.question 5 · Algorithmic Analysis
8 PastPaper.marks
Write your answers in the pseudocode style as defined in the insert.

A programmer implements a Hash Table of size 10 (with index positions 0 to 9) to store integer keys.

The hash function is defined as:
`Hash(Key) = Key MOD 10`

Collision resolution is managed using linear probing (where the algorithm searches sequentially for the next available slot, wrapping around to index 0 if the end of the table is reached).

(a) The hash table is initially empty. Show the state of the hash table after inserting the following keys in the order shown:
`42, 23, 32, 53, 72`

Write down the key stored at each of the indices from 0 to 9. If an index is empty, write "Empty". (3 marks)

(b) Analyze the efficiency of this hash table structure:
(i) Calculate the number of key comparisons required to search for the key `72` in the final table. Show your working. (2 marks)
(ii) Calculate the number of comparisons (including checking empty slots) required to confirm that the key `12` is not present in the table. Explain your answer. (2 marks)
(iii) Suggest one way to reduce the number of collisions in this hash table, apart from choosing a different collision resolution method. (1 mark)
PastPaper.showAnswers

PastPaper.workedSolution

(a) Tracing the insertions:
1. Key 42: Hash(42) = 42 MOD 10 = 2. Slot 2 is empty -> Table[2] = 42.
2. Key 23: Hash(23) = 23 MOD 10 = 3. Slot 3 is empty -> Table[3] = 23.
3. Key 32: Hash(32) = 32 MOD 10 = 2. Slot 2 is full. Linear probe to Slot 3 (full), then to Slot 4. Slot 4 is empty -> Table[4] = 32.
4. Key 53: Hash(53) = 53 MOD 10 = 3. Slot 3 is full. Linear probe to Slot 4 (full), then to Slot 5. Slot 5 is empty -> Table[5] = 53.
5. Key 72: Hash(72) = 72 MOD 10 = 2. Slot 2 is full. Linear probe: Slot 3 (full), Slot 4 (full), Slot 5 (full), Slot 6 (empty) -> Table[6] = 72.

Final Hash Table:
- Index 0: Empty
- Index 1: Empty
- Index 2: 42
- Index 3: 23
- Index 4: 32
- Index 5: 53
- Index 6: 72
- Index 7: Empty
- Index 8: Empty
- Index 9: Empty

(b) (i) To search for 72:
- Hash(72) = 2.
- Compare with Table[2] (42) -> No match (1st comparison)
- Compare with Table[3] (23) -> No match (2nd comparison)
- Compare with Table[4] (32) -> No match (3rd comparison)
- Compare with Table[5] (53) -> No match (4th comparison)
- Compare with Table[6] (72) -> Match found (5th comparison)
Total comparisons = 5.

(ii) To search for 12:
- Hash(12) = 2.
- Compare with Table[2] (42) -> No match (1)
- Compare with Table[3] (23) -> No match (2)
- Compare with Table[4] (32) -> No match (3)
- Compare with Table[5] (53) -> No match (4)
- Compare with Table[6] (72) -> No match (5)
- Compare/Check Table[7] (Empty) -> Empty slot found (6)
The search stops immediately when an empty slot is reached because if 12 were in the table, it would have been inserted sequentially prior to encountering this first empty slot. Total comparisons/checks = 6.

(iii) Increase the size of the table (to reduce the load factor / ratio of filled slots to total slots).

PastPaper.markingScheme

(a) Table State (3 marks):
- 1 mark: Correct placement of 42 at Index 2 and 23 at Index 3.
- 1 mark: Correct placement of 32 at Index 4 and 53 at Index 5.
- 1 mark: Correct placement of 72 at Index 6 and showing all other slots as empty.

(b) (i) Search 72 (2 marks):
- 1 mark: Detailing the step-by-step sequential comparisons from index 2 to index 6.
- 1 mark: Correct final answer of 5 comparisons.

(ii) Search 12 (2 marks):
- 1 mark: Explaining that the search stops upon reaching the empty slot at index 7.
- 1 mark: Correct final answer of 6 comparisons/checks (or 5 comparisons with keys + 1 check for empty).

(iii) Reduction of Collisions (1 mark):
- 1 mark: Suggesting increasing the table size (reducing the load factor) or using a larger prime number for table size.
PastPaper.question 6 · Pseudocode Creation
11.66 PastPaper.marks
A 1D array `TempData` contains 50 real numbers representing daily temperature readings (indexed 1 to 50). Write a pseudocode procedure `ProcessTemperatures` that takes `TempData` as a parameter and performs the following tasks:
- Calculates and outputs the average temperature of the 50 days.
- Counts and outputs how many days had temperatures strictly below the average.
- Counts and outputs how many days had temperatures strictly above the average.
- Finds and outputs the length of the longest consecutive sequence of days where the temperature was strictly increasing from one day to the next (e.g., if temperatures are 12.5, 13.0, 14.2, 11.0, the sequence 12.5 -> 13.0 -> 14.2 has length 3).

Use the pseudocode style defined in the Cambridge 9618 syllabus insert.
PastPaper.showAnswers

PastPaper.workedSolution

PROCEDURE ProcessTemperatures(TempData : ARRAY[1:50] OF REAL)
DECLARE Sum : REAL
DECLARE Average : REAL
DECLARE BelowCount, AboveCount : INTEGER
DECLARE CurrentSeq, MaxSeq : INTEGER
DECLARE i : INTEGER

// 1. Calculate Average
Sum <- 0.0
FOR i <- 1 TO 50
Sum <- Sum + TempData[i]
NEXT i
Average <- Sum / 50.0

// 2. Count Below and Above Average
BelowCount <- 0
AboveCount <- 0
FOR i <- 1 TO 50
IF TempData[i] < Average THEN
BelowCount <- BelowCount + 1
ELSE
IF TempData[i] > Average THEN
AboveCount <- AboveCount + 1
ENDIF
ENDIF
NEXT i

// 3. Find Longest Increasing Sequence
CurrentSeq <- 1
MaxSeq <- 1
FOR i <- 2 TO 50
IF TempData[i] > TempData[i - 1] THEN
CurrentSeq <- CurrentSeq + 1
ELSE
IF CurrentSeq > MaxSeq THEN
MaxSeq <- CurrentSeq
ENDIF
CurrentSeq <- 1
ENDIF
NEXT i

// Final check for sequence reaching end of array
IF CurrentSeq > MaxSeq THEN
MaxSeq <- CurrentSeq
ENDIF

// 4. Output results
OUTPUT "Average temperature: ", Average
OUTPUT "Days below average: ", BelowCount
OUTPUT "Days above average: ", AboveCount
OUTPUT "Longest increasing sequence: ", MaxSeq
ENDPROCEDURE

PastPaper.markingScheme

Award marks as follows:
- 1 Mark: Correct procedure header taking `TempData` as array parameter with type `ARRAY[1:50] OF REAL`.
- 1 Mark: Proper declarations of local variables with correct data types (`REAL`, `INTEGER`).
- 1 Mark: Correct iteration from 1 to 50 to sum the temperatures.
- 1 Mark: Correct calculation of average temperature (`Sum / 50.0`).
- 2 Marks: Loop to count strictly below and strictly above average temperatures (1 mark for loop, 1 mark for correct selection checking condition rules).
- 1 Mark: Initializing sequence counters `CurrentSeq` and `MaxSeq` to 1.
- 2 Marks: Iterating from index 2 to 50, correctly comparing the element at current index with the previous index and incrementing `CurrentSeq`.
- 1 Mark: Handling sequence break by comparing `CurrentSeq` with `MaxSeq`, updating `MaxSeq` if necessary, and resetting `CurrentSeq` to 1.
- 1 Mark: Correct post-loop check to handle sequence stretching to the last element.
- 1 Mark: Proper output statements with explanatory labels for all 4 computed values.
PastPaper.question 7 · Pseudocode Creation
11.66 PastPaper.marks
A text file `LogFile.txt` stores transaction records. Each line of the file contains a transaction record in the fixed format:
`[HH:MM:SS] `

Where:
- `[HH:MM:SS]` is a 10-character timestamp (index 1 to 10), e.g., `[14:32:01]`.
- The space at index 11 separates the timestamp from the UserID.
- `` is a 6-character user identifier (index 12 to 17), e.g., `USR902`.
- The space at index 18 separates the UserID from the Amount.
- `` is a variable-length string representing a decimal value (from index 19 to the end of the line), e.g., `150.50`.

Write pseudocode for a function `SummarizeTransactions` which:
- Takes a string parameter `TargetUser`.
- Opens the file `LogFile.txt` for reading.
- Reads the file line by line until the end of the file is reached.
- Extracts the UserID and checks if it matches `TargetUser`.
- If a match is found:
- Extracts the amount, converts it to a real number, and adds it to a running total.
- Tracks the maximum transaction amount for that user and the timestamp of that maximum transaction.
- Closes the file.
- Outputs the maximum transaction amount and its timestamp (or a 'No transactions found' message if none matched).
- Returns the running total of transactions.

You may use the following built-in functions:
- `MID(String1 : STRING, Start : INTEGER, Length : INTEGER) RETURNS STRING`
- `RIGHT(String1 : STRING, Length : INTEGER) RETURNS STRING`
- `LENGTH(String1 : STRING) RETURNS INTEGER`
- `STR_TO_NUM(String1 : STRING) RETURNS REAL`
- `EOF(FileName : STRING) RETURNS BOOLEAN`
PastPaper.showAnswers

PastPaper.workedSolution

FUNCTION SummarizeTransactions(TargetUser : STRING) RETURNS REAL
DECLARE Line : STRING
DECLARE CurrentUser : STRING
DECLARE AmountStr : STRING
DECLARE AmountVal : REAL
DECLARE TotalAmount : REAL
DECLARE MaxAmount : REAL
DECLARE MaxTime : STRING
DECLARE Found : BOOLEAN

TotalAmount <- 0.0
MaxAmount <- -1.0
MaxTime <- ""
Found <- FALSE

OPENFILE "LogFile.txt" FOR READ
WHILE NOT EOF("LogFile.txt")
READFILE "LogFile.txt", Line
IF LENGTH(Line) >= 19 THEN
CurrentUser <- MID(Line, 12, 6)
IF CurrentUser = TargetUser THEN
Found <- TRUE
AmountStr <- MID(Line, 19, LENGTH(Line) - 18)
AmountVal <- STR_TO_NUM(AmountStr)
TotalAmount <- TotalAmount + AmountVal

IF AmountVal > MaxAmount THEN
MaxAmount <- AmountVal
MaxTime <- MID(Line, 1, 10)
ENDIF
ENDIF
ENDIF
ENDWHILE
CLOSEFILE "LogFile.txt"

IF Found = TRUE THEN
OUTPUT "Max Transaction: ", MaxAmount, " at ", MaxTime
ELSE
OUTPUT "No transactions found"
ENDIF

RETURN TotalAmount
ENDFUNCTION

PastPaper.markingScheme

Award marks as follows:
- 1 Mark: Correct function header with parameter definition and `RETURNS REAL`.
- 1 Mark: Correct use of `OPENFILE` and `CLOSEFILE` with appropriate file mode.
- 1 Mark: Appropriate variable initialization (total to 0, flag and max values initialized cleanly).
- 1 Mark: Correct loop syntax using `WHILE NOT EOF("LogFile.txt")`.
- 1 Mark: Extracting the `CurrentUser` using `MID(Line, 12, 6)`.
- 1 Mark: Comparing the extracted user ID to the input parameter `TargetUser`.
- 2 Marks: Extracting the amount substring using dynamic length `LENGTH(Line) - 18` starting at 19, and converting it to numeric form with `STR_TO_NUM` (1 mark for index, 1 mark for conversion).
- 1 Mark: Accumulating transaction values to a running sum.
- 1 Mark: Correct search algorithm implementation to find maximum transaction amount and record matching timestamp from index 1 to 10.
- 1 Mark: Handling condition where no records were matched with logical flag and outputting informative diagnostics.
- 1 Mark: Correct `RETURN` statement returning the total sum.
PastPaper.question 8 · Pseudocode Creation
11.66 PastPaper.marks
A 2D game board is represented by a 2D array `Grid` of type `CHAR` with 8 rows and 8 columns (indices 1 to 8 for both dimensions).

The grid contains:
- `'P'` representing the player's position (there is exactly one `'P'` on the board).
- `'E'` representing enemy units.
- `'.'` representing empty space.

Write a pseudocode function `CountEnemiesInRange` that takes `Grid` as a parameter and returns an integer representing the number of enemies (`'E'`) in the immediate 8 adjacent squares surrounding the player (horizontally, vertically, and diagonally).

Your function must:
- Find the row and column coordinates of the player `'P'` by searching the grid.
- Safely check all adjacent squares without exceeding the boundaries of the array (rows 1 to 8, columns 1 to 8).
- Count the number of `'E'` cells surrounding `'P'` and exclude the player's own position from comparison.
- Return the total count.
PastPaper.showAnswers

PastPaper.workedSolution

FUNCTION CountEnemiesInRange(Grid : ARRAY[1:8, 1:8] OF CHAR) RETURNS INTEGER
DECLARE PlayerRow, PlayerCol : INTEGER
DECLARE Row, Col : INTEGER
DECLARE EnemyCount : INTEGER
DECLARE r, c : INTEGER

PlayerRow <- 0
PlayerCol <- 0
EnemyCount <- 0

// 1. Locate player 'P'
FOR Row <- 1 TO 8
FOR Col <- 1 TO 8
IF Grid[Row, Col] = 'P' THEN
PlayerRow <- Row
PlayerCol <- Col
ENDIF
NEXT Col
NEXT Row

// If player is not found on the board
IF PlayerRow = 0 OR PlayerCol = 0 THEN
RETURN 0
ENDIF

// 2. Check 3x3 grid around player
FOR r <- PlayerRow - 1 TO PlayerRow + 1
FOR c <- PlayerCol - 1 TO PlayerCol + 1
// Check boundary conditions
IF r >= 1 AND r <= 8 AND c >= 1 AND c <= 8 THEN
// Ensure we do not count the player's own position
IF NOT (r = PlayerRow AND c = PlayerCol) THEN
IF Grid[r, c] = 'E' THEN
EnemyCount <- EnemyCount + 1
ENDIF
ENDIF
ENDIF
NEXT c
NEXT r

RETURN EnemyCount
ENDFUNCTION

PastPaper.markingScheme

Award marks as follows:
- 1 Mark: Correct function header taking 2D array parameter and returns integer.
- 2 Marks: Correct nested loops (1 to 8) to traverse the array to search for player `'P'`.
- 1 Mark: Identifying player `'P'` and capturing both current row and column coordinates.
- 1 Mark: Correctly initializing variable `EnemyCount` to 0.
- 2 Marks: Loop configuration or sequence of individual checks scanning rows from `PlayerRow - 1` to `PlayerRow + 1` and columns from `PlayerCol - 1` to `PlayerCol + 1`.
- 2 Marks: Proper boundary assertions checking that row coordinate `r` and column coordinate `c` are between 1 and 8 inclusive before accessing array.
- 1 Mark: Correct check to make sure the target cell coordinates do not match the player's own position `(PlayerRow, PlayerCol)`.
- 1 Mark: Incrementing `EnemyCount` when finding character `'E'`.
- 1 Mark: Returning the final count value correctly.

Paper 3 Advanced Theory

Answer all questions. Show all working for calculations.
12 PastPaper.question · 75 PastPaper.marks
PastPaper.question 1 · Mathematical/Logic Modeling
7 PastPaper.marks
A real number is stored in normalized floating-point representation using a 10-bit mantissa and a 6-bit exponent, both in two's complement format.

The representation is:
Mantissa: 1011010000
Exponent: 000110

Show all working to calculate the denary value of this representation.

Your answer should show:
1. The calculation and value of the mantissa in denary.
2. The calculation and value of the exponent in denary.
3. The final denary calculation and its result.
PastPaper.showAnswers

PastPaper.workedSolution

Step 1: Convert the Mantissa.
The mantissa is 1011010000. Since the MSB is 1, this represents a negative number in normalized form.
The binary point is after the first bit: 1.011010000.
Using two's complement conversion, the value is calculated as:
-1 + 0*(0.5) + 1*(0.25) + 1*(0.125) + 0*(0.0625) + 1*(0.03125) = -1 + 0.25 + 0.125 + 0.03125 = -0.59375.

Step 2: Convert the Exponent.
The exponent is 000110. Since the MSB is 0, this is a positive integer.
000110 in denary is 4 + 2 = 6.

Step 3: Calculate the Final Value.
Multiply the mantissa by 2 raised to the power of the exponent:
-0.59375 * 2^6 = -0.59375 * 64 = -38.

PastPaper.markingScheme

1 mark: Identifies the mantissa as a negative number starting with 1.0
1 mark: Shows correct conversion of mantissa fractional place values to denary (-0.59375 or -19/32)
1 mark: Correct mantissa denary value (-0.59375)
1 mark: Identifies exponent as positive 6
1 mark: Correct exponent denary value (6)
1 mark: Shows final step multiplying mantissa by 2^6
1 mark: Correct final denary result (-38)
PastPaper.question 2 · Mathematical/Logic Modeling
7 PastPaper.marks
A logic circuit has four inputs A, B, C, and D. The output F is defined by the following boolean expression:

F = (not A and not B and C) or (not A and B and C) or (A and B and not D) or (A and not B and not D)

1. Represent this logic circuit in a 4-variable Karnaugh Map (K-map). (3 marks)
2. Show the groupings (loops) used to simplify the expression, explaining which cells are grouped together. (2 marks)
3. State the final simplified sum-of-products boolean expression. (2 marks)
PastPaper.showAnswers

PastPaper.workedSolution

Step 1: Set up the K-map with grey-code ordering (00, 01, 11, 10) for rows CD and columns AB.
The minterms from the expression are:
- not A and not B and C: covers cells 0010 (2) and 0011 (3)
- not A and B and C: covers cells 0110 (6) and 0111 (7)
- A and B and not D: covers cells 1100 (12) and 1110 (14)
- A and not B and not D: covers cells 1000 (8) and 1010 (10)

Placing 1s in these 8 cells in the K-map:
CD\AB | 00 | 01 | 11 | 10
00 | 0 | 0 | 1 | 1
01 | 0 | 0 | 0 | 0
11 | 1 | 1 | 0 | 0
10 | 1 | 1 | 1 | 1

Step 2: Form groups.
- Group 1: A 2x2 group of four 1s at the intersection of rows 11, 10 and columns 00, 01. This group represents (not A and C).
- Group 2: A 2x2 group of four 1s formed by wrapping the corners/edges, specifically rows 00, 10 and columns 11, 10. This group represents (A and not D).
(Note: The row 10 has a group of 4, but it is entirely redundant as its cells are fully covered by Group 1 and Group 2.)

Step 3: Simplified expression:
F = (not A and C) or (A and not D)

PastPaper.markingScheme

Part 1 (K-map):
1 mark: K-map template drawn with correct Grey code labels (00, 01, 11, 10) for rows/columns.
2 marks: All eight '1's placed in correct cells (lose 1 mark for any incorrect placement or extra/missing 1).

Part 2 (Grouping):
1 mark: Identifies first group of four cells in top-left/middle-left (representing not A and C).
1 mark: Identifies second group of four cells in top-right/bottom-right (representing A and not D) and states that the row of four is redundant.

Part 3 (Simplified Expression):
2 marks: Correct final expression (F = (not A and C) or (A and not D)). Allow equivalent notation like A'C + AD'.
PastPaper.question 3 · Mathematical/Logic Modeling
7 PastPaper.marks
An artificial neural network (ANN) uses a single hidden layer with two nodes, H1 and H2, and an output layer with a single node, Y.

The inputs are x1 = 0.8 and x2 = 0.5.

The weights and biases are as follows:
- For H1: weights from inputs are w11 = 0.5, w21 = -0.2; bias b1 = -0.1
- For H2: weights from inputs are w12 = -0.4, w22 = 0.6; bias b2 = 0.2
- For Y: weights from hidden nodes H1 and H2 are v1 = 0.8, v2 = 1.5; bias bY = -0.3

The activation function for all hidden and output nodes is the Rectified Linear Unit (ReLU), defined as: f(z) = max(0, z).

Calculate the output value of node Y by performing a full feedforward pass. Show all steps of your working.
PastPaper.showAnswers

PastPaper.workedSolution

Step 1: Calculate the output of hidden node H1 (a1).
Weighted sum z1 = (x1 * w11) + (x2 * w21) + b1
z1 = (0.8 * 0.5) + (0.5 * -0.2) + (-0.1)
z1 = 0.4 - 0.1 - 0.1 = 0.2
Since z1 > 0, the output a1 = ReLU(z1) = 0.2.

Step 2: Calculate the output of hidden node H2 (a2).
Weighted sum z2 = (x1 * w12) + (x2 * w22) + b2
z2 = (0.8 * -0.4) + (0.5 * 0.6) + 0.2
z2 = -0.32 + 0.3 + 0.2 = 0.18
Since z2 > 0, the output a2 = ReLU(z2) = 0.18.

Step 3: Calculate the output of node Y (aY).
Weighted sum zY = (a1 * v1) + (a2 * v2) + bY
zY = (0.2 * 0.8) + (0.18 * 1.5) + (-0.3)
zY = 0.16 + 0.27 - 0.3
zY = 0.43 - 0.3 = 0.13
Since zY > 0, the output aY = ReLU(zY) = 0.13.

PastPaper.markingScheme

1 mark: Correct weighted sum calculation for H1 (0.2).
1 mark: Correct output for H1 after applying ReLU (0.2).
1 mark: Correct weighted sum calculation for H2 (0.18).
1 mark: Correct output for H2 after applying ReLU (0.18).
1 mark: Correct formula for output node Y (using outputs from H1 and H2 as inputs).
1 mark: Correct weighted sum for Y (0.13).
1 mark: Correct final output value of Y after applying ReLU (0.13).
PastPaper.question 4 · Mathematical/Logic Modeling
7 PastPaper.marks
Reverse Polish Notation (RPN) is used by some compilers for expression evaluation.

1. Convert the following infix expression into Reverse Polish Notation:
(X - Y) * (Z + W) - U / V (3 marks)

2. Evaluate the following RPN expression using a stack, showing the stack contents after each of the operations (- , * , / , -) are performed:
12 4 - 3 2 + * 15 5 / -
(4 marks)
PastPaper.showAnswers

PastPaper.workedSolution

Part 1: Convert to RPN
- Bracket 1: (X - Y) becomes: X Y -
- Bracket 2: (Z + W) becomes: Z W +
- Multiply the two bracket results: X Y - Z W + *
- Division: U / V becomes: U V /
- Subtract the division from the product: X Y - Z W + * U V / -

Part 2: Stack Evaluation of RPN Expression
- Push 12, Push 4.
- Operation '-': Pop 4, Pop 12. Evaluate 12 - 4 = 8. Push 8. Stack: [8]
- Push 3, Push 2.
- Operation '+': Pop 2, Pop 3. Evaluate 3 + 2 = 5. Push 5. Stack: [8, 5]
- Operation '*': Pop 5, Pop 8. Evaluate 8 * 5 = 40. Push 40. Stack: [40]
- Push 15, Push 5.
- Operation '/': Pop 5, Pop 15. Evaluate 15 / 5 = 3. Push 3. Stack: [40, 3]
- Operation '-': Pop 3, Pop 40. Evaluate 40 - 3 = 37. Push 37. Stack: [37]

PastPaper.markingScheme

Part 1:
1 mark: Correct RPN for brackets: X Y - and Z W +
1 mark: Correct division part: U V /
1 mark: Correct final combined expression: X Y - Z W + * U V / -

Part 2:
1 mark: Shows stack contains [8] after the first '-' operation.
1 mark: Shows stack contains [40] after the '*' operation.
1 mark: Shows stack contains [40, 3] after the '/' operation.
1 mark: Correct final answer of 37 after the final '-' operation.
PastPaper.question 5 · Mathematical/Logic Modeling
7 PastPaper.marks
The Diffie-Hellman key exchange is a mathematical algorithm used to establish a shared secret key over an insecure channel.

Two parties, Alice and Bob, agree to use public parameters:
- A prime number, p = 23
- A base generator, g = 5

Alice chooses her private key a = 4.
Bob chooses his private key b = 3.

Using the formula (g^key mod p), show all steps to calculate:
1. Alice's public value, A. (2 marks)
2. Bob's public value, B. (2 marks)
3. The shared secret key, K, from Bob's perspective using Alice's public value. (3 marks)
PastPaper.showAnswers

PastPaper.workedSolution

Part 1: Alice's public value A
Formula: A = g^a mod p
A = 5^4 mod 23
5^4 = 625
625 / 23 = 27.1739...
27 * 23 = 621
625 - 621 = 4
A = 4

Part 2: Bob's public value B
Formula: B = g^b mod p
B = 5^3 mod 23
5^3 = 125
125 / 23 = 5.4347...
5 * 23 = 115
125 - 115 = 10
B = 10

Part 3: Shared secret key K from Bob's perspective
Formula: K = A^b mod p
K = 4^3 mod 23
4^3 = 64
64 / 23 = 2.7826...
2 * 23 = 46
64 - 46 = 18
K = 18

(Verification from Alice's side: K = B^a mod p = 10^4 mod 23 = 10000 mod 23 = 18.)

PastPaper.markingScheme

Part 1:
1 mark: Correct substitution into the formula: 5^4 mod 23.
1 mark: Correct final calculation of A = 4.

Part 2:
1 mark: Correct substitution into the formula: 5^3 mod 23.
1 mark: Correct final calculation of B = 10.

Part 3:
1 mark: Correct formula from Bob's perspective: A^b mod 23.
1 mark: Correct substitution: 4^3 mod 23.
1 mark: Correct final calculation of K = 18.
PastPaper.question 6 · Mathematical/Logic Modeling
7 PastPaper.marks
A binary computer system represents real numbers using normalized floating-point format with:
- A 6-bit mantissa
- A 4-bit exponent
Both values are stored in two's complement.

1. Calculate the largest positive value that can be represented. Show your working by providing the binary representation of the mantissa and exponent, and converting to denary. (3 marks)
2. Calculate the smallest positive non-zero value that can be represented. Show your working by providing the binary representation of the mantissa and exponent, and converting to denary. (3 marks)
3. State the term used when a calculation results in a positive non-zero value that is too small to be represented in this system. (1 mark)
PastPaper.showAnswers

PastPaper.workedSolution

Part 1: Largest positive value
- To maximize a positive normalized floating-point number, we use the largest positive normalized mantissa and the largest exponent.
- Max mantissa (6 bits): 0.11111
- Denary value of mantissa: 0.5 + 0.25 + 0.125 + 0.0625 + 0.03125 = 0.96875 (or 31/32)
- Max exponent (4 bits): 0111 (since MSB is sign bit 0, max value is 7)
- Denary value of exponent: 7
- Final value: 0.96875 * 2^7 = 0.96875 * 128 = 124 (or 31/32 * 128 = 124)

Part 2: Smallest positive non-zero value
- To minimize a positive normalized floating-point number, we use the smallest positive normalized mantissa and the most negative exponent.
- Smallest normalized positive mantissa (6 bits): 0.10000
- Denary value of mantissa: 0.5 (or 1/2)
- Most negative exponent (4 bits): 1000 (representing -8 in two's complement)
- Denary value of exponent: -8
- Final value: 0.5 * 2^-8 = 1/2 * 1/256 = 1/512 = 0.001953125

Part 3: Underflow
- Floating-point underflow (or underflow).

PastPaper.markingScheme

Part 1:
1 mark: Correct binary mantissa (0.11111) and exponent (0111).
1 mark: Correct denary translation of mantissa (0.96875 or 31/32) and exponent (7).
1 mark: Correct final calculation resulting in 124.

Part 2:
1 mark: Correct binary mantissa (0.10000) and exponent (1000).
1 mark: Correct denary translation of mantissa (0.5 or 1/2) and exponent (-8).
1 mark: Correct final calculation resulting in 1/512 (or 0.001953125).

Part 3:
1 mark: Correctly identifies the term as '(floating-point) underflow'.
PastPaper.question 7 · Theory Essay
5.5 PastPaper.marks
Explain how a virtual machine (VM) executes intermediate code (such as Java bytecode) using Just-In-Time (JIT) compilation. In your answer, compare the advantages and disadvantages of JIT compilation to pure interpretation.
PastPaper.showAnswers

PastPaper.workedSolution

Just-In-Time (JIT) compilation is a method used by virtual machines to execute intermediate code efficiently. Instead of interpreting each instruction every time it is encountered, the JIT compiler translates blocks of bytecode into native machine code on the fly, immediately before execution. The VM typically monitors the running program to detect 'hot spots' (such as loops or frequently called methods) and compiles only those parts to optimize performance.

Advantages of JIT compilation compared to pure interpretation:
1. Execution speed: Once code is compiled to native machine code, it runs directly on the hardware's CPU, making it significantly faster than line-by-line interpretation.
2. Dynamic Optimization: The compiler can use actual runtime profile information (e.g., branch statistics, types of objects passing through) to optimize the generated machine code dynamically.

Disadvantages of JIT compilation:
1. Runtime Overhead: Compilation takes place while the program is running, which can cause an initial startup delay or temporary pauses during execution.
2. Memory Footprint: The compiled native code must be cached in the system's random-access memory (RAM), leading to higher memory consumption than pure interpretation.

PastPaper.markingScheme

Award 1 mark per valid point up to a maximum of 5.5 marks:
- JIT compiles intermediate bytecode into native machine code at runtime [1 mark]
- It compiles code 'on the fly' just before execution / focuses on frequently executed 'hot spots' [1 mark]
- Advantage: Much faster execution speed than pure interpretation once compiled [1 mark]
- Advantage: Allows dynamic optimization using real-time profiling data [1 mark]
- Disadvantage: Causes startup delay / runtime compilation overhead [1 mark]
- Disadvantage: Increases memory usage because compiled native code must be cached in RAM [1 mark]
PastPaper.question 8 · Theory Essay
5.5 PastPaper.marks
Explain the process of how a sender's digital certificate is validated by a recipient's web browser when establishing a secure HTTPS connection. Your explanation must include the roles of the Certificate Authority (CA), cryptographic keys, and the digital signature.
PastPaper.showAnswers

PastPaper.workedSolution

When establishing a secure HTTPS connection, the validation process is as follows:
1. The web browser requests a secure connection, and the server (sender) responds by sending its digital certificate.
2. The digital certificate contains the server's public key, identify details of the owner, and a digital signature.
3. The digital signature is created by the Certificate Authority (CA) by hashing the certificate details and encrypting this hash with the CA's private key.
4. The browser has a built-in list of trusted CAs and their corresponding public keys. It uses the correct CA's public key to decrypt the digital signature, which reveals the original hash calculated by the CA.
5. The browser then independently hashes the certificate details itself using the same hashing algorithm.
6. Finally, the browser compares its calculated hash with the decrypted hash. If they are identical, it proves that the certificate was indeed issued by the trusted CA and has not been altered in transit, thus validating the server's public key.

PastPaper.markingScheme

Award 1 mark per valid point up to a maximum of 5.5 marks:
- Browser receives the certificate containing the server's public key and the CA's digital signature [1 mark]
- The digital signature is created by encrypting the certificate hash using the CA's private key [1 mark]
- The browser retrieves the CA's public key from its built-in trusted store [1 mark]
- The browser decrypts the digital signature using the CA's public key to reveal the original hash [1 mark]
- The browser independently calculates a new hash of the received certificate's details [1 mark]
- The browser compares both hashes; a match verifies integrity and authenticity [1 mark]
PastPaper.question 9 · Theory Essay
5.5 PastPaper.marks
Explain the roles and operations of the loss function and the backpropagation algorithm during the training phase of an artificial neural network (ANN).
PastPaper.showAnswers

PastPaper.workedSolution

During the training of an Artificial Neural Network (ANN):

1. Loss Function:
- The loss function (or cost function) is a mathematical metric that evaluates the network's performance. It compares the predicted output generated by the network during forward propagation with the actual target (ground truth) output.
- It outputs a single scalar value representing the error. The goal of training is to minimize this error value.

2. Backpropagation:
- Backpropagation (backward propagation of errors) is the algorithm used to calculate the gradients of the loss function with respect to the network's weights.
- Starting at the output layer, it calculates the error gradient and propagates it backward through each hidden layer toward the input layer.
- It utilizes the chain rule of calculus to compute how much each individual weight contributed to the total loss.
- The calculated gradients are then passed to an optimization algorithm (such as Gradient Descent) which updates the weights in the direction that reduces the loss. This process repeats over many training epochs until the error is minimized to an acceptable level.

PastPaper.markingScheme

Award 1 mark per valid point up to a maximum of 5.5 marks:
- Loss function calculates the mathematical error/difference between the predicted and target outputs [1 mark]
- Backpropagation calculates the gradients of the loss function with respect to the weights [1 mark]
- It propagates errors backward from the output layer through the hidden layers [1 mark]
- Uses the chain rule of calculus to determine each weight's contribution to the error [1 mark]
- Gradients are used by an optimizer (e.g., Gradient Descent) to update the weights [1 mark]
- The process is iterative, repeating over multiple epochs to minimize the overall loss [1 mark]
PastPaper.question 10 · Theory Essay
5.5 PastPaper.marks
Routing is a key component of packet switching. Describe how routing tables are dynamically populated and updated, and contrast the mechanisms of Distance-Vector routing algorithms with Link-State routing algorithms.
PastPaper.showAnswers

PastPaper.workedSolution

Dynamic routing allows routers to automatically discover network paths and update their routing tables to adapt to changes such as link failures or congestion.

1. Distance-Vector Routing:
- Routers determine the distance (metric, such as hop count) and direction (vector, the next-hop router) to destination networks.
- Routers periodically share their entire routing tables, but only with their directly connected immediate neighbors.
- It is simple to configure but suffers from slow convergence and can lead to routing loops (e.g., count-to-infinity problem).

2. Link-State Routing:
- Routers do not share entire tables; instead, they flood link-state packets (LSPs) containing status information of their immediate interfaces to all routers in the routing domain.
- Every router receives these updates and builds an identical, complete database of the network's topology (the link-state database).
- Each router independently runs the Shortest Path First (SPF) algorithm, such as Dijkstra's algorithm, to calculate the optimal path to each destination.
- It converges much faster than Distance-Vector but requires more processing power and memory on routers.

PastPaper.markingScheme

Award 1 mark per valid point up to a maximum of 5.5 marks:
- Dynamic routing tables are populated using automated protocols that share network topology status [1 mark]
- Distance-Vector: Routers periodically send their complete routing tables [1 mark]
- Distance-Vector: Information is shared only with directly connected neighbors [1 mark]
- Link-State: Routers flood status of their local links to all other routers in the network [1 mark]
- Link-State: Every router constructs a complete and identical map of the entire network topology [1 mark]
- Link-State: Routers run Dijkstra's algorithm (or SPF) to calculate optimal paths [1 mark]
PastPaper.question 11 · Theory Essay
5.5 PastPaper.marks
During the compilation process, syntax analysis (parsing) is performed after lexical analysis. Explain how syntax analysis uses context-free grammars (such as Backus-Naur Form) and parse trees to verify the syntax of the source code and detect syntax errors.
PastPaper.showAnswers

PastPaper.workedSolution

Syntax analysis (parsing) is the second stage of compilation:

1. Input:
- The syntax analyzer receives a linear stream of tokens generated during lexical analysis.

2. Context-Free Grammar (CFG) and BNF:
- A context-free grammar, often expressed using Backus-Naur Form (BNF), defines the complete set of structural rules (syntax) of the programming language (e.g., how statements, loops, and expressions must be structured).

3. Parse Tree Construction:
- The syntax analyzer attempts to parse the token stream by grouping tokens into grammatical phrases. It builds a hierarchical structure called a parse tree.
- In a parse tree, leaf nodes represent terminal tokens (such as identifiers or operators) and internal nodes represent non-terminal grammatical rules (such as expressions or statements).

4. Verification and Error Detection:
- If the sequence of tokens can be completely mapped to the grammar rules, a complete parse tree is successfully built, indicating the source code is syntactically correct.
- If a token does not match any allowed grammatical rules at a given position, the parse tree construction fails. The compiler detects this mismatch as a syntax error, records the location (line number/token), and outputs an appropriate error message to assist the programmer.

PastPaper.markingScheme

Award 1 mark per valid point up to a maximum of 5.5 marks:
- Parser takes the output token stream from the lexical analysis phase [1 mark]
- Context-free grammars (such as BNF) define the structural syntax rules of the programming language [1 mark]
- The syntax analyzer attempts to organize tokens into a hierarchical parse tree [1 mark]
- Success in constructing a complete parse tree verifies that the code syntax is correct [1 mark]
- If tokens violate the grammatical rules, a parse tree cannot be fully constructed [1 mark]
- The parser identifies the point of failure, stops/recovers, and reports a syntax error with position details [1 mark]
PastPaper.question 12 · Theory Essay
5.5 PastPaper.marks
Explain why real numbers represented in binary floating-point format are normalized, and describe the trade-offs between precision and range when the allocation of bits between the mantissa and the exponent is modified.
PastPaper.showAnswers

PastPaper.workedSolution

1. Purpose of Normalization:
- Normalization standardizes floating-point numbers so they always begin with the format '0.1...' for positive numbers (in sign-and-magnitude or two's complement where the first two bits are '01') and '1.0...' for negative numbers (where the first two bits are '10' in two's complement).
- Unique Representation: It ensures that each real number has one, and only one, unique representation in memory. This simplifies operations like comparisons.
- Maximum Precision: By shifting the mantissa to eliminate leading redundant zeros (or ones) and adjusting the exponent accordingly, it ensures that the maximum number of significant bits is preserved within the allocated mantissa size.

2. Bit Allocation Trade-Offs (with a fixed total word size):
- There is a zero-sum relationship because the total number of bits is fixed.
- More bits to Mantissa, fewer to Exponent: This increases the precision of the represented numbers because more significant figures can be stored, reducing rounding errors. However, it severely limits the range of numbers that can be represented because the maximum and minimum exponent values are smaller.
- More bits to Exponent, fewer to Mantissa: This increases the range of numbers that can be represented, allowing extremely large or extremely small numbers to be stored. However, it decreases the precision because fewer bits are available to represent the fractional portion of the number, leading to greater rounding errors.

PastPaper.markingScheme

Award 1 mark per valid point up to a maximum of 5.5 marks:
- Normalization formats the mantissa to begin with distinct bits ('01' for positive, '10' for negative in two's complement) [1 mark]
- It ensures a unique binary representation for each numerical value, preventing duplicate representations [1 mark]
- It maximizes precision by removing leading redundant bits, utilizing all available mantissa bits [1 mark]
- The trade-offs apply under a fixed overall word size constraint [1 mark]
- Increasing mantissa bits (at the expense of exponent bits) improves precision but reduces the range of values [1 mark]
- Increasing exponent bits (at the expense of mantissa bits) broadens the range of values but reduces precision [1 mark]

Paper 4 Practical

Implement solutions in Java, Python, or Visual Basic. Screenshots of outputs are required.
3 PastPaper.question · 75 PastPaper.marks
PastPaper.question 1 · Applied Programming Tasks
25 PastPaper.marks
An application requires the management of a circular queue of computer print jobs. Each job has an ID, a priority level, and an estimated print duration in seconds.

1. Create a class `Job` with the following private attributes:
- `JobID` (String, e.g., \"J101\")
- `Priority` (Integer, from 1 to 5, where 5 is highest)
- `Duration` (Integer, in seconds)

Provide a constructor to initialise these attributes, along with appropriate getter methods for each.

2. Create a class `PrintQueue` that implements a circular queue using an array of 10 `Job` objects. It must contain the following private attributes:
- `Queue` (Array of 10 `Job` elements)
- `Head` (Integer, pointing to the first item)
- `Tail` (Integer, pointing to the last item)
- `NumItems` (Integer, counting current jobs in the queue)

Define the following methods:
- A constructor that initialises `Head` to 0, `Tail` to -1, `NumItems` to 0, and sets all elements of `Queue` to `None`/`null`.
- `Enqueue(NewJob : Job) -> Boolean`: Inserts a `Job` at the correct circular position and updates indicators. Returns `True` if successful, or `False` if the queue is full.
- `Dequeue() -> Job`: Removes and returns the next `Job` to be printed. Returns `None`/`null` if the queue is empty.

3. Write a main program to:
- Instantiate a `PrintQueue` object.
- Attempt to add three jobs: J101 (Priority 3, Duration 120), J102 (Priority 5, Duration 45), and J103 (Priority 2, Duration 300).
- Remove (dequeue) the first job and print its ID and execution details.
- Print the current value of `Head`, `Tail`, and `NumItems` to verify circular operations.
PastPaper.showAnswers

PastPaper.workedSolution

### Python Implementation

```python
class Job:
def __init__(self, job_id, priority, duration):
self.__job_id = job_id
self.__priority = priority
self.__duration = duration

def get_job_id(self):
return self.__job_id

def get_priority(self):
return self.__priority

def get_duration(self):
return self.__duration

class PrintQueue:
def __init__(self):
self.__queue = [None] * 10
self.__head = 0
self.__tail = -1
self.__num_items = 0

def enqueue(self, new_job):
if self.__num_items == 10:
return False

self.__tail = (self.__tail + 1) % 10
self.__queue[self.__tail] = new_job
self.__num_items += 1
return True

def dequeue(self):
if self.__num_items == 0:
return None

removed_job = self.__queue[self.__head]
self.__queue[self.__head] = None
self.__head = (self.__head + 1) % 10
self.__num_items -= 1
return removed_job

def print_state(self):
print(f\"Head: {self.__head}, Tail: {self.__tail}, NumItems: {self.__num_items}\")

# Main Program
if __name__ == \"__main__\":
my_queue = PrintQueue()

j1 = Job(\"J101\", 3, 120)
j2 = Job(\"J102\", 5, 45)
j3 = Job(\"J103\", 2, 300)

print(\"Enqueuing J101:\", my_queue.enqueue(j1))
print(\"Enqueuing J102:\", my_queue.enqueue(j2))
print(\"Enqueuing J103:\", my_queue.enqueue(j3))

my_queue.print_state()

dequeued = my_queue.dequeue()
if dequeued is not None:
print(f\"Dequeued Job: {dequeued.get_job_id()} | Priority: {dequeued.get_priority()} | Duration: {dequeued.get_duration()}s\")

my_queue.print_state()
```

PastPaper.markingScheme

### Marking Scheme (25 Marks Total)

**1. Class `Job` Definition [6 Marks]**
- Declaring and encapsulating private variables: `JobID`, `Priority`, `Duration`. (2 marks)
- Constructor correctly accepting parameters and initialising attributes. (2 marks)
- Implementing three correct getter methods. (2 marks)

**2. Class `PrintQueue` Constructor & State [4 Marks]**
- Setting array `Queue` of size 10 to standard default/None/null elements. (1 mark)
- Initialising `Head` to 0, `Tail` to -1, and `NumItems` to 0. (3 marks)

**3. `Enqueue` Method logic [6 Marks]**
- Check for queue full check (`NumItems == 10`) returning False. (2 marks)
- Correctly updating pointer with wrap-around calculation: `(Tail + 1) % 10`. (2 marks)
- Inserting job, incrementing `NumItems`, and returning `True`. (2 marks)

**4. `Dequeue` Method logic [5 Marks]**
- Checking if empty (`NumItems == 0`) returning None/null. (1 mark)
- Storing reference to job at `Head`. (1 mark)
- Updating `Head` pointer with wrap-around logic: `(Head + 1) % 10`. (2 marks)
- Decrementing `NumItems` and returning the retrieved job object. (1 mark)

**5. Main Program & Testing [4 Marks]**
- Correctly instantiating objects and testing operations sequentially. (2 marks)
- Outputting values indicating expected state (`Head` moves to 1, `Tail` at 2, `NumItems` becomes 2 after dequeue). (2 marks)
PastPaper.question 2 · Applied Programming Tasks
25 PastPaper.marks
A program implements a binary search tree using a static array of node records. Each element in the array represents a node in the tree and contains data and pointer components.

1. Create a class `TreeNode` that represents a node. It must have the following public attributes:
- `Data` (String)
- `LeftPointer` (Integer)
- `RightPointer` (Integer)

Write a constructor for `TreeNode` that takes `NodeData` as a parameter, sets `Data` to this value, and initialises both pointer fields to `-1` (indicating null pointers).

2. Set up a global 1D array named `Tree` consisting of 15 elements of type `TreeNode`. Declare a global variable `RootPointer` (Integer) and initialised to `-1`. Declare a global variable `FreePointer` (Integer) and initialised to `0`.

3. Write a procedure `InsertNode(NewData : String)` that:
- Places the data into the node at index `FreePointer` in the global array `Tree`.
- Traverses the tree starting from `RootPointer` to update the parent's `LeftPointer` or `RightPointer` correctly using alphabetical comparison rules.
- Updates the `FreePointer` to point to the next free array space.
- Handles the edge case of an empty tree where the first node becomes root.

4. Write a recursive procedure `InOrder(Pointer : Integer)` that traverses and prints the contents of the tree alphabetically.

5. Test your program in the main code by inserting the following items in this sequence: \"Mango\", \"Apple\", \"Peach\", \"Banana\", \"Cherry\". Perform an In-Order traversal starting from the root and capture the screenshot of the program output.
PastPaper.showAnswers

PastPaper.workedSolution

### Python Implementation

```python
class TreeNode:
def __init__(self, node_data):
self.Data = node_data
self.LeftPointer = -1
self.RightPointer = -1

Tree = [TreeNode(\"\") for _ in range(15)]
RootPointer = -1
FreePointer = 0

def InsertNode(NewData):
global RootPointer, FreePointer, Tree

if FreePointer >= 15:
print(\"Tree is full\")
return

# Setup the new node at the free slot
Tree[FreePointer] = TreeNode(NewData)

if RootPointer == -1:
RootPointer = FreePointer
FreePointer += 1
else:
Current = RootPointer
Inserted = False
while not Inserted:
if NewData < Tree[Current].Data:
if Tree[Current].LeftPointer == -1:
Tree[Current].LeftPointer = FreePointer
Inserted = True
else:
Current = Tree[Current].LeftPointer
else:
if Tree[Current].RightPointer == -1:
Tree[Current].RightPointer = FreePointer
Inserted = True
else:
Current = Tree[Current].RightPointer
FreePointer += 1

def InOrder(Pointer):
global Tree
if Pointer != -1:
InOrder(Tree[Pointer].LeftPointer)
print(Tree[Pointer].Data)
InOrder(Tree[Pointer].RightPointer)

# Main Execution
if __name__ == \"__main__\":
InsertNode(\"Mango\")
InsertNode(\"Apple\")
InsertNode(\"Peach\")
InsertNode(\"Banana\")
InsertNode(\"Cherry\")

print(\"In-Order Traversal Contents:\")
InOrder(RootPointer)
```

PastPaper.markingScheme

### Marking Scheme (25 Marks Total)

**1. Class `TreeNode` Implementation [4 Marks]**
- Attributes declared correctly as specified (Data, LeftPointer, RightPointer). (2 marks)
- Constructor initialises attributes with default values of pointers to -1. (2 marks)

**2. Setup Array and Pointers [4 Marks]**
- Global declaration of `Tree` with size 15. (2 marks)
- Setting `RootPointer` to -1 and `FreePointer` to 0. (2 marks)

**3. `InsertNode` Procedure Logic [10 Marks]**
- Checking array limits to ensure no out-of-bounds error. (1 mark)
- Assigning the new element at the current free space correctly. (2 marks)
- Checking if tree is empty (`RootPointer == -1`) and setting root. (2 marks)
- Iterative loop traversal logic using left/right pointer directions based on data values. (3 marks)
- Storing the reference index and updating `FreePointer` index by increment. (2 marks)

**4. Recursive `InOrder` Traversal [4 Marks]**
- Base condition checking for null pointers (`Pointer != -1`). (1 mark)
- Correct recursive call order (Left branch first, action on node, Right branch next). (3 marks)

**5. Main Execution and Testing [3 Marks]**
- Calling insert methods in the exact sequence requested. (1 mark)
- Outputs the expected alphabetical ordered strings: Apple, Banana, Cherry, Mango, Peach. (2 marks)
PastPaper.question 3 · Applied Programming Tasks
25 PastPaper.marks
A student database stores examination names and scores in a sequential text file. You are required to design an application to read, sort, and search this record system using an object-oriented approach and sorting/searching algorithms.

1. Create a class `StudentRecord` with private attributes `Name` (String) and `Score` (Integer). Define the constructor and standard getter methods.

2. Write a function `ReadResults(Filename : String)` that:
- Reads elements from the specified file. Each line contains name and score comma-separated (e.g. `David,87`).
- Populates an array `RecordArray` of 30 `StudentRecord` objects.
- Uses exception handling (`Try-Catch` or equivalent) to manage file loading errors. Returns the number of records populated.

3. Write a procedure `InsertionSort(RecordCount : Integer)` that sorts the global array of `StudentRecord` elements in descending order of their `Score` attribute. Use insertion sort.

4. Write a recursive function `BinarySearch(NameTarget : String, Low : Integer, High : Integer) -> Integer` that searches the populated `RecordArray` alphabetically by Name. It should return the array index of the element if found, or `-1` if not found.

5. Write a main procedure to test all algorithms. Read a sample set of lines, sort them, print the top score, and run a search test.
PastPaper.showAnswers

PastPaper.workedSolution

### Python Implementation

```python
import os

class StudentRecord:
def __init__(self, name, score):
self.__name = name
self.__score = score

def get_name(self):
return self.__name

def get_score(self):
return self.__score

RecordArray = [None] * 30

def ReadResults(filename):
global RecordArray
count = 0
try:
with open(filename, 'r') as file:
for line in file:
if count >= 30:
break
parts = line.strip().split(',')
if len(parts) == 2:
name = parts[0]
score = int(parts[1])
RecordArray[count] = StudentRecord(name, score)
count += 1
return count
except IOError:
print(\"Error: File could not be opened.\")
return 0

def InsertionSort(record_count):
global RecordArray
for i in range(1, record_count):
key_item = RecordArray[i]
j = i - 1
# Sorting by descending score value
while j >= 0 and RecordArray[j].get_score() < key_item.get_score():
RecordArray[j + 1] = RecordArray[j]
j -= 1
RecordArray[j + 1] = key_item

def BinarySearch(name_target, low, high):
global RecordArray
if low > high:
return -1
mid = (low + high) // 2
if RecordArray[mid].get_name() == name_target:
return mid
elif RecordArray[mid].get_name() > name_target:
return BinarySearch(name_target, low, mid - 1)
else:
return BinarySearch(name_target, mid + 1, high)

# Main Setup and Execution
if __name__ == \"__main__\":
# Create sample results.txt for test compatibility
with open(\"results.txt\", \"w\") as f:
f.write(\"David,87\
Alice,95\
Charlie,72\
Bob,90\
\")

records_loaded = ReadResults(\"results.txt\")
print(f\"Loaded {records_loaded} records.\")

InsertionSort(records_loaded)
print(\"Sorted Records (Descending Scores):\")
for idx in range(records_loaded):
rec = RecordArray[idx]
print(f\"{rec.get_name()}: {rec.get_score()}\")

# Sort array alphabetically to perform Binary Search on Name
# Note: Binary search requires sorted keys
# In exams, ensure arrays are correctly prepared before binary searching
# Let's simple-sort the names to verify binary search logic
RecordArray[:records_loaded] = sorted(RecordArray[:records_loaded], key=lambda x: x.get_name())
print(\"\
Sorted alphabetically for Binary Search:\")
for idx in range(records_loaded):
rec = RecordArray[idx]
print(f\"Index {idx}: {rec.get_name()}\")

found_idx = BinarySearch(\"Charlie\", 0, records_loaded - 1)
print(f\"\
Searching for 'Charlie'. Found at index: {found_idx}\")
```

PastPaper.markingScheme

### Marking Scheme (25 Marks Total)

**1. Class implementation [4 Marks]**
- Attributes declared private and initialised in constructor. (2 marks)
- Getters properly declared and returning correct attributes. (2 marks)

**2. File Reader Logic [6 Marks]**
- Attempting to open file with structural try-except constructs. (2 marks)
- Correctly parsing/splitting CSV string types, converting scores to int. (2 marks)
- Safe bounds handling avoiding exceeding index index 30. (1 mark)
- Keeping counter tracking size, and returning active record load size. (1 mark)

**3. Insertion Sort Implementation [6 Marks]**
- Correctly nested outer and inner loop iteration layout. (2 marks)
- Standard shifting element mechanics matching target item swap bounds. (2 marks)
- Directional check inequality ensuring descending sorting behavior (`RecordArray[j].get_score() < key_item.get_score()`). (2 marks)

**4. Recursive Binary Search [6 Marks]**
- Correct calculation of middle index using division base index arithmetic. (1 mark)
- Base terminal check for values not present returning -1 when limits collide. (1 mark)
- Comparison logic checking target key relative to dynamic array values. (2 marks)
- Recursive calls passing appropriate range variations (`mid - 1` and `mid + 1`). (2 marks)

**5. Complete Main testing logic [3 Marks]**
- Calling the operations, executing program print statements, demonstrating sorted result array metrics. (3 marks)

PastPaper.sampleCTATitle

PastPaper.sampleCTADescription

PastPaper.sampleStickyMessage

PastPaper.stickyCtaText