CSS Prepare

optional · CSS study notes

II.2 Problem Solving & Program Design

⬆️ P-I.II. Programming Fundamentals · Question Bank · Chapter II (2016–2026)

🧠

Remember: Define → design → dry-run → code.

Start here — what you should be able to do

  • Represent the same algorithm in words, pseudocode and a flowchart.
  • Explain finiteness, definiteness, input, output and effectiveness.
  • Break a large problem into small testable modules.

Reading order: foundation checks → full notes and examples → exam traps → self-test without notes → past-paper answers. All sections below remain part of the topic; code examples are kept in full.

Foundation checks

A reusable design answer

  1. State inputs, outputs and assumptions.
  2. Write the algorithm in numbered steps.
  3. Draw or describe the matching flowchart.
  4. Trace one normal case and one boundary case.
  5. Explain termination and why the output is correct.

Example: maximum of A and B must also work when A = B; either equal value is the maximum.

Complexity basics: a fixed comparison is O(1); one traversal of n items is O(n). Two nested loops are not automatically O(n²)—count their actual iterations.

1. Core Concepts

  • Algorithm: a finite, ordered sequence of unambiguous steps to solve a problem
  • Flowchart: graphical representation of an algorithm using standard symbols
  • Pseudocode: informal, structured English-like description of an algorithm's logic, independent of any specific programming language syntax
  • Top-down design / Stepwise refinement: breaking a large problem into smaller sub-problems (modules), then refining each module in successive steps of detail until it's simple enough to code directly
  • Modularity: dividing a program into independent, reusable modules/functions — improves readability, testing, and maintenance

2. Properties of a Good Algorithm

  • Finiteness — must terminate after a finite number of steps
  • Definiteness — every step must be precisely and unambiguously defined
  • Input — zero or more well-defined inputs
  • Output — one or more well-defined outputs
  • Effectiveness — each step must be basic enough to be carried out, in principle, by a person using pencil and paper

3. Flowchart Symbols

SymbolShapeMeaning
Oval / TerminatorRounded endsStart / End of the algorithm
ParallelogramSlanted sidesInput / Output
RectangleStraight sidesProcess / Computation / Assignment
DiamondRhombusDecision (Yes/No branch)
ArrowLine with arrowheadFlow of control/direction
CircleSmall circleConnector (joins flow across a page break)

4. Pseudocode Conventions

  • Uses plain English keywords like BEGIN/END, IF/ELSE/ENDIF, WHILE/ENDWHILE, READ, WRITE/PRINT
  • Indentation shows nesting/structure, just like real code
  • No strict syntax rules — the goal is clarity of logic, not compilability

5. Worked Example: Find the Largest of Two Numbers

Algorithm:

  1. Start
  2. Input two numbers A and B
  3. If A > B then largest = A, else largest = B
  4. Output largest
  5. Stop

Pseudocode:

BEGIN
  READ A, B
  IF A > B THEN
    largest = A
  ELSE
    largest = B
  ENDIF
  WRITE largest
END

Flowchart (textual): Start → Input A, B → Decision: A > B? → (Yes) largest = A / (No) largest = B → Output largest → End

6. 💻 Code Examples: C & C++

Coding the "Find the Largest of Two Numbers" algorithm from the pseudocode/flowchart above:

C:

#include <stdio.h>
int main(void) {
    int a, b, largest;
    printf("Enter two numbers: ");
    scanf("%d %d", &a, &b);
    if (a > b)
        largest = a;
    else
        largest = b;
    printf("Largest = %d\n", largest);
    return 0;
}

C++:

#include <iostream>
using namespace std;
int main() {
    int a, b, largest;
    cout << "Enter two numbers: ";
    cin >> a >> b;
    largest = (a > b) ? a : b;   // ternary version of the same IF-ELSE decision
    cout << "Largest = " << largest << endl;
    return 0;
}
  • Notice the code maps directly onto the pseudocode: READ A, B → scanf/cin; IF A>B...ELSE...ENDIF → if-else; WRITE largest → printf/cout

