4.2 Decomposition, Pattern Recognition, and Developing Algorithms
Key Takeaways
- Computational thinking is commonly described with four practices: decomposition, pattern recognition, abstraction, and algorithm design.
- To infer an algorithm from a table of values, look for constant differences, repeated ratios, caps and thresholds, and special cases, then test each candidate against every row.
- When decomposing a problem, actors are the people or systems that act (a student, a teacher, a payment service), and actions are what they do (enroll, grade, charge).
- Common decomposition strategies are top-down stepwise refinement, splitting by function or module, by data, by event or actor, and divide-and-conquer.
- Recognizing that several problems share a pattern lets you write one parameterized procedure instead of several near-duplicate ones.
What this competency asks
ETS asks you to know how to use pattern recognition, problem decomposition, and abstraction to develop an algorithm:
- Given a table of values or other data source, identify the patterns in the data and identify algorithms that could produce them.
- Identify components that could be part of an algorithm to solve a problem.
- Identify actions and actors when decomposing a problem.
- Identify appropriate decomposition strategies.
The four computational thinking practices
Computational thinking, a term popularized by Jeannette Wing in 2006, is the thought process of formulating a problem and its solution so that a computer, or a person, can carry it out. It is commonly organized into four practices:
| Practice | Core question | Example |
|---|---|---|
| Decomposition | How can I break this into smaller parts? | Split a registration system into login, catalog, scheduling, and notifications |
| Pattern recognition | What repeats or looks similar? | Every waitlist behaves first-come, first-served, which is a queue |
| Abstraction | What details can I ignore? | Represent a student by ID, grade level, and completed courses |
| Algorithm design | What exact steps solve it? | Check prerequisites, then capacity, then enroll or waitlist |
Inferring an algorithm from a table of values
One ETS sample question shows six dice rolls and the running score after each. You must pick the procedure whose rules reproduce the table: add both dice when neither is a 6, reset to 0 when both are 6, and leave the score unchanged when exactly one is 6. The skill is to state the rule from the data, then test each answer choice against every row.
Worked example
A gym charges members according to the number of visits in a month:
| Visits | 0 | 1 | 2 | 3 | 4 | 5 | 8 |
|---|---|---|---|---|---|---|---|
| Charge ($) | 0 | 8 | 16 | 24 | 30 | 30 | 30 |
Step 1: Look for the pattern. From 0 to 3 visits, each visit adds $8, a constant difference, so the charge grows linearly. At 4 visits the linear rule would give $32, but the table shows $30, and it stays at $30 afterward. There is a cap.
Step 2: State the rule. Charge = 8 × visits, but never more than 30.
Step 3: Test the candidate code against every row.
int charge ( int visits )
if ( visits * 8 > 30 )
return 30
else
return visits * 8
end if
end charge
A tempting wrong version tests visits > 4 instead of visits * 8 > 30. It returns 32 for 4 visits, so it fails the table. Always check the rows at and around the point where the pattern changes.
Pattern checklist
| Look for… | Suggests… |
|---|---|
| Constant difference between outputs | Linear rule: add a fixed amount each step |
| Constant ratio (doubling, halving) | Multiply each step; exponential or logarithmic behavior |
| Differences that themselves grow steadily | Quadratic rule, such as n × n |
| A value that stops changing | A cap, floor, or threshold, which means a conditional |
| Special rows that break the rule | Separate cases handled by if / else |
| Output depending on the previous output | A running total or recurrence, which means a loop or recursion |
Decomposition: breaking problems apart
Decomposition divides a large problem into smaller subproblems that can be designed, built, and tested separately.
Actors and actions
When you decompose a system, identify:
- Actors: the people or external systems that act or are acted on.
- Actions: what each actor does. Actions often become procedures.
For an online course-registration system:
| Actor | Actions |
|---|---|
| Student | Log in, search courses, request enrollment, join a waitlist |
| Counselor | Approve schedule changes, override prerequisites |
| Registrar system | Check prerequisites, check capacity, enroll, send notifications |
| Email service (external) | Deliver confirmation messages |
A common exam distractor mixes the two lists. "Enroll" is an action, not an actor, and "student" is an actor, not an action.
Decomposition strategies
| Strategy | How it works | Good fit |
|---|---|---|
| Top-down (stepwise refinement) | State the whole task, then refine each step into substeps | Designing a program from a clear goal |
| By function or module | One module per responsibility (login, scheduling, reporting) | Large applications and team projects |
| By data | Organize around the main data entities (students, courses, sections) | Data-heavy systems |
| By event or actor | One handler per event or per user role | Interactive and event-driven programs |
| By stage (pipeline) | Input → process → output stages | Data processing |
| Divide-and-conquer | Split into smaller instances of the same problem and combine results | Merge sort, binary search |
A registration system decomposed by module looks like this:
Course Registration System
├── Authentication (log in, check role)
├── Course Catalog (store courses, check prerequisites)
├── Scheduling (detect time conflicts, check room capacity)
├── Enrollment (enroll, maintain first-come, first-served waitlist)
└── Notifications (send confirmations and waitlist updates)
Benefits: each part can be built and tested on its own, team members can work in parallel, and a defect in one module is easier to isolate.
Pattern recognition leads to reuse
Pattern recognition also means noticing that different problems share a structure. Averaging test scores, averaging daily temperatures, and averaging network response times all follow the same steps: accumulate a total, count the items, and divide. Recognizing that shared pattern leads to one procedure, mean ( list ), instead of three copies. This is the bridge from pattern recognition to abstraction and generalization (Section 4.1).
Patterns also point to data structures. Matching nested parentheses, where each closing symbol must match the most recent unmatched opening symbol, is a last-in, first-out pattern that calls for a stack. Serving requests in arrival order is a first-in, first-out pattern that calls for a queue (Section 9.3).
Components of an algorithm
When asked which components could be part of an algorithm for a problem, think in terms of:
- Inputs the algorithm needs, and outputs it produces
- Variables that hold state, such as a running total or a counter
- Sequence, selection, and iteration: the steps, the decisions, and the repetition
- Procedures for subtasks
- Termination: how the algorithm knows it is finished
Classroom connection
Scaffolded frameworks help students apply these practices. In Use–Modify–Create (Irene Lee and colleagues), students run an existing program, then modify it, then create their own. PRIMM (Sue Sentance) moves through Predict, Run, Investigate, Modify, and Make. Parsons problems give students jumbled lines of correct code to arrange, which isolates sequencing and logic from typing.
A procedure returns 3 when n = 1, 5 when n = 2, 9 when n = 3, and 17 when n = 4. Which procedure produces these values?
A class is decomposing a school library's checkout system. Which choice correctly lists actors and then actions?
Students notice that computing an exam average, a monthly rainfall average, and an average web-page load time all require summing values and dividing by the count. They write one procedure, mean ( list ), and use it for all three. Which practice does this best demonstrate?