NivaarExam PrepOfficial exam papers ↗

25-Comp-A4 Program Design and Data Structures · December 2014

Question 1 of 9: Programming — Sliding-Scale Commission and a Check Digit

Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)

Notes on this paper

Paper format. 98-Comp-A4 Program Design and Data Structures, December 2014 — 3 hours, closed book, no calculator permitted. Nine questions, each of equal weight (20 marks); candidates answer any six, so a complete paper is 120 marks. Pseudocode or any high-level language is accepted, and the examiner's note states explicitly that marking emphasises the operation of the program, not syntactic details. All nine questions are answered below, because the whole set is the more useful revision resource. Answers are given in C or C++ as the question dictates; each is compilable as written, but a clear, correctly reasoned pseudocode answer would earn the same marks.

Reference texts for this subject.

  • Cormen, Leiserson, Rivest & Stein, Introduction to Algorithms, 4th ed. — tree traversals (ch. 12), partitioning (ch. 7), asymptotic analysis (ch. 3).
  • Weiss, Data Structures and Algorithm Analysis in C, 2nd ed. — linked lists (ch. 3), binary search trees (ch. 4).
  • Deitel & Deitel, C++ How to Program, 10th ed. — class design and operator overloading (ch. 9–10), file streams (ch. 14).
  • Kernighan & Ritchie, The C Programming Language, 2nd ed. — character I/O idioms (ch. 1, 7), pointers and structures (ch. 5–6).
  • Stroustrup, The C++ Programming Language, 4th ed. — value semantics and const-correctness (ch. 16–18).

The Computer Engineering citation list is built around architecture and networking texts (Patterson & Hennessy, Tanenbaum, Mano); this subject is programming and data structures, so the works above are cited instead.

Question 1: Programming — Sliding-Scale Commission and a Check Digit (20 marks: (a) 10, (b) 10)

Question text not reproduced: the examination questions are © Engineers and Geoscientists BC. Open the official past paper (linked at the top of this page) to read the question, then follow the worked solution below.

Given. For (a), a six-bracket commission scale keyed on the transaction amount, each bracket contributing a fixed base plus a percentage of the whole amount, with an overriding minimum charge of $39. For (b), an identifying number whose final digit is a modulo-7 check digit over all the digits that precede it.

Commission scale as printed
Transaction amountBaseRate on the whole amount
Under $2,500$301.70%
$2,500 to $6,250$560.66%
$6,250 to $20,000$760.34%
$20,000 to $50,000$1000.22%
$50,000 to $500,000$1550.11%
Over $500,000$2550.09%
Minimum charge $39 in every bracket

Find. A program for each part: (a) reads an amount and prints the commission to the cent; (b) reads a ticket number one digit at a time and prints Valid or Invalid.

Approach. Hold the commission scale as parallel arrays and select the bracket with a linear scan, then apply the minimum charge as a final clamp; for the check digit, fold the digits into a running remainder with Horner's rule modulo 7 so the number itself is never stored.

(a) Commission on a sliding scale (10 marks)

  1. Resolve the bracket boundaries before writing any code. The printed scale names $6,250 in two adjacent rows (and likewise $2,500, $20,000, $50,000, $500,000), so the boundaries are ambiguous as written. Adopt the ordinary financial reading — each bracket is lower-inclusive and upper-exclusive, so an amount of exactly $6,250 attracts the $76 + 0.34% rate. This choice costs nothing, because the scale turns out to be continuous at every boundary.
  2. Check the scale for continuity. At each boundary the two adjacent formulas agree, which is what stops a client paying less by declaring a larger trade: $$b_{k}+r_{k}B = b_{k+1}+r_{k+1}B$$ where $b_k$ is the base, $r_k$ the rate and $B$ the boundary. At $B = 2500$: $30 + 0.0170(2500) = 72.50$ and $56 + 0.0066(2500) = 72.50$; at $B = 6250$ both give $97.25$; at $B = 20{,}000$ both give $144.00$; at $B = 50{,}000$ both give $210.00$; at $B = 500{,}000$ both give $705.00$. $$\boxed{\text{the scale is continuous at all five boundaries}}$$ It follows that commission rises monotonically with the amount, so the bracket-boundary convention chosen in step 1 changes nothing.
  3. Find where the minimum charge actually binds. The floor matters only in the lowest bracket, where it displaces the formula until $$30 + 0.0170A = 39 \quad\Longrightarrow\quad A = \frac{9}{0.0170} = 529.41$$ so every transaction below about $529.41 pays the flat $39, and above it the formula governs. Applying the clamp after the bracket arithmetic, as the code does, handles this automatically.
  4. Write the program. The scale lives in three parallel arrays, so the loop that selects a bracket is three lines and a rate change is a one-character edit.
    #include <stdio.h>
    
    #define N_TIERS 6
    
    int main(void)
    {
        /* Upper bound of each bracket (exclusive), fixed base, percentage rate.
           Holding the scale as DATA rather than as a chain of if/else keeps the
           policy in one place: a rate change edits one array element. */
        const double upper[N_TIERS] = {2500.0, 6250.0, 20000.0,
                                       50000.0, 500000.0, 1.0e30};
        const double base [N_TIERS] = {  30.0,   56.0,    76.0,
                                        100.0,  155.0,   255.0};
        const double rate [N_TIERS] = {   1.70,   0.66,    0.34,
                                          0.22,   0.11,    0.09};
        const double MIN_CHARGE = 39.0;
    
        double amount, commission;
        int i;
    
        printf("Enter the amount of the transaction: ");
        if (scanf("%lf", &amount) != 1 || amount < 0.0) {
            printf("That is not a valid transaction amount.\n");
            return 1;
        }
    
        /* Locate the bracket: the first one whose upper bound the amount has
           not reached. The sentinel 1.0e30 guarantees this loop terminates. */
        for (i = 0; i < N_TIERS - 1 && amount >= upper[i]; i++)
            ;
    
        commission = base[i] + rate[i] / 100.0 * amount;
    
        if (commission < MIN_CHARGE)        /* the floor, applied last */
            commission = MIN_CHARGE;
    
        printf("Commission is: $%.2f\n", commission);
        return 0;
    }
  5. Test against the paper's own example. An amount of 3000 falls in the second bracket, giving $$C = 56 + 0.0066(3000) = 56 + 19.80 = 75.80$$ $$\boxed{C(3000) = 75.80\ \text{dollars}}$$ which is not the $166.00 the question prints. Working backwards, the printed figure is reproduced exactly by an amount ten times larger: $100 + 0.0022(30{,}000) = 100 + 66 = 166.00$ to the cent. The example has lost a trailing zero — the answer belongs to a $30,000 transaction.