7. MCQ Traps

  • A flowchart is a diagram; pseudocode is text — both represent the same underlying algorithm, just in different notations
  • Pseudocode has no fixed syntax standard — it is meant to be readable, not compilable, unlike real source code
  • The diamond shape is reserved for decisions only — never used for input/output or process steps
  • Top-down design works from the general problem down to specific steps; it is a design strategy, not a testing technique
  • An algorithm that never terminates (infinite loop with no exit) violates the finiteness property and is not considered a valid algorithm

8. ✅ Self-Test Questions (with Answers)

Q1. List the five properties every valid algorithm must satisfy.

Answer — key points

  • Formalised by Donald Knuth, these five criteria separate a genuine algorithm from a mere set of instructions.
  • If even one fails, the procedure is not an algorithm.
  • Finiteness — it must terminate after a finite number of steps; an endless process is not an algorithm
  • Definiteness — every step must be precise and unambiguous, with exactly one interpretation ("add a little salt" fails this test)
  • Input — it must have zero or more well-defined inputs, supplied before or during execution
  • Output — it must produce one or more well-defined outputs bearing a specified relation to the inputs
  • Effectiveness — each step must be basic enough to be carried out, in principle, by a person with pencil and paper in finite time
// VALID: finite, definite, 1 input, 1 output, elementary steps
int factorial(int n) {
    int f = 1;
    for (int i = 2; i <= n; i++) f *= i;   // terminates after n-1 passes
    return f;
}
// factorial(5) -> 120

// NOT an algorithm: violates FINITENESS -- never terminates
// int i = 1;  while (i > 0) { cout << i; }
  • MCQ trap: the Input property allows zero inputs (a procedure that merely prints "Hello World" or generates the first 10 primes is still an algorithm), but the Output property demands at least one — an algorithm producing nothing is useless by definition.
  • Exam answers often confuse this asymmetry: zero or more inputs, one or more outputs.

Q2. Which flowchart symbol represents a decision, and which represents input/output?

Answer

  • Decision: diamond containing a condition; a Boolean decision normally has Yes/No exits.
  • Input/output: parallelogram; its wording tells you whether data is read or written.
  • Process: rectangle.
  • Start/end: terminator.
  • Connectors: labelled connectors avoid long crossing arrows; circle commonly means an on-page connector.
  • Qualification: general flowchart notations can include multiway decisions; “exactly two exits” describes the Boolean examples here.
SymbolRepresentsExitsExample text inside
Oval (terminator)Start / EndOneStart, Stop
ParallelogramInput / OutputOneRead A, B / Print sum
RectangleProcess or assignmentOnesum = a + b
DiamondDecision (condition)TWO (Yes / No)Is A greater than B?
CircleConnector across pagesOneA
cin >> a >> b;        // parallelogram: Input
if (a > b)            // diamond: Decision -> two branches
     cout << a;       // parallelogram: Output
else cout << b;       // parallelogram: Output

MCQ trap: the diamond is reserved for decisions only — never for input/output or processing. Conversely, the rectangle never holds a condition. Remember also that looping reuses the diamond plus a backward arrow; there is no dedicated loop symbol in standard flowcharting.

Q3. Write pseudocode to find the largest of three numbers.

Answer — key points

  • The standard solution uses nested selection: compare the first two numbers to find a provisional maximum, then compare that winner against the third.
  • Only two comparisons are ever needed, and every path through the logic assigns largest exactly once, so no value can be left undefined.

Pseudocode:

BEGIN
  READ A, B, C
  IF A > B THEN
     IF A > C THEN
        largest = A
     ELSE
        largest = C
     ENDIF
  ELSE
     IF B > C THEN
        largest = B
     ELSE
        largest = C
     ENDIF
  ENDIF
  WRITE largest
END

C++ implementation:

#include <iostream>
using namespace std;

