graph TD
accTitle: Classify an integer as even or odd
accDescr: Start, input integer n, test whether dividing n by 2 leaves no remainder, output Even on the Yes path or Odd on the No path, and then end.
Start(("Start")) --> Input[/"Input integer n"/]
Input --> IsEven{"Does dividing n by 2<br>leave no remainder?"}
IsEven -- "Yes" --> Even[/"Output Even"/]
IsEven -- "No" --> Odd[/"Output Odd"/]
Even --> End(("End"))
Odd --> End
1.2 Designing algorithms
This chapter introduces the fundamental concepts of algorithm development. It explains what algorithms are, how sequence, selection, and iteration organize their control flow, and how pseudocode, flowcharts, and decision tables represent them. A sandwich-making example then develops these ideas progressively, beginning with a simple sequence and adding decisions, repetition, and modular structure.
1.2.1 What is an algorithm?
An algorithm is a finite and explicit procedure for completing a task or solving a problem. It receives permitted inputs, follows stated instructions and decisions, and produces outputs that satisfy the problem’s specification. Finite means that the procedure reaches an end after a limited number of steps for every permitted input. Explicit means that its instructions are precise enough for the intended executor, whether a person or a computer, to carry them out.
Algorithms are used in data processing, artificial intelligence, machine learning, and many other fields. They are essential for developing software applications, analyzing data, and solving complex problems. When several algorithms solve the same problem correctly, they can also be compared by the time, memory, or other resources they require.
Figure 1 shows an incomplete algorithm for making a sandwich. Some required actions and decisions are missing, so the intended executor cannot reliably obtain the required result. At the chosen level of detail, every required action and decision must be stated precisely enough for the intended executor to follow it.
1.2.2 Control structures: sequence, selection, and iteration
Algorithms are designed using common control-flow building blocks. These building blocks form the basis of the structured imperative algorithms used throughout this course: algorithms written as explicit commands organized into clear control-flow structures.
There are three basic building blocks to consider:
- Sequence carries out instructions1 in a stated order.
- Selection chooses a path according to the result of a condition. A condition is a question or statement that the algorithm evaluates as true or false.
- Iteration/Repetition carries out a group of instructions more than once.
There are two types of iteration:
- Definite iteration (also known as count-controlled iteration) repeats a known number of times or once for every item in a bounded collection.
- Indefinite iteration (also known as condition-controlled iteration) continues while or until a condition has a stated result.
Structured imperative algorithms use one or more of these constructs. Longer and more complex algorithms may use these constructs repeatedly.
Selection sort
Motivation. A sorting algorithm must work for every permitted arrangement of its input values. Selection sort gives a small example of how sequence, selection, and iteration combine in one complete procedure.
Start with the cards [5, 3, 4, 1, 2]. A pass is one complete scan of the remaining cards. The unsorted region contains cards whose final positions are still unknown. Its left edge is the boundary. To swap 2 cards means to exchange their positions.
During the first pass, scan the complete row and remember the smallest value seen so far. The remembered value changes from 5 to 3 and then to 1. Swap 1 with the first card. The row becomes [1, 3, 4, 5, 2], and the first position is complete. Scan only the remaining cards, select 2, and swap it into the second position. Continue until no unsorted positions remain. This is the standard selection-sort strategy of repeatedly placing the least remaining item in its final position (NIST Dictionary of Algorithms and Data Structures).
The design can be stated as a repeated procedure:
- scan the unsorted region;
- remember the position of its smallest card;
- swap that card with the first card in the unsorted region; and
- move the boundary of the sorted region one position to the right.
Figure 2 records every pass. The card values are the input. The ordered row is the output. The boundary and remembered minimum are the changing state. The procedure stops after every position has joined the sorted region.
The name selection sort refers to selecting the least remaining item. The procedure uses iteration to scan the unsorted region and conditional selection to update the remembered minimum.
What must change in the procedure to sort the same cards from largest to smallest?
1.2.3 Algorithm representation
Pseudocode
Pseudocode is a detailed yet informal description of an algorithm that uses structured natural language to describe the steps involved in solving a problem. Pseudocode is not a programming language; it expresses an algorithm’s logic without requiring the syntax of a particular programming language.
Pseudocode has no universal syntax, so this book uses one consistent convention. A complete listing begins with Input: and Output: to state what the algorithm receives and produces. Start and End mark its boundaries. Indentation shows which instructions belong inside a selection or repetition. Words such as If, While, and Set describe control flow and state changes in plain English; they are not commands from a particular programming language.
Algorithms written as pseudocode appear as numbered listings. The first algorithm below is Listing 1, and later listings follow in order.
Listing 1 uses this convention to classify an integer as even or odd. The Input: line states that the algorithm receives an integer called \(n\), and the Output: line states the two permitted results. Between Start and End, If introduces a condition. The indented instruction below the condition applies when the answer is Yes; Else introduces the alternative for a No answer.
For example, dividing 8 by 2 leaves no remainder, so the algorithm outputs Even. Dividing 7 by 2 leaves a remainder, so the algorithm follows the Else alternative and outputs Odd. The wording is deliberately independent of any programming language.
Flowcharts
A flowchart is a visual tool that represents the steps of a process or algorithm. It uses symbols and arrows to illustrate the flow of control within a procedure. Flowcharts and pseudocode are alternative representations of an algorithm: a flowchart emphasizes visual paths, whereas pseudocode expresses the same logic as structured text.
In a flowchart, the shape of an element signals the kind of information it contains. This chapter uses the following seven elements consistently:
- Start/End (terminator): Marks where the algorithm begins or ends. It may be drawn as an oval or a rounded rectangle; this book uses rounded rectangles.
- Input/Output: Shows information entering or leaving the algorithm, using a parallelogram.
- Process: Contains an action or calculation, using a rectangle.
- Decision: Contains a condition whose result selects the next path, using a diamond.
- Flow line: Connects one element directly to the next. Its arrowhead shows the direction of control flow.
- On-page connector: Shows that flow continues at a matching labeled circle elsewhere on the same page. It can replace a long or crossing flow line.
- Predefined process (module): Calls a named procedure defined separately, using a rectangle with one vertical line near each side. A procedure is a bounded set of instructions with one specific responsibility.
Figure 3 shows both the conventional shape and a short example for each element. Its panels show the terminator, input/output, process, and decision symbols in Figure 3 (a), Figure 3 (b), Figure 3 (c), and Figure 3 (d). The remaining panels show the flow line, on-page connector, and predefined process in Figure 3 (e), Figure 3 (f), and Figure 3 (g).2
To read a flowchart, begin at Start and follow the arrowheads. At a decision diamond, evaluate its condition and follow the branch labeled with the matching result, such as Yes or No. Continue until you reach End.
The flowchart in Figure 4 represents the same algorithm as the pseudocode in Listing 1. Start at the top, read the integer \(n\), and evaluate the condition in the diamond. A Yes result leads to Output Even; a No result leads to Output Odd. The two paths then meet at End. The arrows show the order in which to visit the elements; they are flow lines, not on-page connectors.
An on-page connector becomes useful when a direct return line would be long or would cross other paths. In Figure 5, the No branch requests a correction and enters the lower connector labeled A. Control resumes at the matching A beside the input step, so the algorithm can read the corrected order without drawing a line around the whole diagram. The connector does not perform an action; it only continues an existing path.
graph TD
accTitle: Order validation with matching on-page connectors
accDescr: Start, input an order, and test whether it is valid. A valid order is accepted and ends. When the order is invalid, the algorithm requests a correction and enters connector A. Flow resumes at the matching connector A before the input step.
Start(("Start")) --> Input[/"Input order"/]
Resume(("A")) --> Input
Input --> IsValid{"Is the order valid?"}
IsValid -- "Yes" --> Accept["Accept order"]
Accept --> End(("End"))
IsValid -- "No" --> Correct["Request correction"]
Correct --> Continue(("A"))
Prefer a direct flow line when it fits without crossing another path. Use an on-page connector only when both matching symbols remain easy to find and the connector removes a long or crossing line. For a responsive web diagram, rearranging the flowchart is often clearer; connectors are most useful in dense layouts and fixed-page print or PDF output.
Decision tables
A decision rule describes one complete case. If all of its conditions hold, the algorithm produces the stated result. A decision table places several rules side by side so their conditions and results can be compared. The layout makes missing, overlapping, and conflicting cases easier to find.
Start with one rule
The pseudocode in Listing 1 and the flowchart in Figure 4 distinguish two cases. If dividing \(n\) by 2 leaves no remainder, the result is Even. If division leaves a remainder, the result is Odd. Table 1 places these two rules side by side.
| Question or result | Each column is one rule. Read downward. | |
|---|---|---|
| Rule 1 | Rule 2 | |
| IF: conditions | ||
| Does dividing integer n by 2 leave no remainder? | Yes | No |
| THEN: result | ||
| Classification | Even | Odd |
| Every integer matches exactly one of the two rules. | ||
Read Rule 1 downward. Its condition entry is Yes, so its result is Even. The input 8 matches Rule 1. Rule 2 requires No and produces Odd, so the input 7 matches Rule 2.
How to read the book’s tables
Each numbered column is one complete rule. Read the column from the IF: conditions group to the THEN: result group. A condition entry gives the answer required by one rule. The result row gives the outcome when every condition entry in that column matches.
Rule numbers identify columns. They indicate priority only when the policy says so.
This book places rules in columns. Some decision-table systems place rules in rows. In either orientation, one rule connects its complete set of conditions to one result.3
When to use a decision table
Use a decision table when several conditions can interact and you need to compare the result for each combination. Use pseudocode for ordered instructions and a flowchart for paths and loop-backs.
When conditions interact
The next decision is whether a traveler should take an umbrella. Rain matters only when the journey includes time outdoors. Rain and outdoor travel each have 2 permitted answers, so Table 2 contains four rules.
| Question or result | Each column is one rule. Read downward. | |||
|---|---|---|---|---|
| Rule 1 | Rule 2 | Rule 3 | Rule 4 | |
| IF: conditions | ||||
| Is rain forecast? | Yes | Yes | No | No |
| Will the journey include time outdoors? | Yes | No | Yes | No |
| THEN: result | ||||
| Umbrella decision | Take an umbrella | Leave the umbrella behind | Leave the umbrella behind | Leave the umbrella behind |
| The four columns contain all four combinations of the two Yes/No conditions. | ||||
Rule 1 says that if rain is forecast and the journey includes time outdoors, then take an umbrella. Rule 2 says that if rain is forecast and the journey stays indoors, then leave the umbrella behind. Rules 3 and 4 give the same result when rain is not forecast. For example, No rain and Yes outdoor travel matches Rule 3.
Check coverage
The input domain contains every value or situation permitted by the problem. The umbrella inputs form the pairs (Yes, Yes), (Yes, No), (No, Yes), and (No, No). Each pair appears once in Table 2. The table therefore has no gap and no overlap.
A complete table gives every permitted input at least one matching rule. Non-overlapping rules give every permitted input at most one match. A complete table with a unique hit policy gives every permitted input exactly one match.4
Test a decision table with at least one input for each rule. Include boundary and unusual permitted values. Suitable even-or-odd checks include 8, 7, 0, and a negative integer. 1.3.1 Why algorithms need to be tested shows how expected and observed results turn these checks into test evidence.
A full table for \(n\) Yes/No conditions contains \(2^n\) raw combinations. Constraints can make some combinations impossible. Remove the impossible combinations to obtain the feasible rules.5
Simplify rules with Any
Rules 3 and 4 in Table 2 both produce Leave the umbrella behind. Their only difference is the outdoor condition. Table 3 combines those columns.
| Question or result | Each column is one rule. Read downward. | ||
|---|---|---|---|
| Rule 1 | Rule 2 | Rule 3 | |
| IF: conditions | |||
| Is rain forecast? | Yes | Yes | No |
| Will the journey include time outdoors? | Yes | No | Any |
| THEN: result | |||
| Umbrella decision | Take an umbrella | Leave the umbrella behind | Leave the umbrella behind |
Any means either permitted value. It does not mean unknown or missing. |
|||
Any means either permitted value for that condition, here Yes or No. It does not mean unknown or missing. Rule 3 in Table 3 expands to (No, Yes) and (No, No). The rule says that if rain is not forecast, then leave the umbrella behind whether outdoor travel is Yes or No. The three columns therefore represent four situations and produce the same results as the complete table.
A library loan requires a valid library card, an available item, and a clear borrower account. The policy reports the first failed prerequisite:
- Refuse the loan if the library card is invalid.
- Otherwise, refuse the loan if the item is unavailable.
- Otherwise, refuse the loan if the borrower account has a problem.
- Otherwise, approve the loan.
Table 4 records this priority.
| Question or result | Each column is one rule. Read downward. | |||
|---|---|---|---|---|
| Rule 1 | Rule 2 | Rule 3 | Rule 4 | |
| IF: conditions | ||||
| Does the borrower have a valid library card? | No | Yes | Yes | Yes |
| Is the requested item available? | Any | No | Yes | Yes |
| Is the borrower's account clear? | Any | Any | No | Yes |
| THEN: result | ||||
| Loan outcome | Refuse: invalid card | Refuse: item unavailable | Refuse: account problem | Approve the loan |
| The conditions in each rule encode the policy's first-failure priority. | ||||
Rule 1 says that an invalid card produces Refuse: invalid card, regardless of the later conditions. Rule 2 requires a valid card and an unavailable item. Rule 3 requires a valid card, an available item, and an account problem. Rule 4 requires all three prerequisites and approves the loan.
The input (No, No, No) matches Rule 1. The input (Yes, No, No) matches Rule 2. In both rules, each Any entry marks a lower-priority condition that cannot change the result. The conditions in each column encode the priority, so the columns do not need to be evaluated in numerical order.
Rule 1 represents 4 raw combinations, Rule 2 represents 2, and Rules 3 and 4 represent 1 each. The four rules therefore cover \(4 + 2 + 1 + 1 = 8\) raw combinations without overlap.
The examples use a limited-entry decision table, where each condition has a small set of permitted entries.
Build a decision table
Build a decision table in this order:
- State the decision, permitted inputs, and required results.
- Write the condition questions and their permitted entries.
- Create one rule for each feasible combination and assign its result.
- Combine equal-result rules with
Anyonly when the combined rule preserves the policy. - Test every rule, then check coverage and overlap.
1.2.4 Example: Sandwich-making algorithm
The following sections develop one peanut butter and jelly sandwich algorithm through five versions. The process begins with a simple sequence and then gains complexity and structure.
The examples use pseudocode for structured steps and flowcharts for paths and loop-backs. Decision tables appear where comparing local rules adds useful information.
Version 1. Making a PB&J sandwich (sequence)
Read the fixed sequence in Listing 2 from its inputs to its output.
Figure 6 translates the pseudocode in Listing 2 into a flowchart, preserving the same sequence from inputs to the completed sandwich.
graph TD
accTitle: PB and J sandwich Version 1 sequence
accDescr: The flow proceeds from ingredients through spreading peanut butter and jelly, adding the second bread slice, and outputting the sandwich.
A((Start)) --> B[/Two Bread Slices, Peanut Butter, Jelly/]
B --> C[Take 1st bread slice]
C --> D[Spread peanut butter on it]
D --> E[Spread jelly on it]
E --> F[Take 2nd bread slice]
F --> G[Put 2nd slice on top of the 1st]
G --> H[/PB&J Sandwich/]
H --> I((End))
Version 1 contains one fixed sequence. The pseudocode states its instructions, and the flowchart shows their order.
Version 2. Toast the bread? (selection)
Listing 2 can be improved by adding a decision point to check if the bread should be toasted before making the sandwich. If the bread is to be toasted, the algorithm will include the toasting step before proceeding to the next steps. Otherwise, the algorithm will skip the toasting step and proceed directly to making the sandwich. Listing 3 shows the resulting selection.
Input: Two Bread Slices, Peanut Butter,
Jelly, Toast Preference (Yes/No)
Output: PB&J Sandwich
Start
If Toast Preference is Yes
Toast the slices of bread
End If
Take 1st bread slice
Spread peanut butter on it
Spread jelly on it
Take 2nd bread slice
Put 2nd slice on top of the 1st
Output PB&J Sandwich
EndFigure 7 translates Listing 3 into a flowchart and makes the new toasting decision and its two paths explicit.
graph TD
accTitle: PB and J sandwich Version 2 with optional toasting
accDescr: A yes or no decision determines whether the bread is toasted before the sandwich-making sequence continues.
A((Start)) --> B[/Two Bread Slices, Peanut Butter,<br>Jelly, Toast Preference/]
B --> C{Toast Bread?}
C -- Yes --> D[Toast the slices of bread]
C -- No --> E[Take 1st bread slice]
D --> E
E --> F[Spread peanut butter on it]
F --> G[Spread jelly on it]
G --> H[Take 2nd bread slice]
H --> I[Put 2nd slice on top of the 1st]
I --> J[/PB&J Sandwich/]
J --> K((End))
The new decision is whether the algorithm should toast the bread. Toast Preference is restricted to Yes or No, so Table 5 contains 2 complete, non-overlapping rules.
| Question or result | Each column is one rule. Read downward. | |
|---|---|---|
| Rule 1 | Rule 2 | |
| IF: conditions | ||
| Is Toast Preference Yes? | Yes | No |
| THEN: result | ||
| Next step | Toast both bread slices | Continue without toasting |
| Toast Preference has two permitted values: Yes and No. | ||
Rule 1 says that if Toast Preference is Yes, then toast both bread slices. Rule 2 says that if Toast Preference is No, then continue without toasting. For example, Toast Preference = Yes matches Rule 1. The table gives the local result. The pseudocode and flowchart show where the decision occurs in the full sequence.
Version 3. Keeping an even spread (condition-controlled repetition)
Listing 3 can be improved by adding a decision point to check if the spread is even on the bread slices. While the spread is not even (i.e., the ingredient is distributed unevenly across the bread’s surface), the algorithm will correct it before proceeding to the next step. Therefore, this correction step is condition-controlled, being repeated until the spread is even. The repeating section is called a loop. Each pass through that section is one iteration. This version assumes that each correction improves the spread and that repeated corrections eventually make it even. Without that progress assumption, the repetition might never stop. Listing 4 shows both spread checks and their repeated correction steps.
Input: Two Bread Slices, Peanut Butter, Jelly,
Toast Preference (Yes/No)
Output: PB&J Sandwich
Start
If Toast Preference is Yes
Toast the slices of bread
End If
Take 1st bread slice
Spread peanut butter on it
While the peanut-butter spread is uneven
Correct the peanut-butter spread
End While
Spread jelly on it
While the jelly spread is uneven
Correct the jelly spread
End While
Take 2nd bread slice
Put 2nd slice on top of the 1st
Output PB&J Sandwich
EndFigure 8 translates Listing 4 into a flowchart and shows how each correction returns to the corresponding evenness check.
graph TD
accTitle: PB and J sandwich Version 3 with even-spread repetition
accDescr: Optional toasting is followed by peanut-butter and jelly spreading loops that repeat corrections until each spread is even.
A((Start)) --> IN[/Two Bread Slices, Peanut Butter,<br>Jelly, Toast Preference/]
IN --> B{Toast Bread?}
B -- Yes --> C[Toast the slices of bread]
B -- No --> D[Take 1st bread slice]
C --> D
D --> E[Spread peanut butter on it]
E --> F{Is the PB<br>spread evenly?}
F -- No --> G[Correct the peanut<br>butter spread]
G --> F
F -- Yes --> H[Spread jelly<br>on it]
H --> I{Is the jelly<br>spread evenly?}
I -- No --> J[Correct the<br>jelly spread]
J --> I
I -- Yes --> K[Take 2nd bread slice]
K --> L[Put 2nd slice on top of the 1st]
L --> OUT[/PB&J Sandwich/]
OUT --> M((End))
Version 3 retains the toast decision already shown in Table 5, so it is not repeated. It adds two local spread decisions. Table 6 answers the first question: Should the algorithm correct the peanut-butter spread?
| Question or result | Each column is one rule. Read downward. | |
|---|---|---|
| Rule 1 | Rule 2 | |
| IF: conditions | ||
| Is the peanut butter spread even? | Yes | No |
| THEN: result | ||
| Next step | Continue to jelly | Correct the peanut-butter spread once |
| The pseudocode and flowchart show the recheck that follows a correction. | ||
Rule 1 says that if the peanut-butter spread is even, then continue to jelly. Rule 2 says that if the spread is uneven, then correct it once. An uneven spread therefore matches Rule 2. The pseudocode and flowchart return from the correction to another evaluation of the condition.
Table 7 answers the second question: Should the algorithm correct the jelly spread? Before reading the result row, predict the result for each condition entry.
| Question or result | Each column is one rule. Read downward. | |
|---|---|---|
| Rule 1 | Rule 2 | |
| IF: conditions | ||
| Is the jelly spread even? | Yes | No |
| THEN: result | ||
| Next step | Continue to the second bread slice | Correct the jelly spread once |
| The pseudocode and flowchart show the recheck that follows a correction. | ||
Rule 1 says that if the jelly spread is even, then continue to the second bread slice. Rule 2 says that if the jelly spread is uneven, then correct it once. An even jelly spread matches Rule 1. The separate tables show that the peanut-butter and jelly checks occur independently. The loop-backs remain in the pseudocode in Listing 4 and the flowchart in Figure 8.
Version 4. Making multiple sandwiches (definite iteration)
Listing 4 can be further enhanced by introducing definite iteration, allowing the algorithm to create multiple sandwiches based on the user’s input. Instead of making just one sandwich, the algorithm will now repeat the process for the number of sandwiches specified by the user. This involves repeating the operations a fixed number of times, which is known as definite iteration.
In this version, the input will include the number of sandwiches to be made, and the entire sandwich-making process will be repeated until the specified number of sandwiches is created. The algorithm will ensure that each sandwich is made according to the steps in Version 3, including checking if the spread is even and toasting the bread if desired.
For Versions 4 and 5, Bread means a supply containing at least two slices for every requested sandwich, and the supply of peanut butter and jelly is assumed to be sufficient. The progress assumption from Version 3 also continues to apply: each correction must move the spread toward an even result.
Listing 5 adds the sandwich count and its stopping condition to the previous version.
Input: Bread, Peanut Butter, Jelly,
Toast Preference (Yes/No),
Number of Sandwiches (non-negative whole number)
Output: Specified Number of PB&J Sandwiches
Start
Set Sandwich Count to 0
While Sandwich Count < Number of Sandwiches
If Toast Preference is Yes
Toast the slices of bread
End If
Take 1st bread slice
Spread peanut butter on it
While the peanut-butter spread is uneven
Correct the peanut-butter spread
End While
Spread jelly on it
While the jelly spread is uneven
Correct the jelly spread
End While
Take 2nd bread slice
Put 2nd slice on top of the 1st
Increment Sandwich Count by 1
End While
Output PB&J Sandwiches
EndFigure 9 translates Listing 5 into a flowchart and shows the definite iteration that repeats until the requested number of sandwiches is complete.
graph TD
accTitle: PB and J sandwich Version 4 with definite iteration
accDescr: The complete sandwich procedure repeats while the sandwich count is lower than the requested non-negative number of sandwiches.
A((Start)) --> IN[/Bread, Peanut Butter,<br>Jelly, Toast Preference,<br>Number of Sandwiches/]
IN --> B[Set <b>Sandwich Count</b> to 0]
B --> C{Is <b>Sandwich Count</b><br>lower than<br><b>Number of Sandwiches</b>?}
C -- Yes --> D{Toast Bread?}
D -- Yes --> E[Toast the slices of bread]
E --> F
D -- No --> F[Take 1st bread slice]
F --> G[Spread peanut butter on it]
G --> H{Is the PB<br>spread evenly?}
H -- No --> I[Correct the peanut<br>butter spread]
I --> H
H -- Yes --> J[Spread jelly<br>on it]
J --> K{Is the jelly<br>spread evenly?}
K -- No --> L[Correct the<br>jelly spread]
L --> K
K -- Yes --> M[Take 2nd bread slice]
M --> N[Put 2nd slice on top of the 1st]
N --> O[Increment <b>Sandwich Count</b> by 1]
O --> C
C -- No --> OUT[/PB&J Sandwiches/]
OUT --> P((End))
The condition Sandwich Count < Number of Sandwiches controls the repetition. The pseudocode and flowchart show when another sandwich starts, when the count changes, and when the algorithm stops.
Version 5. Refactoring with modular algorithms
Listing 5 can be further refined by refactoring the algorithm into modular components. Refactoring involves restructuring the algorithm without changing its intended behavior to improve readability and maintainability. It does not necessarily improve execution efficiency. We can introduce separate algorithms for spreading an ingredient, making a single sandwich, and making multiple sandwiches. This modular approach allows the same procedure to be reused, simplifies maintenance, and makes the overall algorithm more structured and easier to understand.
A procedure is a named, bounded algorithm with a specific responsibility and explicit inputs and outputs. One procedure can call another and use its output.
In this version, the Spread Ingredient algorithm (Listing 6) is responsible for evenly spreading a given ingredient (e.g., peanut butter, jelly) on a single slice of bread. The Make a Sandwich algorithm (Listing 7) uses the Spread Ingredient algorithm to create a single PB&J sandwich. Finally, the Make Multiple Sandwiches algorithm (Listing 8) calls the Make a Sandwich algorithm repeatedly to create the desired number of sandwiches.
This modular design allows us to focus on specific tasks within the sandwich-making process, making the algorithm more flexible and maintainable. Completed Sandwiches is a collection: one value that groups the sandwiches already produced. The Spread Ingredient procedure uses the same progress assumption as Versions 3 and 4, so repeated corrections eventually stop.
Input: Two Bread Slices, Peanut Butter, Jelly,
Toast Preference (Yes/No)
Output: PB&J Sandwich
Start
If Toast Preference is Yes
Toast the slices of bread
End If
Take 1st bread slice
Set 1st bread slice to output of Call "Spread Ingredient"
with 1st bread slice and Peanut Butter
Set 1st bread slice to output of Call "Spread Ingredient"
with 1st bread slice and Jelly
Take 2nd bread slice
Place the second slice on top of the first slice
Output PB&J Sandwich
EndInput: Bread, Peanut Butter, Jelly,
Toast Preference (Yes/No),
Number of Sandwiches (non-negative whole number)
Output: Specified Number of PB&J Sandwiches
Start
Set Sandwich Count to 0
Set Completed Sandwiches to an empty collection
While Sandwich Count < Number of Sandwiches
Take Two Bread Slices from Bread
Set Sandwich to output of Call "Make a Sandwich" with
Two Bread Slices, Peanut Butter, Jelly, and Toast Preference
Add Sandwich to Completed Sandwiches
Increment Sandwich Count by 1
End While
Output Completed Sandwiches
EndFigure 10 combines Listing 6, Listing 7, and Listing 8 in one flowchart, making the reusable calls between the three algorithms explicit.
graph TD
accTitle: Modular PB and J sandwich Version 5
accDescr: Make Multiple Sandwiches calls Make a Sandwich, which calls Spread Ingredient twice, while completed sandwiches are collected until the requested count is reached.
A((Start)) --> IN[/Bread, Peanut Butter,<br>Jelly, Toast Preference,<br>Number of Sandwiches/]
IN --> B[Set <b>Sandwich Count</b> to 0]
B --> BC[Set <b>Completed Sandwiches</b><br>to an empty collection]
BC --> C{Is <b>Sandwich Count</b><br>lower than<br><b>Number of Sandwiches</b>?}
C -- Yes --> TS[Take Two Bread Slices<br>from Bread]
TS --> J[[Set <b>Sandwich</b> to output of Call<br><b>Make a Sandwich</b> with Two Bread Slices,<br>PB, Jelly, Toast Preference]]
J --> L[Add <b>Sandwich</b> to<br><b>Completed Sandwiches</b>]
L --> K[Increment Sandwich Count by 1]
K --> C
C -- No --> OUT[/Completed Sandwiches/]
OUT --> M((End))
%% Keep the three reusable algorithms stacked vertically. These invisible
%% links constrain layout only; the algorithm calls above remain the
%% semantic connections between the modules.
M ~~~ A1
MS8 ~~~ A2
subgraph "Spread Ingredient"
A2((Start)) --> IN2
IN2[/Bread Slice, Ingredient/] --> S1
S1[Apply the ingredient<br>to the bread slice] --> S2{Is the spread even?}
S2 -- No --> S3[Correct the spread]
S3 --> S2
S2 -- Yes --> OUT2[/Bread Slice with<br>Evenly Spread Ingredient/]
OUT2 --> S4((End))
end
subgraph "Make a Sandwich"
A1((Start)) --> IN1
IN1[/Two Bread Slices, Peanut Butter,<br>Jelly, Toast Preference/] --> MS1{Toast Bread?}
MS1 -- Yes --> MS2[Toast the slices<br>of bread]
MS2 --> MS3[Take 1st bread slice]
MS1 -- No --> MS3
MS3 --> MS4[[Set 1st Bread Slice to output of Call<br><b>Spread Ingredient</b> with 1st Bread Slice and PB]]
MS4 --> MS5[[Set 1st Bread Slice to output of Call<br><b>Spread Ingredient</b> with prepared 1st Bread Slice and Jelly]]
MS5 --> MS6[Take 2nd bread slice]
MS6 --> MS7[Put 2nd slice on top of the 1st]
MS7 --> OUT1[/PB&J Sandwich/]
OUT1 --> MS8((End))
end
In the modular version, each decision remains inside the procedure responsible for evaluating it. The listings and Figure 10 show the procedure calls, returns, and repetition.
Algorithms describe procedures independently of a programming language. Their control flow can be organized using sequence, selection, and iteration. A program may implement one or more algorithms while also specifying data, input and output, and interactions with a computing environment.
Module 3 later explains how algorithms are expressed and executed as programs.
Evaluate an algorithm by stating the required result for a chosen input, following the instructions, and comparing the result produced. 1.3.1 Why algorithms need to be tested applies this process to the decisions and repetition introduced in this chapter.
1.2.5 Exercises
1.2.Q1 Choosing an outfit based on weather
Imagine you are getting dressed in the morning, and you decide what to wear (raincoat, jacket, t-shirt) based on the weather (raining, cold, sunny). Write an algorithm that describes this decision-making process.
Listing 9 tests rain before temperature so that each input pair produces one outfit.
Following the pseudocode solution, Figure 11 expresses the same weather decisions as a flowchart.
graph TD
A((Start)) --> IN[/weather/]
IN --> B{Is it raining?}
B -- Yes --> C[/raincoat/]
B -- No --> D{Is it cold?}
D -- Yes --> E[/jacket/]
D -- No --> F[/t-shirt/]
C --> G((End))
E --> G
F --> G
1.2.Q2 Formulate a bottle-filling problem
Write an algorithm for filling a water bottle with cups of water. The algorithm should determine how many cupfuls are needed and explain how to pour the water into the bottle.
Choose the bottle and cup capacities, then create a formulation before writing pseudocode. State:
- the inputs and required outputs;
- the state that changes while the bottle is being filled;
- the rule for each pour, including the final pour; and
- the stopping condition and any assumptions needed to prevent overflow and ensure that the algorithm stops.
Use your model to write pseudocode. Give the final number of cupfuls for the capacities you chose.
Decide what happens when the remaining space in the bottle is smaller than the cup capacity.
Many formulations are valid. One model treats the bottle and cup capacities as positive whole-number inputs. Bottle Volume and Cupfuls form the changing state. Each round fills a cup and pours only the amount that still fits. A partly poured final cup counts as one cupful.
Listing 10 gives pseudocode for this model.
Input: Bottle Capacity, Cup Capacity
Output: Bottle Volume, Cupfuls
Start
Set Bottle Volume to 0
Set Cupfuls to 0
While Bottle Volume < Bottle Capacity
Fill the cup with water
Set Amount to Pour to minimum(Cup Capacity,
Bottle Capacity - Bottle Volume)
Pour Amount to Pour into the bottle
Set Bottle Volume to Bottle Volume + Amount to Pour
Set Cupfuls to Cupfuls + 1
End While
Output Bottle Volume, Cupfuls
EndFor example, a 1,000 mL bottle and a 300 mL cup require 4 cupfuls. The final pour adds 100 mL to the bottle.
1.2.Q3 Fill a bottle by iteration
The previous exercise asked you to choose a model. Use the specified values and rules below for this exercise.
Scenario. A 750-milliliter bottle is filled using a 200-milliliter cup. Each round fills the cup, pours only the amount still needed into the bottle, and counts that cupful. Any water left in the final cup remains in the cup.
Inputs. bottle_capacity = 750 mL and cup_capacity = 200 mL.
Rules and notation. Start with bottle_volume = 0 and cupfuls = 0. In each round, pour minimum(cup_capacity, bottle_capacity - bottle_volume) milliliters and then increase cupfuls by 1. Here, minimum(a, b) means the smaller of a and b.
Assumptions. Capacities are positive whole numbers. No water leaks from the bottle. A partly used final cup still counts as one cupful.
Deliverable. Write pseudocode with a stopping condition. State the final values of bottle_volume and cupfuls, and how much water remains in the final cup. The solution includes a round-by-round trace. 1.3.1 Why algorithms need to be tested uses the same problem to show why the choice of test inputs matters.
Success criteria. The algorithm is designed to stop with exactly 750 mL in the bottle, never overfill it, and count four cupfuls.
The final round is different: only 150 mL is still needed.
Listing 11 implements the specified capacities and stopping rule.
Input: Bottle Capacity, Cup Capacity
Output: Bottle Volume, Cupfuls, Water Remaining in Final Cup
Start
Set Bottle Volume to 0
Set Cupfuls to 0
Set Water Remaining in Final Cup to 0
While Bottle Volume < Bottle Capacity
Set Amount to Pour to minimum(Cup Capacity,
Bottle Capacity - Bottle Volume)
Set Bottle Volume to Bottle Volume + Amount to Pour
Set Cupfuls to Cupfuls + 1
Set Water Remaining in Final Cup to Cup Capacity - Amount to Pour
End While
Output Bottle Volume, Cupfuls, Water Remaining in Final Cup
EndTable 8 records the state after each pass through Listing 11.
| Round | Amount poured (mL) | Bottle volume (mL) | Cupfuls |
|---|---|---|---|
| start | N/A | 0 | 0 |
| 1 | 200 | 200 | 1 |
| 2 | 200 | 400 | 2 |
| 3 | 200 | 600 | 3 |
| 4 | 150 | 750 | 4 |
The final cup contains 50 mL after 150 mL is poured. Because a positive amount is added whenever the bottle is not full, the loop makes progress and reaches its stopping condition.
1.2.Q4 Count rules for three Yes/No conditions
Scenario. A bicycle-sharing service checks three things before unlocking a bicycle:
- Does the rider have a valid pass?
YesorNo - Is a bicycle available?
YesorNo - Is the station open?
YesorNo
Every combination of answers is possible. For example, a rider may have a valid pass even when no bicycle is available.
A raw combination contains one answer for every condition. A full decision table begins with one decision rule for each raw combination. How many rules are needed before cases with the same result are combined?
- 6 rules
- 8 rules
- 9 rules
- 16 rules
Answer: 8 rules.
Count the combinations one condition at a time:
The valid-pass condition has 2 possible answers.
For each of those answers, bicycle availability has 2 possible answers.
For each of those combinations, station status has 2 possible answers.
Multiply the numbers of answers:
\[ 2 \times 2 \times 2 = 8 \]
The calculation can also be written as \(2^3=8\): two possible answers for each of three conditions.
All 8 raw combinations are feasible cases because the scenario rules out nothing. A full table therefore begins with 8 rules. The results are not given, so the minimum number of rules after equal-result cases are combined is unknown.
1.2.Q5 Count rules when conditions have different numbers of options
Scenario. A parcel desk records three pieces of information for each parcel:
- Destination:
Local,National, orInternational - Delivery speed:
StandardorExpress - Fragile:
YesorNo
Every destination can use either delivery speed, and every parcel can be fragile or not fragile.
A raw combination contains one option for every condition. For example, Local, Express, and Yes form one raw combination. A full decision table begins with one decision rule for each raw combination. How many rules are needed before cases with the same result are combined?
- 7 rules
- 8 rules
- 12 rules
- 24 rules
Answer: 12 rules.
Count the available options for each condition:
Destination has 3 options.
Delivery speed has 2 options.
Fragile status has 2 options.
Choose one option from each condition, so multiply the three numbers:
\[ 3 \times 2 \times 2 = 12 \]
Multiplying the numbers of options is called the product rule for counting.
All 12 raw combinations are feasible cases because the scenario rules out nothing. A full table therefore begins with 12 rules. The results are not given, so the minimum number of rules after equal-result cases are combined is unknown.
1.2.Q6 Count only the rules allowed by the scenario
Scenario. A cafeteria records a meal category and whether the meal contains meat or dairy. Use the category supplied by the cafeteria; do not try to infer the category from the ingredients.
The cafeteria allows these combinations:
- A
Standardmeal may contain meat or not and may contain dairy or not. - A
Vegetarianmeal contains no meat but may contain dairy. - A
Veganmeal contains neither meat nor dairy.
A raw combination allowed by these requirements is a feasible case. How many feasible cases are there?
- 4 cases
- 7 cases
- 9 cases
- 12 cases
Answer: 7 feasible cases.
Count the allowed combinations within each meal category:
For
Standard, meat has 2 possible answers and dairy has 2 possible answers:\[ 2 \times 2 = 4 \]
For
Vegetarian, meat must beNo, while dairy may beYesorNo:\[ 1 \times 2 = 2 \]
For
Vegan, both meat and dairy must beNo:\[ 1 \times 1 = 1 \]
Add the allowed combinations:
\[ 4 + 2 + 1 = 7 \]
If the category restrictions were ignored, there would be \(3 \times 2 \times 2=12\) raw combinations. Five of those combinations are not allowed, leaving 7 feasible cases. A full decision table begins with one decision rule for each feasible case, so it begins with 7 rules. The results are not given, so the minimum number of rules after equal-result cases are combined is unknown.
1.2.Q7 Convert a color rule into an algorithm
Table 9 defines the result of combining two different colors. Each input is Red, Yellow, or Blue. Input order does not change the result.
| First color | Second color | Result |
|---|---|---|
| Red | Yellow | Orange |
| Yellow | Blue | Green |
| Blue | Red | Purple |
The algorithm receives color_1 and color_2. Capitalization has already been normalized. A pair is valid when it contains two different listed colors and matches one table row in either order. For a repeated color or any other word, output Invalid combination.
Write pseudocode for the rule. Then give the outputs for (Yellow, Red), (Blue, Yellow), (Red, Red), and (Green, Blue).
Each table row represents two possible input orders.
Listing 12 checks both input orders for each row in Table 9.
Input: Color 1, Color 2
Output: Combined Color or Invalid combination
Start
If (Color 1 is Red and Color 2 is Yellow) or
(Color 1 is Yellow and Color 2 is Red)
Output Orange
Else If (Color 1 is Yellow and Color 2 is Blue) or
(Color 1 is Blue and Color 2 is Yellow)
Output Green
Else If (Color 1 is Blue and Color 2 is Red) or
(Color 1 is Red and Color 2 is Blue)
Output Purple
Else
Output Invalid combination
End If
EndThe requested outputs are Orange, Green, Invalid combination, and Invalid combination. The final Else covers every remaining input.
1.2.Q8 Bulk or cut decision-making
Motivation. In fitness and bodybuilding, deciding whether to bulk (gain muscle) or cut (lose fat) is crucial. This decision is based on several factors, including body fat (BF) percentage, muscle mass (MM), and fitness goals. There are many strategies to help individuals make this decision.
For example, according to “Should You Bulk or Cut?”, the decision-making process involves the following rules:
- For Men:
- Cut if body fat percentage is above 20%.
- Bulk if body fat percentage is below 15%.
- If body fat percentage is between 15% and 20%:
- Bulk if muscle mass is low.
- Cut if muscle mass is high.
- Maintain if muscle mass is moderate.
- For Women:
- Cut if body fat percentage is above 30%.
- Bulk if body fat percentage is below 25%.
- If body fat percentage is between 25% and 30%:
- Bulk if muscle mass is low.
- Cut if muscle mass is high.
- Maintain if muscle mass is moderate.
Problem. Write an algorithm that uses these guidelines to determine whether an individual should bulk or cut. The algorithm takes a person’s gender, body fat percentage, and muscle mass level (low, high, and moderate) as input and determines whether they should bulk, cut, or maintain.
Example Scenarios:
Input: Male, 22% body fat, moderate muscle mass Output: Cut Explanation: For men, body fat above 20% suggests cutting.
Input: Female, 28% body fat, low muscle mass Output: Bulk Explanation: For women with body fat between 25% and 30%, and low muscle mass, bulking is recommended.
Input: Male, 14% body fat, high muscle mass Output: Bulk Explanation: For men, body fat below 15% suggests bulking.
Input: Female, 32% body fat, high muscle mass Output: Cut Explanation: For women, body fat above 30% suggests cutting.
Input: Male, 16% body fat, moderate muscle mass Output: Maintain Explanation: For men, body fat between 15% and 20% and moderate muscle mass suggest maintaining.
Input: Female, 26% body fat, moderate muscle mass Output: Maintain Explanation: For women, body fat between 25% and 30% and moderate muscle mass suggest maintaining.
Listing 13 applies the stated thresholds separately for men and women.
Input: Gender, Body Fat Percentage, Muscle Mass Level
Output: Recommendation (Bulk, Cut, or Maintain)
Start
If Gender is Male
If Body Fat Percentage > 20
Output Cut
Else If Body Fat Percentage < 15
Output Bulk
Else
If Muscle Mass Level is Low
Output Bulk
Else If Muscle Mass Level is High
Output Cut
Else
Output Maintain
End If
End If
Else
If Body Fat Percentage > 30
Output Cut
Else If Body Fat Percentage < 25
Output Bulk
Else
If Muscle Mass Level is Low
Output Bulk
Else If Muscle Mass Level is High
Output Cut
Else
Output Maintain
End If
End If
End If
EndFollowing the pseudocode solution, Figure 12 expresses the same body-composition decisions as a flowchart.
graph TD
A((Start)) --> IN[/"<b>gender</b>,<br><b>BF</b> (bodyFatPercentage),<br><b>MM</b> (muscleMassLevel)"/]
IN --> B{Is<br><b>gender</b><br>`male`?}
B -->|Yes| C{Is<br><b>BF</b> > 20%?}
C ---->|Yes| W[/`Cut`/]
C -->|No| E{Is<br><b>BF</b> < 15%?}
E ---->|Yes| F[/`Bulk`/]
E -->|No| H{Is<br><b>MM</b><br>`low`?}
H ---->|Yes| F
H -->|No| J{Is<br><b>MM</b><br>`high`?}
J ---->|Yes| W
J ---->|No| L[/`Maintain`/]
B -->|No| O{Is<br><b>BF</b> > 30%?}
O -->|Yes| W
O -->|No| Q{Is<br><b>BF</b> < 25%?}
Q ---->|Yes| F
Q -->|No| H
F ----> Z((End))
L ----> Z
W ----> Z
linkStyle 2,3,4,5,6 stroke:blue
linkStyle 11,12,13,14,15 stroke:magenta
1.2.Q9 Warehouse operation management
Motivation. A warehouse team uses a traffic-light model to turn two dashboard percentages—occupancy rate and fill rate—into a status and a response. For this exercise, treat both rates as supplied inputs; you do not need to calculate them.
The model categorizes the warehouse’s status into four levels:
- Green,
- Orange,
- Red, and
- Black.
Evaluate the rows of Table 10 from top to bottom and use the first matching row. This priority rule resolves cases that satisfy more than one condition. Values exactly equal to 85% occupancy or 30% fill do not exceed those thresholds and are therefore Green unless a higher-priority row matches.
| Scenario | Metrics | Action to be taken |
|---|---|---|
| Black | Occupancy rate > 90% AND Fill rate > 35% | Refuse deliveries |
| Red | Occupancy rate > 85% AND Fill rate > 30% | Review inbound plans daily and reduce inbound volume if needed |
| Orange | Occupancy rate > 85% OR Fill rate > 30% | Check the cause and consider moving or consolidating stock |
| Green | Occupancy rate <= 85% AND Fill rate <= 30% | No action needed |
The Traffic Light Model is used in practice by a large e-commerce company. See details at Beekman, Yorick (2023). Accuracy improvement of warehouse capacity calculation using the bin packing problem.
Problem. Write an algorithm that takes the supplied occupancy rate (OR) and fill rate (FR) as input and returns the first matching traffic-light color from Table 10.
Examples:
Input: Occupancy Rate: 92%, Fill Rate: 36% Output: Black Explanation: Both the occupancy rate and fill rate exceed the thresholds for the Black scenario, indicating the most critical state.
Input: Occupancy Rate: 87%, Fill Rate: 32% Output: Red Explanation: Both the occupancy rate and fill rate exceed the thresholds for the Red scenario, requiring several corrective actions.
Input: Occupancy Rate: 88%, Fill Rate: 28% Output: Orange Explanation: The occupancy rate exceeds 85%, falling into the Orange category, which triggers preventive measures.
Input: Occupancy Rate: 80%, Fill Rate: 25% Output: Green Explanation: Both the occupancy rate and fill rate are within the acceptable range, indicating normal operations with no need for intervention.
Input: Occupancy Rate: 85%, Fill Rate: 30% Output: Green Explanation: Equal values do not satisfy the strict greater-than tests.
Listing 14 applies the four outcomes in priority order, which lets you check that each operating condition receives one color.
Following the pseudocode solution, Figure 13 expresses the occupancy- and fill-rate decisions as a flowchart.
graph TD
accTitle: Warehouse traffic-light classification
accDescr: The flowchart checks Black, Red, Orange, and Green conditions in priority order for supplied occupancy and fill rates.
A((Start)) --> IN[/"<b>occupancyRate (OR)</b>, <b>fillRate (FR)</b>"/]
IN --> B{<b>OR</b> > 90%<br>and<br><b>FR</b> > 35%?}
B -->|Yes| C[/`Black`/]
B -->|No| D{<b>OR</b> > 85%<br>and<br><b>FR</b> > 30%?}
D -->|Yes| E[/`Red`/]
D -->|No| F{<b>OR</b> > 85%<br>or<br><b>FR</b> > 30%?}
F -->|Yes| G[/`Orange`/]
F -->|No| H[/`Green`/]
C --> I((End))
E --> I
G --> I
H --> I
1.2.Q11 Design a bounded number-guessing game
Scenario. A classroom game asks a player to guess a hidden whole number from 1 through 100.
Inputs. A valid hidden secret from 1 through 100 and one player entry in each round. The player may make at most seven entries. An entry is valid when it is a whole number from 1 through 100.
Rules and notation. Every entry consumes one round, including an invalid entry. After each entry:
- output
Invalid entrywhen it is outside the permitted domain; - otherwise output
Higherwhen the entry is below the secret; - output
Lowerwhen the entry is above the secret; or - output
Correct in n roundswhen it equals the secret, wherenincludes the successful round.
After seven unsuccessful rounds, output No more attempts and stop.
Assumptions. The secret is supplied by the exercise system and is not changed during play. No random-number algorithm is required.
Deliverable. Write modular pseudocode with a visible stopping condition. State the messages for secret 42 and entries 20, 60, 42.
Success criteria. A correct guess is included in the round count, no more than seven entries are read, every entry produces one message, and the stopping condition is explicit.
Increase the round count immediately after reading an entry. The number of rounds remaining then decreases on every iteration.
Listing 16 defines the reusable procedure for evaluating one entry.
Listing 17 calls the procedure after every entry and stops after a correct entry or 7 rounds.
Input: Secret, Player Entries
Output: Feedback Messages
Start
Set Rounds Used to 0
Set Solved to No
While Rounds Used < 7 and Solved is No
Read Entry
Increment Rounds Used by 1
Set Result to output of Call "Evaluate Guess" with Entry and Secret
If Result is Correct
Output Correct in Rounds Used Rounds
Set Solved to Yes
Else
Output Result
End If
End While
If Solved is No
Output No more attempts
End If
EndFor secret 42, the messages are Higher, Lower, and Correct in 3 rounds. The number of rounds remaining starts at seven and decreases by one after every entry, so the loop performs at most seven iterations.
The flowchart in Figure 14 represents the main procedure. Evaluate Guess applies the entry rules in Listing 16, and the main procedure follows Listing 17.
graph TD
A(("Start")) --> B[/"Input <b>secret</b>"/]
B --> C["Set <b>rounds used</b> to 0"]
C --> D{"Are fewer than 7 rounds used?"}
D -- "Yes" --> E[/"Input <b>entry</b>"/]
E --> F["Increase <b>rounds used</b> by 1"]
F --> G[["Call Evaluate Guess with <b>entry</b> and <b>secret</b>"]]
G --> H{"Is the result Correct?"}
H -- "Yes" --> I[/"Output Correct in <b>rounds used</b> rounds"/]
H -- "No" --> J[/"Output result"/]
J --> D
D -- "No" --> K[/"Output No more attempts"/]
I --> L(("End"))
K --> L
A list is an ordered collection of values. L[i] means the value stored at position i in list L. These exercises number positions from 0, so L[0] is the first value. The length of L is its number of values.
1.2.M1 Pass or fail algorithm
Which of the following correctly represents an algorithm that outputs “Pass” if a student’s score—labeled score—is 50 or above, and “Fail” otherwise? (Note: More than one flowchart may be correct.)
Select the correct flowchart(s) from the options below:
- Flowchart in Figure 15 (a)
- Flowchart in Figure 15 (b)
- Flowchart in Figure 15 (c)
- Flowchart in Figure 15 (d)
- Flowchart in Figure 15 (e)
Figure 15 groups the five candidate flowcharts for comparison.
graph LR
accTitle: Pass-or-fail candidate A
accDescr: Scores at least 50 follow the Pass branch; lower scores follow the Fail branch.
A((Start)) --> B[/score/]
B --> C{"Is score >= 50?"}
C -- Yes --> D[/Pass/]
C -- No --> E[/Fail/]
D --> F((End))
E --> F
graph LR
accTitle: Pass-or-fail candidate B
accDescr: Scores greater than 50 follow the Pass branch; a score of exactly 50 follows the Fail branch.
A((Start)) --> B[/score/]
B --> C{"Is score > 50?"}
C -- Yes --> D[/Pass/]
C -- No --> E[/Fail/]
D --> F((End))
E --> F
graph LR
accTitle: Pass-or-fail candidate C
accDescr: Scores below 50 follow the Fail branch; scores of 50 or more follow the Pass branch.
A((Start)) --> B[/score/]
B --> C{"Is score < 50?"}
C -- Yes --> D[/Fail/]
C -- No --> E[/Pass/]
D --> F((End))
E --> F
graph LR
accTitle: Pass-or-fail candidate D
accDescr: Only a score equal to 50 follows the Pass branch; every other score follows the Fail branch.
A((Start)) --> B[/score/]
B --> C{"Is score = 50?"}
C -- Yes --> D[/Pass/]
C -- No --> E[/Fail/]
D --> F((End))
E --> F
graph LR
accTitle: Pass-or-fail candidate E
accDescr: Scores at least 50 incorrectly follow the Fail branch, while lower scores follow the Pass branch.
A((Start)) --> B[/score/]
B --> C{"Is score >= 50?"}
C -- No --> D[/Pass/]
C -- Yes --> E[/Fail/]
D --> F((End))
E --> F
Answer: Flowcharts in Figure 15 (a) and Figure 15 (c).
In the pass or fail algorithm, we check if a student’s score is 50 or above to determine if they pass or fail. Or, equivalently, we can check if the score is less than 50 to determine if the student fails. Therefore, options A and C are correct representations of the algorithm.
1.2.M2 Linear search algorithm
Which of the following flowcharts correctly represents a linear search algorithm that searches for a specific number called target in a list entitled L? Given a list L and a number target, the algorithm should output “Number found” if target is in the list L, and “Number not found” otherwise.
For example:
- if
L = [1, 2, 3, 4, 5]andtarget = 3, the algorithm should output “Number found”. - if
L = [1, 2, 3, 4, 5]andtarget = 6, the algorithm should output “Number not found”.
You can assume that the list L is:
- Indexed starting from 0.
- Non empty.
Choose the correct flowchart from the options below:
- Flowchart in Figure 16 (a)
- Flowchart in Figure 16 (b)
- Flowchart in Figure 16 (c)
- Flowchart in Figure 16 (d)
Figure 16 groups the four candidate flowcharts for comparison.
graph LR
accTitle: Linear-search candidate A
accDescr: The index starts at zero, advances after each mismatch, reports found on a match, and reports not found after all positions are checked.
A((Start)) --> IN[/L, target/]
IN --> B["Set i to 0"]
B --> C{"Is i<br>equal to<br>L length?"}
C -- Yes --> D[/Number not found/]
C -- No --> E{"Is L[i]<br>equal to<br>target?"}
E -- Yes --> F[/Number found/]
E -- No --> G[Increment i by 1]
G --> C
D --> H((End))
F --> H
graph LR
accTitle: Linear-search candidate B
accDescr: The exhausted-list branch incorrectly outputs Number found even when no value matched the target.
A((Start)) --> IN[/L, target/]
IN --> B[Set i to 0]
B --> C{"Is i<br>less than<br>L length?"}
C -- No --> D[/Number found/]
C -- Yes --> E{"Is L[i]<br>equal to<br>target?"}
E -- Yes --> F[/Number found/]
E -- No --> G[Increment i by 1]
G --> C
D --> H((End))
F --> H
graph LR
accTitle: Linear-search candidate C
accDescr: The first decision tests whether the initial index equals zero and immediately follows the Number not found branch.
A((Start)) --> IN[/L, target/]
IN --> B[Set i to 0]
B --> C{"Is i<br>equal to 0?"}
C -- Yes --> D[/Number not found/]
C -- No --> E{"Is L[i]<br>equal to<br>target?"}
E -- Yes --> F[/Number found/]
E -- No --> G[Decrement i by 1]
G --> C
D --> H((End))
F --> H
graph LR
accTitle: Linear-search candidate D
accDescr: The index starts at zero, so the greater-than-zero test immediately follows the Number not found branch.
A((Start)) --> IN[/L, target/]
IN --> B[Set i to 0]
B --> C{"Is i<br>greater than 0?"}
C -- No --> D[/Number not found/]
C -- Yes --> E{"Is L[i]<br>equal to<br>target?"}
E -- Yes --> F[/Number found/]
E -- No --> G[Decrement i by 1]
G --> C
D --> H((End))
F --> H
Answer: Flowchart in Figure 16 (a).
In the linear search algorithm, we iterate through each element of the list and compare it with the target number. If the element is equal to the target, we output “Number found”; otherwise, we continue searching. Here’s a step-by-step breakdown of the algorithm using an example list L = [1, 2, 3, 4, 5] and a target number 3:
Use Table 12 to compare iteration, l, n, and related results for linear search algorithm.
target = 3 in L = [1, 2, 3, 4, 5].
| Iteration | L | n (L Length) | i | L[i] | target | i = n? | L[i] = target? |
|---|---|---|---|---|---|---|---|
| 1 | 1,2,3,4,5 | 5 | 0 | 1 | 3 | 0 = 5? No! | 1 = 3? No! |
| 2 | 1,2,3,4,5 | 5 | 1 | 2 | 3 | 1 = 5? No! | 2 = 3? No! |
| 3 | 1,2,3,4,5 | 5 | 2 | 3 | 3 | 2 = 5? No! | 3 = 3? Yes! (Found!) |
The table shows the complete trace: the first two comparisons fail, and the third comparison finds target at index 2. The algorithm therefore outputs Number found without checking any later position.
1.2.M3 Finding the max. value in a list
Which of the following flowcharts correctly represents an algorithm for finding the maximum value—labeled max—in a list L? (Note: More than one flowchart may be correct.)
For example:
- if
L = [1, 2, 3, 4, 5], the algorithm should output5. - if
L = [5, 4, 3, 2, 1], the algorithm should output5. - if
L = [1, 3, 2, 5, 4], the algorithm should output5. - if
L = [5, 6], the algorithm should output6.
You can consider that the list L:
- Is non-empty and contains at least two elements.
- Is indexed starting from 0.
Choose the correct flowchart from the options below:
- Flowchart in Figure 17 (a)
- Flowchart in Figure 17 (b)
- Flowchart in Figure 17 (c)
- Flowchart in Figure 17 (d)
- Flowchart in Figure 17 (e)
Figure 17 groups the five candidate flowcharts for comparison.
graph LR
accTitle: Maximum-value candidate A
accDescr: The maximum starts at the first list value, the index starts at one, and larger later values replace the maximum.
A((Start)) --> IN[/L/]
IN --> B[Set max to<br>first element]
B --> C[Set i to 1]
C --> D{"Is i<br>less than<br>L length?"}
D -- No --> E[/Output max/]
D -- Yes --> F{"Is L[i]<br>greater<br>than max?"}
F -- Yes --> G["Set max<br>to L[i]"]
F -- No --> H[Increment i by 1]
G --> H
H --> D
E --> I((End))
graph LR
accTitle: Maximum-value candidate B
accDescr: The maximum starts at the first list value, the index starts at zero, and each larger value replaces the maximum.
A((Start)) --> IN[/L/]
IN --> B[Set max to<br>first element]
B --> C[Set i to 0]
C --> D{"Is i<br>less than<br>L length?"}
D -- No --> E[/Output max/]
D -- Yes --> F{"Is L[i]<br>greater<br>than max?"}
F -- Yes --> G["Set max<br>to L[i]"]
F -- No --> H[Increment i by 1]
G --> H
H --> D
E --> I((End))
graph LR
accTitle: Maximum-value candidate C
accDescr: The maximum starts at zero and the loop continues while the index is not greater than the list length, which can access a position beyond the list.
A((Start)) --> IN[/L/]
IN --> B[Set max to 0]
B --> C[Set i to 1]
C --> D{"Is i<br>greater than<br>L length?"}
D -- Yes --> E[/Output max/]
D -- No --> F{"Is L[i]<br>greater<br>than max?"}
F -- Yes --> G["Set max<br>to L[i]"]
F -- No --> H[Increment i by 1]
G --> H
H --> D
E --> I((End))
graph LR
accTitle: Maximum-value candidate D
accDescr: The maximum starts at zero and is replaced when a list value is smaller, so the logic does not find the greatest value.
A((Start)) --> IN[/L/]
IN --> B[Set max to 0]
B --> C[Set i to 0]
C --> D{"Is i<br>less than<br>L length?"}
D -- No --> E[/Output max/]
D -- Yes --> F{"Is L[i]<br>less than<br>max?"}
F -- Yes --> G["Set max to L[i]"]
F -- No --> H[Increment i by 1]
G --> H
H --> D
E --> I((End))
graph LR
accTitle: Maximum-value candidate E
accDescr: The maximum starts at the first list value but is replaced by smaller values, so it can finish with a value that is not the maximum.
A((Start)) --> IN[/L/]
IN --> B[Set max to<br>first element]
B --> C[Set i to 1]
C --> D{"Is i<br>equal to<br>L length?"}
D -- Yes --> E[/Output max/]
D -- No --> F{"Is L[i]<br>less than<br>max?"}
F -- Yes --> G["Set max<br>to L[i]"]
F -- No --> H[Increment i by 1]
G --> H
H --> D
E --> I((End))
Answer: Flowchart in Figure 17 (a) and Figure 17 (b).
In the linear search algorithm for finding the maximum value in a list, we iterate through each element of the list and compare it with the current maximum value. If the element is greater than the current maximum, we update the maximum value.
Here’s a step-by-step breakdown of the algorithm using an example list L = [1, 5, 3].
Considering Option A
If we consider the flowchart in option A, i is initialized to 1, and max (i.e., the first element of the list, L[0]) is set as the initial maximum value. Then, in iteration 1, we compare L[1] (i.e., 5) with max=L[0] (i.e., 1) and update max if L[1] is greater.
Use Table 13 to compare step, l, n, and related results for finding the max. value in a list.
L = [1, 5, 3].
| Step | L | n (L Length) | i | L[i] | max | i < n? | L[i] > max? |
|---|---|---|---|---|---|---|---|
| 1 | 1,5,3 | 3 | 1 | 5 | 1 | 1 < 3? Yes! | 5 > 1? Yes! |
| 2 | 1,5,3 | 3 | 2 | 3 | 5 | 2 < 3? Yes! | 3 > 5? No! |
| 3 | 1,5,3 | 3 | 3 | Not evaluated | 5 | 3 < 3? No! | Not evaluated |
Considering Option B
If we consider flowchart B, the algorithm starts with i = 0 and max is set to the first element of the list. Then, max is equal to L[i]=L[0]=1.
Notice that the first comparison in this case is redundant (comparing L[0] with max=L[0]), but it doesn’t affect the final result.
Option B therefore performs three loop iterations and four condition checks. Option A avoids the redundant comparison, so it performs two loop iterations and three condition checks.
Table 14 organizes the loop state so you can compare Algorithm B’s redundant first-value check with Algorithm A.
L = [1, 5, 3].
| Step | L | n (L Length) | i | L[i] | max | i < n? | L[i] > max? |
|---|---|---|---|---|---|---|---|
| 1 | 1,5,3 | 3 | 0 | 1 | 1 | 0 < 3? Yes! | 1 > 1? No! |
| 2 | 1,5,3 | 3 | 1 | 5 | 1 | 1 < 3? Yes! | 5 > 1? Yes! |
| 3 | 1,5,3 | 3 | 2 | 3 | 5 | 2 < 3? Yes! | 3 > 5? No! |
| 4 | 1,5,3 | 3 | 3 | Not evaluated | 5 | 3 < 3? No! | Not evaluated |
- Do A and B algorithms work if the list is empty?
- Do A and B algorithms work if the list has only one element?
1.2.M4 Iterative sum algorithm
Figure 18 represents the iterative sum and shows which values change the accumulator. What will be the output if the input—labeled number—is 4?
graph LR
accTitle: Iterative sum of even numbers
accDescr: Starting at one, the algorithm adds even values to the sum, skips odd values, and stops after the supplied number.
A((Start)) --> B[/number/]
B --> C[Set sum to 0]
C --> D[Set i to 1]
D --> E{"Is i<br>less than or<br>equal to<br>number?"}
E -- Yes --> F{"Is i<br>an even<br>number?"}
F -- Yes --> G[Add i<br>to the sum]
F -- No --> H[Keep sum the same]
G --> I[Increase i by one]
E -- No --> J[/sum/]
H --> I
I --> E
J --> K((End))
Choose the correct output:
- 4
- 6
- 8
- 10
- 12
Answer: The output is 6.
In the iterative sum algorithm, we calculate the sum of all even numbers up to a given number. Here’s a step-by-step breakdown of the algorithm using an input of 4:
Use Table 15 to compare iteration, i, i <= 4?, and related results for iterative sum algorithm.
number = 4.
| Iteration | i | i <= 4? | i even? | Sum |
|---|---|---|---|---|
| 1 | 1 | Yes | No | 0 |
| 2 | 2 | Yes | Yes | 2 |
| 3 | 3 | Yes | No | 2 |
| 4 | 4 | Yes | Yes | 6 |
| 5 | 5 | No | - | 6 |
The table shows the complete trace. Only the even values 2 and 4 change the sum, so the final output is 2 + 4 = 6.
1.2.M5 Algorithm X
Figure 19 represents Algorithm X and makes the loop state visible for tracing. What will be the output if the input—labeled number—is 6?
graph TD
accTitle: Fibonacci value at a zero-based position
accDescr: Positions zero and one return directly; later positions repeatedly add the two previous Fibonacci values until reaching the requested position.
A((Start)) --> B[/number/]
B --> C{"Is number<br>less than or<br>equal to 1?"}
C -- Yes --> D[/Return number/]
C -- No --> E[Initialize<br>a to 0]
E --> F[Initialize<br>b to 1]
F --> S[Initialize<br>sum to 0]
S --> G[Set i to 2]
G --> H{Is i<br>less than or<br>equal to<br>number?}
H -- Yes --> I[Set sum to<br>a + b]
I --> J[Set a to b]
J --> K[Set b to sum]
K --> L[Increase i by 1]
L --> H
H -- No --> M[/b/]
D --> N((End))
M --> N
Choose the correct output:
- 5
- 8
- 13
- 21
- 34
Answer: B) 8
Algorithm X returns the Fibonacci number at position number when positions start at 0: positions 0 and 1 contain 0 and 1. Therefore, position 6 contains 8. Here’s a step-by-step breakdown of the algorithm using an input of 6:
Use Table 16 to compare iteration, number, a, and related results for algorithm x.
number = 6.
| Iteration | number | a | b | i | i <= number? | sum (a + b) | a (updated) | b (updated) |
|---|---|---|---|---|---|---|---|---|
| 1 | 6 | 0 | 1 | 2 | yes | 1 | 1 | 1 |
| 2 | 6 | 1 | 1 | 3 | yes | 2 | 1 | 2 |
| 3 | 6 | 1 | 2 | 4 | yes | 3 | 2 | 3 |
| 4 | 6 | 2 | 3 | 5 | yes | 5 | 3 | 5 |
| 5 | 6 | 3 | 5 | 6 | yes | 8 | 5 | 8 |
| 6 | 6 | 5 | 8 | 7 | no | - | - | - |
An instruction states an action for an executor to perform. The executor may be a person or a computer, and a high-level instruction may later be decomposed into more detailed operations.↩︎
ISO 5807:1985 defines symbols and conventions for program and system flowcharts and remains the current confirmed ISO standard. The common names and uses shown here also follow Microsoft’s Basic Flowchart Shapes guidance. Exact drawing styles vary, so a flowchart should use shapes consistently and label every decision branch.↩︎
The conditions-in-rows and rules-in-columns structure follows ISTQB, Certified Tester Foundation Level Syllabus 4.0.1, Section 4.2.3. IBM’s decision-table column guidance shows the alternative rules-in-rows orientation. Camunda’s rule documentation and the Object Management Group’s Decision Model and Notation 1.5 define rules through condition or input entries and result or output entries. Captions, explicit headers, and associated explanations follow the W3C guidance for captions and summaries and the Australian Government Style Manual guidance for tables.↩︎
IBM’s guidance on decision-table errors and warnings distinguishes gaps, where no rule matches, from overlaps, where more than one rule matches.↩︎
ISTQB’s Certified Tester Foundation Level Syllabus 4.0.1, Section 4.2.3 describes a full decision table as covering every combination of condition entries and distinguishes simplification and minimization. The Object Management Group’s Decision Model and Notation 1.5, Section 8 defines a complete table as containing all possible combinations of input values.↩︎