FAC1003 — Programming Revision Questions
Source style: Adapted from the Revision (Part B) slides. Each question gives a real-world scenario, specifies required sub-functions (void/non-void, pass-by-value, recursion, pointers), and expects a complete C++ program with example output.
Section A — Modular Functions (Non-Void + Void)
Q1 — Electricity Bill Calculator
A utility company wants a C++ program to calculate residential electricity bills. The company charges:
| Usage (kWh) | Rate (RM/kWh) |
|---|---|
| First 200 kWh | 0.218 |
| Next 100 kWh (201–300) | 0.334 |
| Above 300 kWh | 0.516 |
The company also applies a fixed monthly charge of RM5.00 for all customers. Customers who use more than 600 kWh receive an additional 5% surcharge on the total bill (excluding the fixed charge).
Task:
Write a complete C++ program that does the following:
-
Ask the user to enter:
- Customer name
- Total electricity usage in kWh (as a double)
-
Use a non-void function named
calculateCharge(double usage)that:- Returns the total consumption charge based on the tiered rates above
- (The fixed charge and surcharge are applied separately — not inside this function)
-
Use a non-void function named
calculateSurcharge(double charge)that:- Returns 5% of the charge if usage exceeds 600 kWh
- Returns 0 otherwise
-
Use a void function named
displayBill(string name, double usage, double charge, double surcharge)that:- Displays the customer name
- Shows a breakdown of usage, tiered charge, fixed charge (RM5.00), surcharge, and total amount
- Formats all monetary values to 2 decimal places
All values are passed by value.
Example output:
Enter customer name: Aisha
Enter total electricity usage (kWh): 450
--- Electricity Bill ---
Customer Name: Aisha
Usage: 450.00 kWh
Consumption Charge: RM140.20
Fixed Charge: RM5.00
Surcharge: RM0.00 (usage ≤ 600 kWh)
Total Amount: RM145.20
Example output (with surcharge):
Enter customer name: Beng
Enter total electricity usage (kWh): 720
--- Electricity Bill ---
Customer Name: Beng
Usage: 720.00 kWh
Consumption Charge: RM272.72
Fixed Charge: RM5.00
Surcharge: RM13.64 (5% of consumption charge)
Total Amount: RM291.36
Q2 — Loan Repayment Calculator
A bank offers personal loans with the following terms:
- Loan amounts between RM1,000 and RM50,000
- Annual interest rate: 4.5% for loans ≤ RM10,000, 3.9% for loans > RM10,000
- Loan tenure: 6, 12, 24, or 36 months
The monthly payment is calculated using the formula:
monthlyPayment = (loanAmount + totalInterest) / tenureMonths
where totalInterest = loanAmount × annualRate × (tenureMonths / 12).
Write a complete C++ program that does the following:
-
Ask the user to enter:
- Customer name
- Loan amount (RM)
- Loan tenure in months (6, 12, 24, or 36 — the program MUST validate this)
-
Use a non-void function named
getInterestRate(double amount)that:- Returns the applicable annual interest rate based on loan amount
- Returns
-1.0if the loan amount is outside the valid range
-
Use a non-void function named
calculateMonthlyPayment(double amount, double rate, int tenure)that:- Computes and returns the monthly payment using the formula above
-
Use a void function named
displayLoanSummary(string name, double amount, int tenure, double rate, double monthly)that:- Displays a complete loan summary table
- Shows: loan amount, annual rate, tenure, total interest paid, total repayment, and monthly payment
- Formats all monetary values to 2 decimal places
Validation rules:
- If the user enters an invalid loan amount (< 1000 or > 50000), the program should display
"Invalid loan amount. Must be between RM1,000 and RM50,000."and exit. - If the user enters an invalid tenure (not 6, 12, 24, or 36), the program should display
"Invalid tenure. Must be 6, 12, 24, or 36 months."and keep asking until a valid value is entered.
Example output:
Enter customer name: Chan
Enter loan amount (RM): 15000
Enter loan tenure (months): 24
--- Loan Summary ---
Customer: Chan
Loan Amount: RM15000.00
Annual Interest Rate: 3.90%
Tenure: 24 months
Total Interest: RM1170.00
Total Repayment: RM16170.00
Monthly Payment: RM673.75
Section B — Recursion
Q3 — Digit Sum & Digital Root
Write a C++ program that processes a positive integer entered by the user using recursion. The program has two tasks:
Task A — Sum of Digits: Compute the sum of all digits of the number recursively. Task B — Digital Root: Keep summing the digits until a single digit remains (the digital root).
For example:
- Number: 4723
- Digit sum: 4 + 7 + 2 + 3 = 16
- Digital root: 1 + 6 = 7
Requirements:
-
Ask the user to enter a positive integer (no validation needed — assume valid input).
-
Use a recursive non-void function
int sumOfDigits(int n)that:- Returns the sum of all digits of
n - Base case: if
n == 0, return 0 - Recursive case: return
(n % 10) + sumOfDigits(n / 10)
- Returns the sum of all digits of
-
Use a recursive non-void function
int digitalRoot(int n)that:- If
n < 10, returnn - Otherwise, return
digitalRoot(sumOfDigits(n))
- If
-
Use a void function
displayDigitAnalysis(int original)that:- Displays the number entered
- Shows the step-by-step digit sum calculation: each digit separated by
+ - Shows the sum of digits
- Shows the digital root with its step-by-step reduction
Example output:
Enter a positive integer: 4723
--- Digit Analysis ---
Number: 4723
Digit Sum: 4 + 7 + 2 + 3 = 16
Digital Root: 16 → 1 + 6 = 7
Final Digital Root: 7
Example output (single digit):
Enter a positive integer: 9
--- Digit Analysis ---
Number: 9
Digit Sum: 9 = 9
Digital Root: 9 (already a single digit)
Final Digital Root: 9
Q4 — Recursive Prime Factorisation
Write a C++ program that recursively decomposes a positive integer into its prime factors.
Prime factorisation is the process of breaking a number into the product of its prime factors:
- 12 = 2 × 2 × 3
- 30 = 2 × 3 × 5
- 100 = 2 × 2 × 5 × 5
- 97 = 97 (prime — no factorisation)
Requirements:
-
Ask the user to enter a positive integer greater than 1. If the user enters a number ≤ 1, display
"Please enter a number greater than 1."and ask again until valid input is given. -
Use a recursive non-void function
bool isPrime(int n, int divisor = 2)that:- Returns
trueifnis prime,falseotherwise - Base cases: if
n <= 2, returnn == 2; ifn % divisor == 0, returnfalse - Recursive case: return
isPrime(n, divisor + 1) - Only check divisors up to
sqrt(n)— stop recursion whendivisor * divisor > n
- Returns
-
Use a recursive void function
void factorise(int n, bool first = true)that:- If
n == 1, return (done) - If
nis prime, printnand return - Otherwise, find the smallest divisor
dofn(starting from 2) - Print
d, then recursively callfactorise(n / d, false) - Print
×between factors — thefirstparameter controls whether a×is printed before the factor
- If
-
Use a void function
void displayFactorisation(int n)that:- Calls
factorise(n)to print the prime factors - Prints
n =followed by the factorisation - If the number is prime, prints
n = n (prime)instead
- Calls
Example output:
Enter a positive integer (> 1): 84
84 = 2 × 2 × 3 × 7
Example output (prime):
Enter a positive integer (> 1): 97
97 = 97 (prime)
Example output (invalid → retry):
Enter a positive integer (> 1): 1
Please enter a number greater than 1.
Enter a positive integer (> 1): -5
Please enter a number greater than 1.
Enter a positive integer (> 1): 60
60 = 2 × 2 × 3 × 5
Section C — Pointers & Dynamic 2D Arrays
Q5 — Temperature Anomaly Tracker
A climate research centre records daily temperature anomalies across multiple weather stations. Each station takes measurements at different times of day. Write a C++ program that processes this data using dynamic 2D arrays and pointer notation only.
Requirements:
-
The program shall first prompt the user to enter:
- The number of weather stations
- The number of daily readings (each station has the same number of readings)
-
Based on these values, dynamically allocate a 2D array of doubles. The memory MUST be allocated and accessed strictly using pointer notation (i.e.,
*(*(arr + i) + j), NOTarr[i][j]). -
The program shall then read the readings (temperature anomalies in °C) for each station across all daily readings.
-
For each station, compute:
- Mean temperature anomaly
- Maximum anomaly (highest positive value)
- Minimum anomaly (lowest negative value — or 0 if all readings are positive)
- Range (max - min)
-
Classify each station based on its mean anomaly:
Mean Anomaly (°C) Classification > +2.0 Extreme Warming +0.5 to +2.0 Moderate Warming -0.5 to +0.5 Stable -2.0 to -0.5 Moderate Cooling < -2.0 Extreme Cooling -
Use a void function
void displayStationReport(double* anomalies, int numReadings, int stationIndex)that:- Takes a pointer to a single row of the 2D array (one station's data)
- Computes and displays the mean, max, min, range, and classification for that station
-
Memory cleanup: Deallocate the 2D array after processing.
Hint: To allocate a 2D array using pointers:
double** data = new double*[numStations];
for (int i = 0; i < numStations; i++)
data[i] = new double[numReadings];
But all access must use pointer arithmetic: *(*(data + i) + j).
Example output:
Enter number of weather stations: 3
Enter number of daily readings: 4
Station 1, Reading 1: 1.2
Station 1, Reading 2: 2.5
Station 1, Reading 3: 3.1
Station 1, Reading 4: 2.8
Station 2, Reading 1: -0.5
Station 2, Reading 2: -1.2
Station 2, Reading 3: 0.3
Station 2, Reading 4: -0.8
Station 3, Reading 1: 3.5
Station 3, Reading 2: 4.2
Station 3, Reading 3: 3.9
Station 3, Reading 4: 4.8
--- Station Report ---
Station 1: Mean = 2.40°C | Max = 3.10°C | Min = 1.20°C | Range = 1.90°C | Moderate Warming
Station 2: Mean = -0.55°C | Max = 0.30°C | Min = -1.20°C | Range = 1.50°C | Moderate Cooling
Station 3: Mean = 4.10°C | Max = 4.80°C | Min = 3.50°C | Range = 1.30°C | Extreme Warming
Q6 — Sparse Matrix Compression (Dynamic Pointer Structure)
[!warning] Hard This question combines dynamic memory allocation, pointers, and structured programming. It is more difficult than a typical exam question — treat it as a stretch exercise.
A sparse matrix is a matrix where most elements are zero. Instead of storing all the zeros, we can use a compressed representation: store only the non-zero values along with their row and column positions.
Write a C++ program that converts a regular 2D matrix into a compressed sparse representation using dynamic arrays and pointer notation.
Requirements:
-
Ask the user to enter the dimensions of a matrix:
- Number of rows
- Number of columns
-
Dynamically allocate a 2D integer array (
int**) and read its elements from the user. -
After reading the full matrix, count the number of non-zero elements.
-
Dynamically allocate three 1D arrays using pointers:
int* values— stores the non-zero valuesint* rowIndices— stores the row index of each non-zero valueint* colIndices— stores the column index of each non-zero value
The size of each array should be exactly the number of non-zero elements.
-
Use a void function
void compressMatrix(int** matrix, int rows, int cols, int*& values, int*& rowIndices, int*& colIndices, int& nonZeroCount)that:- Scans the matrix row by row
- For each non-zero element, appends its value, row index, and column index to the respective dynamic arrays
- The function parameters
values,rowIndices,colIndicesare passed by reference (they will be allocated inside the function)
-
Use a void function
void displayMatrix(int** matrix, int rows, int cols)that:- Displays the full matrix in grid format
-
Use a void function
void displayCompressed(int* values, int* rowIndices, int* colIndices, int nonZeroCount)that:- Displays the compressed representation as a table
-
Use a void function
void reconstructAndDisplay(int* values, int* rowIndices, int* colIndices, int nonZeroCount, int rows, int cols)that:- Reconstructs the matrix from the compressed representation
- Displays it — it should match the original matrix exactly
-
Memory cleanup: Deallocate ALL dynamically allocated memory (the original 2D array AND the three compressed arrays).
Example output:
Enter number of rows: 3
Enter number of columns: 4
Row 0:
Col 0: 0
Col 1: 0
Col 2: 5
Col 3: 0
Row 1:
Col 0: 0
Col 1: 0
Col 2: 0
Col 3: 0
Row 2:
Col 0: 3
Col 1: 0
Col 2: 0
Col 3: 8
Original Matrix:
0 0 5 0
0 0 0 0
3 0 0 8
Compressed Representation (Non-zero elements: 3):
Value Row Col
5 0 2
3 2 0
8 2 3
Reconstructed Matrix:
0 0 5 0
0 0 0 0
3 0 0 8
Matrices match!
Example output (all zeros):
Enter number of rows: 2
Enter number of columns: 2
Row 0:
Col 0: 0
Col 1: 0
Row 1:
Col 0: 0
Col 1: 0
Original Matrix:
0 0
0 0
No non-zero elements found. Matrix is entirely zero.