int main() {
    int a, b, c, largest;
    cout << "Enter three numbers: ";
    cin >> a >> b >> c;

    if (a > b) largest = (a > c) ? a : c;
    else       largest = (b > c) ? b : c;

    cout << "Largest = " << largest << endl;
    return 0;
}
// Input: 12 45 30   ->   Largest = 45

Dry run for A=12, B=45, C=30: A > B → 12 > 45 is false, so take the ELSE branch → test B > C → 45 > 30 is true → largest = B = 45 → output 45.

  • An equally acceptable running-maximum form scales to n numbers: largest = A; IF B > largest THEN largest = B; IF C > largest THEN largest = C
  • MCQ trap: a chain written as IF A>B AND A>C without a final ELSE leaves largest unassigned when the condition fails — every branch must produce a value. Note too that with > (not >=) ties are still handled correctly, since equal values make either choice right.

Q4. What is the difference between top-down design and stepwise refinement, if any?

Answer — key points

  • The two terms describe the same design philosophy viewed from different angles, and most textbooks treat them as near-synonyms — which is exactly why examiners ask.
  • Top-down design names the overall strategy: start from the complete problem at the highest level of abstraction and decompose it into major sub-problems (modules), each of which is decomposed further, producing a hierarchy or structure chart.
  • Stepwise refinement names the technique or process by which that decomposition is actually carried out: take one statement of the solution and rewrite it in progressively greater detail, one level at a time, until every step is elementary enough to be coded directly as a statement or function.
AspectTop-Down DesignStepwise Refinement
NatureOverall strategy / direction of workThe iterative technique used to apply it
EmphasisSplitting a problem into modules (structure)Adding detail level by level (elaboration)
ResultA module hierarchy / structure chartPseudocode refined down to codable steps
Credited toStructured programming movementNiklaus Wirth, 1971
// Level 1 (top): "Process student results"
// Level 2 (refined): readMarks -> computeAverage -> assignGrade -> display
int  readMarks(int m[], int n);
double computeAverage(const int m[], int n);
char assignGrade(double avg);
void display(double avg, char grade);

MCQ trap: top-down design is a design strategy, not a testing method — do not confuse it with top-down testing. Its opposite is bottom-up design, which builds and tests small reusable components first and assembles them upward.

Q5. Why is pseudocode considered language-independent while actual source code is not?

Answer — key points

  • Pseudocode is a structured, English-like description of an algorithm written for human readers, not for a compiler.
  • It has no fixed syntax standard: there is no official keyword list, no punctuation rules, no type declarations and no compiler to satisfy — the only requirement is that the logic be unambiguous.
  • Because it commits to no vocabulary of any one language, the same pseudocode can be handed to a C, C++, Java or Python programmer and each will produce a working implementation.
  • Source code, by contrast, is written for a specific translator: it must obey that language's exact grammar, reserved words, type system and library names, and a single misplaced semicolon makes it fail to compile.
AspectPseudocodeSource Code
AudienceHumans (designers, reviewers)The compiler / interpreter
Syntax rulesNone fixed; informal conventions onlyStrict and enforced
Executable?NoYes, after translation
Stage of useDesign / planning stageImplementation stage
PortabilityFully language-independentTied to one language
// Pseudocode:  IF A > B THEN WRITE A ELSE WRITE B ENDIF
// Same logic, now bound to C++ syntax and its iostream library:
if (a > b) cout << a;
else       cout << b;

MCQ trap: pseudocode and a flowchart are two different notations for the same algorithm — one textual, one graphical. Neither is "more correct"; pseudocode scales better to long algorithms, flowcharts show branching visually.

Recall check and coverage

  • Explain the three learning outcomes at the top without looking.
  • Reproduce one example or trace and test a boundary case.
  • Answer each self-test, then compare with the key.
  • Attempt each recorded past-paper task on this page.

Recorded written references: No direct written record in this topic's current notes. These concepts support the chapter's programming questions.

Evidence limit: this page preserves the question records found in your Notion notes. Disputed labels and questions not checked against original PDFs remain flagged in the Question Bank; this is not a claim of exhaustive original-paper verification.