An algorithm is easier to design when its input, output, state changes, decisions, and stopping rule are visible before code is written.
What you will be able to do
- Identify an algorithm's valid inputs, required outputs, ordered steps, decisions, and repetition.
- Write and trace clear pseudocode that transforms input state into the specified output.
- Check termination and test an algorithm with ordinary, empty, boundary, and invalid-input cases.
01
Start with the problem contract
Before writing steps, state the problem as a relationship between permitted inputs and required outputs. For a largest-number task, the input might be a non-empty list of numbers and the output must be one number equal to the greatest value in that list. The words non-empty and number are part of the contract, not decoration. They define what the procedure must accept. A correct result for one example is not enough: the algorithm must return a correct output for every input inside the declared scope. This contract gives you a stable target for design, tracing, tests, and later implementation in any programming language.
02
Recognize a reusable algorithm
An algorithm is a finite, communicable procedure for solving every permitted instance of a problem. A single answer such as 42 is not an algorithm, and neither is a private intuition that another person cannot follow. The procedure must be reusable with different valid inputs and precise enough that its actions can be carried out consistently. Finite does not mean that every input takes the same number of steps. It means the procedure has a route to completion for inputs in scope. This distinction separates an algorithm from a worked answer, an open-ended activity, or an instruction that can repeat forever without progress.
03
Transform state through ordered steps
Beginner algorithms are easiest to inspect when each action has a clear place in an ordered sequence. An action may read input, create an initial value, compare two values, update state, or produce output. Order matters: computing a total before reading the values cannot work, and returning a result before the loop finishes can omit later input. Name the state that each step reads and changes. Then ask what must be true immediately before and after that action. This small discipline exposes missing initialization, early output, and updates performed in the wrong branch before those mistakes become hidden inside program syntax.
04
Use decisions to choose a path
A conditional selects among alternative actions using a Boolean condition or a matching case. Write the condition so its true and false meanings are unambiguous. In a maximum-value procedure, if the current item is greater than the best value seen so far, update the best value; otherwise leave it unchanged. The branch does not repeat by itself and it does not describe vague intent such as handle the value. It names a test and the action taken for each relevant outcome. When branches overlap or leave an input uncovered, make the priority or fallback explicit so two readers execute the same procedure.
05
Repeat work with a visible stopping rule
Iteration repeats a body for each item in a finite collection or while a condition remains true. A collection loop can stop when no items remain. A condition-controlled loop needs an update that moves state toward a false condition. For example, while attempts are below three must increase attempts on every route that repeats. If one branch skips the update, that branch may never terminate. State what changes during each repetition, what remains true, and what ends the loop. This makes repetition easier to trace and prevents a loop from being treated as magic that somehow knows when the task is complete.
06
Write pseudocode for people first
Pseudocode communicates the procedure without depending on the punctuation of one programming language. Use one action per line, consistent names, visible indentation for branches and loops, and an explicit return or output step. Prefer set total to zero over initialize accumulator because the first version shows both the state and its value. Avoid details that do not affect the reasoning, but do not hide essential actions behind phrases such as process the data. Clear pseudocode can be translated later because it already exposes input, state, conditions, updates, repetition, and output. Its purpose is shared understanding, not imitation of source code.
07
Build a maximum-value procedure
For input [7, 2, 11, 4], set best to the first item, 7. Examine each remaining item in order. Two is not greater than best, so best stays 7. Eleven is greater, so best becomes 11. Four is not greater, so best remains 11. After the collection is exhausted, output 11. Initializing from the first item avoids inventing a sentinel value that might be outside the problem contract. The example shows how the branch and loop cooperate, but it is only one execution. It helps reveal the procedure; it does not prove that every permitted list produces the correct maximum.
08
Trace input, state, and output
A trace table records enough state to replay one execution. For the maximum procedure, useful columns are current item, best before comparison, branch result, and best after comparison. Start with the selected input and initial state, add one row after each meaningful step, then record the final output. If the observed result differs from the expected result, the first row where state diverges identifies the faulty action more precisely than rereading the whole procedure. Keep the table focused: record values that influence later behavior, not every label in the problem description. A trace is repeatable evidence for a selected case, not a universal proof.
09
Demonstrate why repetition ends
For every loop, identify a decreasing amount of work or state that moves toward the stopping condition. A for-each loop over a finite list consumes one remaining item per repetition. A while loop might reduce remaining retries or increase an index toward a known length. Check every branch that can repeat: each must preserve progress or exit. Saying the loop should finish is not evidence. A termination check names the finite collection or progress measure and shows that repeated execution cannot avoid the end forever. If no such argument exists, revise the loop before relying on its output.
10
Name expected results before execution
A useful test states the input, the expected output or behavior, and the comparison with the actual result. Write the expectation before running the procedure so the observed output does not quietly redefine success. For a maximum algorithm, input [7, 2, 11, 4] should produce 11. For a one-item list [5], the expected output is 5. If an empty list is outside the contract, the expected behavior might be a clear rejection rather than a numeric result. Repeatable checks turn a vague claim that it seems to work into evidence another person can reproduce.
11
Select cases that challenge assumptions
A compact beginner test set includes an ordinary case plus relevant empty, boundary, and invalid-input cases. Ordinary data checks the intended path. A boundary such as one item tests the smallest valid collection. An empty collection checks either explicit support or correct rejection. Invalid input checks the contract instead of pretending all data is valid. Add cases that exercise both sides of important branches: values already in order, a new maximum at the end, duplicate maximum values, and negative numbers when they are allowed. More tests are not automatically better; choose cases that expose different assumptions and state transitions.
12
Connect examples to a correctness argument
Testing can reveal defects, but passing selected examples does not establish correctness for every valid input. Pair tests with a short argument tied to the problem contract. In the maximum procedure, best starts as a value from the list. After each comparison, best equals the greatest value among the items examined so far. When no items remain, the examined portion is the entire list, so best is the required output. The loop terminates because a finite collection loses one unexamined item per repetition. This argument, the trace, and the varied tests support different questions: what must be true, what happened in one run, and which assumptions were challenged.