Check: the question's worked example is internally inconsistent, and the scale is taken as authoritative. The paper prints “3000” against a commission of $166.00, but under its own printed scale $3,000 yields $75.80. Since $100 + 0.22\% \times 30{,}000 = 166.00$ exactly, the transaction amount — not the commission — is the misprint. The program above is written to the scale, which is the specification; both figures are reported in the results table so a marker can see the discrepancy was noticed rather than missed. An exam candidate should state this assumption on the answer paper, as the paper's own Note 1 invites.

(b) Validating the ticket check digit (10 marks)

  1. See why the number cannot simply be read as an integer. A ticket number such as 47715497443 has eleven digits and exceeds $2^{31}-1 = 2{,}147{,}483{,}647$, so scanf into an int overflows. This is exactly why the question hints at reading one digit at a time.
  2. Fold the digits with Horner's rule, reduced at every step. Because remainder arithmetic commutes with the digit-by-digit construction of a number, the running value $$r_{k} = (10\,r_{k-1} + d_{k}) \bmod 7, \qquad r_{-1}=0$$ never exceeds 69 and yet ends at the true remainder of the whole group of digits. For the leading ten digits of the example, 4771549744, the recurrence terminates at $$\boxed{r = 3}$$ matching the remainder the question quotes.
  3. Separate the check digit from the digits it checks. The program does not know the number's length in advance, so it keeps the most recent digit in prev and folds it into $r$ only when a further digit arrives. At end of input prev is the check digit and $r$ is the remainder of everything before it — one pass, no array, any length.
    #include <stdio.h>
    #include <ctype.h>
    
    int main(void)
    {
        int c, r = 0, prev = -1, ndigits = 0;
    
        printf("Enter ticket number: ");
    
        /* One digit at a time, as the hint directs. `prev` deliberately lags one
           digit behind the stream: when the stream ends, `prev` holds the check
           digit and `r` holds the remainder of everything that preceded it, so a
           single pass computes both without ever storing the number. */
        while ((c = getchar()) != EOF && !isspace(c)) {
            if (!isdigit(c)) {
                printf("That is not a ticket number.\n");
                return 1;
            }
            if (prev >= 0)
                r = (r * 10 + prev) % 7;    /* fold in the digit before this one */
            prev = c - '0';
            ndigits++;
        }
    
        if (ndigits < 2) {
            printf("That is not a ticket number.\n");
            return 1;
        }
    
        printf(prev == r ? "Valid\n" : "Invalid\n");
        return 0;
    }
  4. Confirm both printed cases. For 47715497443 the digits before the last give $r = 3$ and the last digit is 3, so the program prints Valid. For 47715497445 the leading digits are identical, so $r$ is still 3 while the check digit is 5; $3 \neq 5$ and the program prints Invalid.
Question 1 — results
QuantityValue
Commission on $400 (floor binds)$39.00
Amount at which the $39 floor stops binding$529.41
Commission on $2,000$64.00
Commission on $3,000 (the amount the paper prints)$75.80
Commission on $10,000$110.00
Commission on $30,000 (reproduces the paper's printed $166.00)$166.00
Commission on $100,000$265.00
Commission on $1,000,000$1,155.00
Remainder for ticket body 47715497443
47715497443Valid
47715497445Invalid
← Paper overview