Front MatterGenerated 2026-05-03 - world-class iteration 04
How to learn from each page
Each page now follows a beginner path: plain-English mental model, paragraph-level reading links, guided lab, code docs beside the code, checkpoint questions, and a practice task.
Read the lede and click the paragraph link beside it if the words are unfamiliar.
Run the lab before reading the full code.
Use the code-doc links next to the implementation when adapting the example.
Mark the page done only after you can explain the invariant or state transition.
A 561-page, printable, searchable, self-contained HTML course with beginner bootcamp pages, visual atlas pages, browser labs, checked SVG diagrams, source-linked code examples, and a companion Jupyter notebook.
Manual Curation Upgrade
This revision adds a structured study layer across the whole course: curated reference shelves, extra code harnesses, stronger student prompts, and interactive practice studios on every routed lesson page.
References
Each page now gets a focused shelf that points learners to official docs, algorithm notes, platform docs, and visual references.
Code
Each page includes an extra Python edge-case harness and a browser JavaScript companion in addition to the main example.
Interaction
Each page includes a practice studio with first-step, edge-case, rubric, and next-change prompts.
Review
Each page has explicit student deliverables and common traps to make self-study less passive.
Iteration 04 world-class upgrade
This build extends the original 500 lesson course to 561 routed pages by adding a beginner foundations bootcamp, a visual algorithm atlas, practice tracks, a GitHub Pages publishing guide, and capstone rubrics. The original course already included source notes, a working launchpad, page-local deep reads, targeted reading links, and labs; this pass turns those pieces into a publishable teaching system.
Beginner first
Every new page includes a plain-English model, one diagram, one lab, one code example, and three checkpoint questions.
In-page citations
New pages cite official documentation beside the paragraph, lab, and code block where the learner needs it.
GitHub Pages ready
The bundle includes index.html, .nojekyll, a README, a notebook, and a validation report.
Visual QA
Representative diagrams were rendered in headless Chromium and checked for route visibility, page counts, anchors, and JSON lab data.
Iteration 05 layout and content quality repair
This pass removes the large blank help-box regression by scoping sidebar CSS to the table of contents only. Page-level source notes are normal compact teaching notes again, so every lesson flows from explanation to diagram, lab, code, and checkpoint without a viewport-sized void.
561 routed pagesall pages have real textall pages have labsall pages have code cardscontent notes are non-sticky
New chapters added in iteration 04
Beginner Foundations Bootcamp - pages 501-512
Visual Algorithm Atlas - pages 513-528
Interactive Practice Tracks - pages 529-540
Publishing and Maintainer Guide - pages 541-550
Capstone Assessments and Project Rubrics - pages 551-560
References and citation map - page 561
How to use: Use the table of contents, search box, page number field, or left/right arrow keys. Check pages as done to track progress. Use Print / Save PDF to render the 561 pages as a printable book.
Documentation and source notes
The course content is original, but implementation notes were cross-checked against current public documentation listed below, especially for Python standard-library tools, browser canvas behavior, JavaScript sorting behavior, and Jupyter notebook file structure.
Every chapter tile and every numbered page link below is wired through the same page router as the side table of contents, so the visible page, URL hash, page number box, active TOC row, and top progress bar update together.
Reference examples use official, current documentation for Python standard-library helpers, JavaScript sorting/canvas behavior, and the Jupyter notebook format.
Every chapter opening page now contains a hand-authored textbook implementation and a custom diagram. Non-opening pages include a pointer back to the chapter anchor so beginners always know where to find the heavier explanation.
Iteration 03 upgrade map
This build adds page-local deep-read sections, targeted reading links, JavaScript companion implementations for chapter anchors, and Chromium-based layout metrics over all 500 article pages.
Page 001 / 561Chapter 1: Orientation and Algorithmic Thinking
How to use this interactive course
Page-local deep read
Mental model for How to use this interactive course: Treat the page as a design checklist. The important beginner move is to name the input, output, invariant, and stopping condition before chasing clever code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 001, the goal is not memorizing how to use this interactive course; it is recognizing the representation, the safe transition, and the stopping condition inside the Orientation and Algorithmic Thinking chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: How to use this interactive course is one small tool in the larger Orientation and Algorithmic Thinking toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for How to use this interactive course before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Chapter anchor: This page is the Chapter 01 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Orientation and Algorithmic Thinking.
Algorithms are precise strategies for transforming inputs into outputs under stated assumptions. The most useful habit is to name the representation, name the invariant, and name the stopping condition before writing code.
Use this chapter to build a repeatable workflow: restate the task, identify constraints, pick data structures, prove correctness, test edge cases, and only then optimize.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: clarity beats cleverness. Make this risk visible in tests and in code comments.
Common pitfall: Skipping the input contract makes later complexity analysis meaningless because the same code can behave very differently on different input models.
# Page 001: How to use this interactive course
EXAMPLE = {'page': 1, 'topic': 'How to use this interactive course', 'chapter': 'Orientation and Algorithmic Thinking', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for How to use this interactive course.', 'sample_input': {'visited_pages': [1, 11, 12, 79], 'completed_pages': [1, 11], 'page_marker': '001-how_to_use_this_inte'}, 'expected_output': 'Inspectable result for How to use this interactive course', 'watch_for': 'The invariant that makes How to use this interactive course safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': [], 'visual_gate_note': 'This is page 001; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'visited_pages'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def how_to_use_this_interactive_course_p001(visited_pages, completed_pages):
visited = list(dict.fromkeys(visited_pages))
completed = set(completed_pages)
return {
'current_page': visited[-1] if visited else None,
'visited_in_order': visited,
'done_count': len(completed),
'progress_percent': round(100 * (visited[-1] if visited else 0) / 500, 2),
'next_action': 'open a page, run its example, then mark it done',
}
def run_example(example=EXAMPLE):
return how_to_use_this_interactive_course_p001([1, 11, 12, 79], [1, 11])
Manual review notes for students
What to inspect first
Track visited_pages, completed_pages before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of How to use this interactive course, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 001 curation harness: How to use this interactive course
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "How to use this interactive course"
SAMPLE = {
"visited_pages": [
1,
11,
12,
79
],
"completed_pages": [
1,
11
],
"page_marker": "001-how_to_use_this_inte"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "visited_pages",
"marker": sample.get("page_marker", "001-how_to_use_this_inte"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "visited_pages": []} if "visited_pages" in sample else dict(sample)),
("single-step", {**sample, "visited_pages": sample.get("visited_pages", [])[:1]} if isinstance(sample.get("visited_pages"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "001-how_to_use_this_inte"))
Browser JavaScript companion
// Page 001 browser-side experiment: How to use this interactive course
const pageExample1 = {"visited_pages":[1,11,12,79],"completed_pages":[1,11],"page_marker":"001-how_to_use_this_inte"};
function summarizePage1(sample = pageExample1) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "How to use this interactive course",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage1());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['visited_pages'], then compare it with the first line produced by How to use this interactive course.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 001.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for how to use this interactive course and explain what each one stresses.
Page 002 / 561Chapter 1: Orientation and Algorithmic Thinking
What an algorithm really specifies
Page-local deep read
Mental model for What an algorithm really specifies: Treat the page as a design checklist. The important beginner move is to name the input, output, invariant, and stopping condition before chasing clever code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 002, the goal is not memorizing what an algorithm really specifies; it is recognizing the representation, the safe transition, and the stopping condition inside the Orientation and Algorithmic Thinking chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: What an algorithm really specifies is one small tool in the larger Orientation and Algorithmic Thinking toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for What an algorithm really specifies before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Algorithms are precise strategies for transforming inputs into outputs under stated assumptions. The most useful habit is to name the representation, name the invariant, and name the stopping condition before writing code.
Use this chapter to build a repeatable workflow: restate the task, identify constraints, pick data structures, prove correctness, test edge cases, and only then optimize.
Write the invariant in a sentence before code. At every step, check what remains true, what shrinks, and what answer information is already final.
Key risk: clarity beats cleverness. Make this risk visible in tests and in code comments.
Common pitfall: Skipping the input contract makes later complexity analysis meaningless because the same code can behave very differently on different input models.
# Page 002: What an algorithm really specifies
EXAMPLE = {'page': 2, 'topic': 'What an algorithm really specifies', 'chapter': 'Orientation and Algorithmic Thinking', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for What an algorithm really specifies.', 'sample_input': {'spec': {'input_model': 'finite list of comparable items', 'output_contract': 'same items sorted', 'invariant': 'prefix is sorted', 'termination': 'index reaches len(items)'}, 'page_marker': '002-what_an_algorithm_re'}, 'expected_output': 'Inspectable result for What an algorithm really specifies', 'watch_for': 'The invariant that makes What an algorithm really specifies safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': [], 'visual_gate_note': 'This is page 002; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'spec'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def what_an_algorithm_really_specifies_p002(spec):
required = ['input_model', 'output_contract', 'invariant', 'termination']
missing = [field for field in required if not spec.get(field)]
return {'complete': not missing, 'missing': missing, 'contract': spec}
def run_example(example=EXAMPLE):
spec = {'input_model':'finite list of comparable items','output_contract':'same items sorted','invariant':'prefix is sorted','termination':'index reaches len(items)'}
return what_an_algorithm_really_specifies_p002(spec)
Manual review notes for students
What to inspect first
Track spec before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of What an algorithm really specifies, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 002 curation harness: What an algorithm really specifies
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "What an algorithm really specifies"
SAMPLE = {
"spec": {
"input_model": "finite list of comparable items",
"output_contract": "same items sorted",
"invariant": "prefix is sorted",
"termination": "index reaches len(items)"
},
"page_marker": "002-what_an_algorithm_re"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "spec",
"marker": sample.get("page_marker", "002-what_an_algorithm_re"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "spec": []} if "spec" in sample else dict(sample)),
("single-step", {**sample, "spec": sample.get("spec", [])[:1]} if isinstance(sample.get("spec"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "002-what_an_algorithm_re"))
Browser JavaScript companion
// Page 002 browser-side experiment: What an algorithm really specifies
const pageExample2 = {"spec":{"input_model":"finite list of comparable items","output_contract":"same items sorted","invariant":"prefix is sorted","termination":"index reaches len(items)"},"page_marker":"002-what_an_algorithm_re"};
function summarizePage2(sample = pageExample2) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "What an algorithm really specifies",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage2());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['spec'], then compare it with the first line produced by What an algorithm really specifies.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 002.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for what an algorithm really specifies, then point to the line of code that preserves it.
Page 003 / 561Chapter 1: Orientation and Algorithmic Thinking
Input models, output contracts, and edge cases
Page-local deep read
Mental model for Input models, output contracts, and edge cases: Treat the page as a design checklist. The important beginner move is to name the input, output, invariant, and stopping condition before chasing clever code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 003, the goal is not memorizing input models, output contracts, and edge cases; it is recognizing the representation, the safe transition, and the stopping condition inside the Orientation and Algorithmic Thinking chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Input models, output contracts, and edge cases is one small tool in the larger Orientation and Algorithmic Thinking toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Input models, output contracts, and edge cases before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Algorithms are precise strategies for transforming inputs into outputs under stated assumptions. The most useful habit is to name the representation, name the invariant, and name the stopping condition before writing code.
Use this chapter to build a repeatable workflow: restate the task, identify constraints, pick data structures, prove correctness, test edge cases, and only then optimize.
Budget the cost as varies time and varies space in the common model, then revisit the bound when the input representation changes.
Key risk: clarity beats cleverness. Make this risk visible in tests and in code comments.
Common pitfall: Skipping the input contract makes later complexity analysis meaningless because the same code can behave very differently on different input models.
# Page 003: Input models, output contracts, and edge cases
EXAMPLE = {'page': 3, 'topic': 'Input models, output contracts, and edge cases', 'chapter': 'Orientation and Algorithmic Thinking', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for Input models, output contracts, and edge cases.', 'sample_input': {'values': [3, 1, 3, 5], 'page_marker': '003-input_models_output_'}, 'expected_output': 'Inspectable result for Input models, output contracts, and edge cases', 'watch_for': 'The invariant that makes Input models, output contracts, and edge cases safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': [], 'visual_gate_note': 'This is page 003; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'values'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def input_models_output_contracts_and_edge_cases_p003(values):
if values is None:
raise TypeError('values must be a finite sequence, not None')
return {
'input_size': len(values),
'edge_cases': {'empty': len(values)==0, 'one': len(values)==1, 'has_duplicates': len(set(values)) < len(values)},
'output_contract': 'return metadata without mutating values',
'copy_preserved': list(values),
}
def run_example(example=EXAMPLE):
return input_models_output_contracts_and_edge_cases_p003([3, 1, 3, 5])
Manual review notes for students
What to inspect first
Track values before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Input models, output contracts, and edge cases, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 003 curation harness: Input models, output contracts, and edge cases
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "Input models, output contracts, and edge cases"
SAMPLE = {
"values": [
3,
1,
3,
5
],
"page_marker": "003-input_models_output_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "003-input_models_output_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "003-input_models_output_"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Input models, output contracts, and edge cases.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 003.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 004 / 561Chapter 1: Orientation and Algorithmic Thinking
From problem statement to representation
Page-local deep read
Mental model for From problem statement to representation: Treat the page as a design checklist. The important beginner move is to name the input, output, invariant, and stopping condition before chasing clever code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 004, the goal is not memorizing from problem statement to representation; it is recognizing the representation, the safe transition, and the stopping condition inside the Orientation and Algorithmic Thinking chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: From problem statement to representation is one small tool in the larger Orientation and Algorithmic Thinking toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for From problem statement to representation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Algorithms are precise strategies for transforming inputs into outputs under stated assumptions. The most useful habit is to name the representation, name the invariant, and name the stopping condition before writing code.
Use this chapter to build a repeatable workflow: restate the task, identify constraints, pick data structures, prove correctness, test edge cases, and only then optimize.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: clarity beats cleverness. Make this risk visible in tests and in code comments.
Common pitfall: Skipping the input contract makes later complexity analysis meaningless because the same code can behave very differently on different input models.
# Page 004: From problem statement to representation
EXAMPLE = {'page': 4, 'topic': 'From problem statement to representation', 'chapter': 'Orientation and Algorithmic Thinking', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for From problem statement to representation.', 'sample_input': {'problem_statement': 'Find the shortest route in a connected campus network', 'page_marker': '004-from_problem_stateme'}, 'expected_output': 'Inspectable result for From problem statement to representation', 'watch_for': 'The invariant that makes From problem statement to representation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': [], 'visual_gate_note': 'This is page 004; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'problem_statement'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def from_problem_statement_to_representation_p004(problem_statement):
tokens = problem_statement.lower().replace(',', ' ').split()
representation = {
'mentions_order': any(w in tokens for w in ['sorted','before','after','nearest']),
'mentions_connectivity': any(w in tokens for w in ['route','network','connected','path']),
'mentions_repetition': len(tokens) != len(set(tokens)),
}
recommendation = 'graph' if representation['mentions_connectivity'] else 'array/hash map'
return {'tokens': tokens, 'representation': representation, 'recommended_structure': recommendation}
def run_example(example=EXAMPLE):
return from_problem_statement_to_representation_p004('Find the shortest route in a connected campus network')
Manual review notes for students
What to inspect first
Track problem_statement before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of From problem statement to representation, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 004 curation harness: From problem statement to representation
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "From problem statement to representation"
SAMPLE = {
"problem_statement": "Find the shortest route in a connected campus network",
"page_marker": "004-from_problem_stateme"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "problem_statement",
"marker": sample.get("page_marker", "004-from_problem_stateme"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "problem_statement": []} if "problem_statement" in sample else dict(sample)),
("single-step", {**sample, "problem_statement": sample.get("problem_statement", [])[:1]} if isinstance(sample.get("problem_statement"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "004-from_problem_stateme"))
Browser JavaScript companion
// Page 004 browser-side experiment: From problem statement to representation
const pageExample4 = {"problem_statement":"Find the shortest route in a connected campus network","page_marker":"004-from_problem_stateme"};
function summarizePage4(sample = pageExample4) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "From problem statement to representation",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage4());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['problem_statement'], then compare it with the first line produced by From problem statement to representation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 004.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 005 / 561Chapter 1: Orientation and Algorithmic Thinking
Pseudocode, reference code, and tests
Page-local deep read
Mental model for Pseudocode, reference code, and tests: Treat the page as a design checklist. The important beginner move is to name the input, output, invariant, and stopping condition before chasing clever code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 005, the goal is not memorizing pseudocode, reference code, and tests; it is recognizing the representation, the safe transition, and the stopping condition inside the Orientation and Algorithmic Thinking chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Pseudocode, reference code, and tests is one small tool in the larger Orientation and Algorithmic Thinking toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Pseudocode, reference code, and tests before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Algorithms are precise strategies for transforming inputs into outputs under stated assumptions. The most useful habit is to name the representation, name the invariant, and name the stopping condition before writing code.
Use this chapter to build a repeatable workflow: restate the task, identify constraints, pick data structures, prove correctness, test edge cases, and only then optimize.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: clarity beats cleverness. Make this risk visible in tests and in code comments.
Common pitfall: Skipping the input contract makes later complexity analysis meaningless because the same code can behave very differently on different input models.
# Page 005: Pseudocode, reference code, and tests
EXAMPLE = {'page': 5, 'topic': 'Pseudocode, reference code, and tests', 'chapter': 'Orientation and Algorithmic Thinking', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Pseudocode, reference code, and tests.', 'sample_input': {'cases': [[], [1], [3, 1, 3], [5, 4, 3, 2, 1]], 'page_marker': '005-pseudocode_reference'}, 'expected_output': 'Inspectable result for Pseudocode, reference code, and tests', 'watch_for': 'The invariant that makes Pseudocode, reference code, and tests safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': [], 'visual_gate_note': 'This is page 005; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'cases'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def reference_solution(values):
return sorted(values)
def slow_oracle(values):
remaining = list(values); out = []
while remaining:
m = min(remaining); out.append(m); remaining.remove(m)
return out
def pseudocode_reference_code_and_tests_p005(cases):
return [{'case': case, 'reference': reference_solution(case), 'oracle_agrees': reference_solution(case) == slow_oracle(case)} for case in cases]
def run_example(example=EXAMPLE):
return pseudocode_reference_code_and_tests_p005([[], [1], [3,1,3], [5,4,3,2,1]])
Manual review notes for students
What to inspect first
Track cases before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Pseudocode, reference code, and tests, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 005 curation harness: Pseudocode, reference code, and tests
EXAMPLE_KIND = "project"
EXAMPLE_TITLE = "Pseudocode, reference code, and tests"
SAMPLE = {
"cases": [
[],
[
1
],
[
3,
1,
3
],
[
5,
4,
3,
2,
1
]
],
"page_marker": "005-pseudocode_reference"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "cases",
"marker": sample.get("page_marker", "005-pseudocode_reference"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "cases": []} if "cases" in sample else dict(sample)),
("single-step", {**sample, "cases": sample.get("cases", [])[:1]} if isinstance(sample.get("cases"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "005-pseudocode_reference"))
Browser JavaScript companion
// Page 005 browser-side experiment: Pseudocode, reference code, and tests
const pageExample5 = {"cases":[[],[1],[3,1,3],[5,4,3,2,1]],"page_marker":"005-pseudocode_reference"};
function summarizePage5(sample = pageExample5) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Pseudocode, reference code, and tests",
kind: "project",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage5());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['cases'], then compare it with the first line produced by Pseudocode, reference code, and tests.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 005.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement pseudocode, reference code, and tests twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 006 / 561Chapter 1: Orientation and Algorithmic Thinking
The algorithm designer's checklist
Page-local deep read
Mental model for The algorithm designer's checklist: Treat the page as a design checklist. The important beginner move is to name the input, output, invariant, and stopping condition before chasing clever code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 006, the goal is not memorizing the algorithm designer's checklist; it is recognizing the representation, the safe transition, and the stopping condition inside the Orientation and Algorithmic Thinking chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: The algorithm designer's checklist is one small tool in the larger Orientation and Algorithmic Thinking toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for The algorithm designer's checklist before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Algorithms are precise strategies for transforming inputs into outputs under stated assumptions. The most useful habit is to name the representation, name the invariant, and name the stopping condition before writing code.
Use this chapter to build a repeatable workflow: restate the task, identify constraints, pick data structures, prove correctness, test edge cases, and only then optimize.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: clarity beats cleverness. Make this risk visible in tests and in code comments.
Common pitfall: Skipping the input contract makes later complexity analysis meaningless because the same code can behave very differently on different input models.
# Page 006: The algorithm designer's checklist
EXAMPLE = {'page': 6, 'topic': "The algorithm designer's checklist", 'chapter': 'Orientation and Algorithmic Thinking', 'kind': 'project', 'scenario': "Run a concrete project miniature for The algorithm designer's checklist.", 'sample_input': {'idea': {'contract': 'named', 'representation': 'list plus indices', 'invariant': 'processed prefix safe', 'termination': 'index grows', 'tests': ['empty', 'duplicate'], 'cost': 'O(n)'}, 'page_marker': '006-the_algorithm_design'}, 'expected_output': "Inspectable result for The algorithm designer's checklist", 'watch_for': "The invariant that makes The algorithm designer's checklist safe is checked before the next transition.", 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': [], 'visual_gate_note': 'This is page 006; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'idea'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def the_algorithm_designer_s_checklist_p006(idea):
checklist = ['contract', 'representation', 'invariant', 'termination', 'tests', 'cost']
return {item: bool(idea.get(item)) for item in checklist}
def run_example(example=EXAMPLE):
return the_algorithm_designer_s_checklist_p006({'contract': 'input/output named', 'representation': 'list plus indices', 'invariant': 'processed prefix safe', 'termination': 'index grows', 'tests': ['empty','duplicate'], 'cost':'O(n)'})
Manual review notes for students
What to inspect first
Track idea before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of The algorithm designer's checklist, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 006 curation harness: The algorithm designer's checklist
EXAMPLE_KIND = "project"
EXAMPLE_TITLE = "The algorithm designer's checklist"
SAMPLE = {
"idea": {
"contract": "named",
"representation": "list plus indices",
"invariant": "processed prefix safe",
"termination": "index grows",
"tests": [
"empty",
"duplicate"
],
"cost": "O(n)"
},
"page_marker": "006-the_algorithm_design"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "idea",
"marker": sample.get("page_marker", "006-the_algorithm_design"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "idea": []} if "idea" in sample else dict(sample)),
("single-step", {**sample, "idea": sample.get("idea", [])[:1]} if isinstance(sample.get("idea"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "006-the_algorithm_design"))
Browser JavaScript companion
// Page 006 browser-side experiment: The algorithm designer's checklist
const pageExample6 = {"idea":{"contract":"named","representation":"list plus indices","invariant":"processed prefix safe","termination":"index grows","tests":["empty","duplicate"],"cost":"O(n)"},"page_marker":"006-the_algorithm_design"};
function summarizePage6(sample = pageExample6) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "The algorithm designer's checklist",
kind: "project",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage6());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['idea'], then compare it with the first line produced by The algorithm designer's checklist.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 006.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for the algorithm designer's checklist and explain what each one stresses.
Page 007 / 561Chapter 1: Orientation and Algorithmic Thinking
Tracing algorithms by hand
Page-local deep read
Mental model for Tracing algorithms by hand: Treat the page as a design checklist. The important beginner move is to name the input, output, invariant, and stopping condition before chasing clever code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 007, the goal is not memorizing tracing algorithms by hand; it is recognizing the representation, the safe transition, and the stopping condition inside the Orientation and Algorithmic Thinking chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Tracing algorithms by hand is one small tool in the larger Orientation and Algorithmic Thinking toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Tracing algorithms by hand before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Algorithms are precise strategies for transforming inputs into outputs under stated assumptions. The most useful habit is to name the representation, name the invariant, and name the stopping condition before writing code.
Use this chapter to build a repeatable workflow: restate the task, identify constraints, pick data structures, prove correctness, test edge cases, and only then optimize.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: clarity beats cleverness. Make this risk visible in tests and in code comments.
Common pitfall: Skipping the input contract makes later complexity analysis meaningless because the same code can behave very differently on different input models.
# Page 007: Tracing algorithms by hand
EXAMPLE = {'page': 7, 'topic': 'Tracing algorithms by hand', 'chapter': 'Orientation and Algorithmic Thinking', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for Tracing algorithms by hand.', 'sample_input': {'values': [4, 1, 7, 2], 'page_marker': '007-tracing_algorithms_b'}, 'expected_output': 'Inspectable result for Tracing algorithms by hand', 'watch_for': 'The invariant that makes Tracing algorithms by hand safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': [], 'visual_gate_note': 'This is page 007; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'values'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def tracing_algorithms_by_hand_p007(values):
running, trace = 0, []
for index, value in enumerate(values):
before = running
running += value
trace.append({'index': index, 'value': value, 'before': before, 'after': running, 'invariant': 'after equals sum(values[:index+1])'})
return trace
def run_example(example=EXAMPLE):
return tracing_algorithms_by_hand_p007([4, 1, 7, 2])
Manual review notes for students
What to inspect first
Track values before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Tracing algorithms by hand, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 007 curation harness: Tracing algorithms by hand
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "Tracing algorithms by hand"
SAMPLE = {
"values": [
4,
1,
7,
2
],
"page_marker": "007-tracing_algorithms_b"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "007-tracing_algorithms_b"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "007-tracing_algorithms_b"))
Browser JavaScript companion
// Page 007 browser-side experiment: Tracing algorithms by hand
const pageExample7 = {"values":[4,1,7,2],"page_marker":"007-tracing_algorithms_b"};
function summarizePage7(sample = pageExample7) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Tracing algorithms by hand",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage7());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Tracing algorithms by hand.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 007.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for tracing algorithms by hand, then point to the line of code that preserves it.
Page 008 / 561Chapter 1: Orientation and Algorithmic Thinking
Choosing data structures before code
Page-local deep read
Mental model for Choosing data structures before code: Treat the page as a design checklist. The important beginner move is to name the input, output, invariant, and stopping condition before chasing clever code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 008, the goal is not memorizing choosing data structures before code; it is recognizing the representation, the safe transition, and the stopping condition inside the Orientation and Algorithmic Thinking chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Choosing data structures before code is one small tool in the larger Orientation and Algorithmic Thinking toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Choosing data structures before code before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Algorithms are precise strategies for transforming inputs into outputs under stated assumptions. The most useful habit is to name the representation, name the invariant, and name the stopping condition before writing code.
Use this chapter to build a repeatable workflow: restate the task, identify constraints, pick data structures, prove correctness, test edge cases, and only then optimize.
Look for Choosing data structures before code whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: clarity beats cleverness. Make this risk visible in tests and in code comments.
Common pitfall: Skipping the input contract makes later complexity analysis meaningless because the same code can behave very differently on different input models.
# Page 008: Choosing data structures before code
EXAMPLE = {'page': 8, 'topic': 'Choosing data structures before code', 'chapter': 'Orientation and Algorithmic Thinking', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for Choosing data structures before code.', 'sample_input': {'operation_sets': [['membership', 'count'], ['min', 'delete_min'], ['range_sum', 'prefix'], ['neighbors', 'paths']], 'page_marker': '008-choosing_data_struct'}, 'expected_output': 'Inspectable result for Choosing data structures before code', 'watch_for': 'The invariant that makes Choosing data structures before code safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': [], 'visual_gate_note': 'This is page 008; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'operation_sets'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def choosing_data_structures_before_code_p008(operations):
needs = set(operations)
if set(('min','delete_min')) & needs: return 'heap / priority queue'
if set(('membership','count')) & needs: return 'set or dict'
if set(('range_sum','prefix')) & needs: return 'prefix array or Fenwick tree'
if set(('neighbors','paths')) & needs: return 'adjacency list graph'
return 'plain list with clear invariants'
def run_example(example=EXAMPLE):
return {ops: choosing_data_structures_before_code_p008(ops) for ops in [('membership','count'), ('min','delete_min'), ('range_sum','prefix'), ('neighbors','paths')]}
Manual review notes for students
What to inspect first
Track operation_sets before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Choosing data structures before code, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 008 curation harness: Choosing data structures before code
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "Choosing data structures before code"
SAMPLE = {
"operation_sets": [
[
"membership",
"count"
],
[
"min",
"delete_min"
],
[
"range_sum",
"prefix"
],
[
"neighbors",
"paths"
]
],
"page_marker": "008-choosing_data_struct"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "operation_sets",
"marker": sample.get("page_marker", "008-choosing_data_struct"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "operation_sets": []} if "operation_sets" in sample else dict(sample)),
("single-step", {**sample, "operation_sets": sample.get("operation_sets", [])[:1]} if isinstance(sample.get("operation_sets"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "008-choosing_data_struct"))
Browser JavaScript companion
// Page 008 browser-side experiment: Choosing data structures before code
const pageExample8 = {"operation_sets":[["membership","count"],["min","delete_min"],["range_sum","prefix"],["neighbors","paths"]],"page_marker":"008-choosing_data_struct"};
function summarizePage8(sample = pageExample8) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Choosing data structures before code",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage8());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['operation_sets'], then compare it with the first line produced by Choosing data structures before code.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 008.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 009 / 561Chapter 1: Orientation and Algorithmic Thinking
Measuring progress with invariants
Page-local deep read
Mental model for Measuring progress with invariants: Treat the page as a design checklist. The important beginner move is to name the input, output, invariant, and stopping condition before chasing clever code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 009, the goal is not memorizing measuring progress with invariants; it is recognizing the representation, the safe transition, and the stopping condition inside the Orientation and Algorithmic Thinking chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Measuring progress with invariants is one small tool in the larger Orientation and Algorithmic Thinking toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Measuring progress with invariants before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Algorithms are precise strategies for transforming inputs into outputs under stated assumptions. The most useful habit is to name the representation, name the invariant, and name the stopping condition before writing code.
Use this chapter to build a repeatable workflow: restate the task, identify constraints, pick data structures, prove correctness, test edge cases, and only then optimize.
Practice by inventing a tiny input, tracing every step, then writing a randomized checker that compares against a slow brute-force implementation.
Key risk: clarity beats cleverness. Make this risk visible in tests and in code comments.
Common pitfall: Skipping the input contract makes later complexity analysis meaningless because the same code can behave very differently on different input models.
# Page 009: Measuring progress with invariants
EXAMPLE = {'page': 9, 'topic': 'Measuring progress with invariants', 'chapter': 'Orientation and Algorithmic Thinking', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Measuring progress with invariants.', 'sample_input': {'values': [2, 9, 4, 12, 5], 'page_marker': '009-measuring_progress_w'}, 'expected_output': 'Inspectable result for Measuring progress with invariants', 'watch_for': 'The invariant that makes Measuring progress with invariants safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 009; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'values'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def measuring_progress_with_invariants_p009(values):
max_so_far, trace = None, []
for i, value in enumerate(values):
max_so_far = value if max_so_far is None else max(max_so_far, value)
trace.append({'i': i, 'max_so_far': max_so_far, 'invariant_holds': max_so_far == max(values[:i+1])})
return trace
def run_example(example=EXAMPLE):
return measuring_progress_with_invariants_p009([2, 9, 4, 12, 5])
Manual review notes for students
What to inspect first
Track values before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Measuring progress with invariants, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 009 curation harness: Measuring progress with invariants
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Measuring progress with invariants"
SAMPLE = {
"values": [
2,
9,
4,
12,
5
],
"page_marker": "009-measuring_progress_w"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "009-measuring_progress_w"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "009-measuring_progress_w"))
Browser JavaScript companion
// Page 009 browser-side experiment: Measuring progress with invariants
const pageExample9 = {"values":[2,9,4,12,5],"page_marker":"009-measuring_progress_w"};
function summarizePage9(sample = pageExample9) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Measuring progress with invariants",
kind: "proof",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage9());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Measuring progress with invariants.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 009.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 010 / 561Chapter 1: Orientation and Algorithmic Thinking
Course map and capstone outcomes
Page-local deep read
Mental model for Course map and capstone outcomes: Treat the page as a design checklist. The important beginner move is to name the input, output, invariant, and stopping condition before chasing clever code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 010, the goal is not memorizing course map and capstone outcomes; it is recognizing the representation, the safe transition, and the stopping condition inside the Orientation and Algorithmic Thinking chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Course map and capstone outcomes is one small tool in the larger Orientation and Algorithmic Thinking toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Course map and capstone outcomes before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Algorithms are precise strategies for transforming inputs into outputs under stated assumptions. The most useful habit is to name the representation, name the invariant, and name the stopping condition before writing code.
Use this chapter to build a repeatable workflow: restate the task, identify constraints, pick data structures, prove correctness, test edge cases, and only then optimize.
Think of Course map and capstone outcomes as a foundational pattern with an explicit state, a transition rule, and a measure of progress.
Key risk: clarity beats cleverness. Make this risk visible in tests and in code comments.
Common pitfall: Skipping the input contract makes later complexity analysis meaningless because the same code can behave very differently on different input models.
# Page 010: Course map and capstone outcomes
EXAMPLE = {'page': 10, 'topic': 'Course map and capstone outcomes', 'chapter': 'Orientation and Algorithmic Thinking', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for Course map and capstone outcomes.', 'sample_input': {'milestones': ['arrays/search', 'graphs', 'dynamic programming', 'capstone visualizer'], 'page_marker': '010-course_map_and_capst'}, 'expected_output': 'Inspectable result for Course map and capstone outcomes', 'watch_for': 'The invariant that makes Course map and capstone outcomes safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': [], 'visual_gate_note': 'This is page 010; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'milestones'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def course_map_and_capstone_outcomes_p010(milestones):
return [{'week': i+1, 'milestone': m, 'evidence': 'working code + proof note + tests'} for i, m in enumerate(milestones)]
def run_example(example=EXAMPLE):
return course_map_and_capstone_outcomes_p010(['arrays/search', 'graphs', 'dynamic programming', 'capstone visualizer'])
Manual review notes for students
What to inspect first
Track milestones before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Course map and capstone outcomes, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 010 curation harness: Course map and capstone outcomes
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "Course map and capstone outcomes"
SAMPLE = {
"milestones": [
"arrays/search",
"graphs",
"dynamic programming",
"capstone visualizer"
],
"page_marker": "010-course_map_and_capst"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "milestones",
"marker": sample.get("page_marker", "010-course_map_and_capst"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "milestones": []} if "milestones" in sample else dict(sample)),
("single-step", {**sample, "milestones": sample.get("milestones", [])[:1]} if isinstance(sample.get("milestones"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "010-course_map_and_capst"))
Browser JavaScript companion
// Page 010 browser-side experiment: Course map and capstone outcomes
const pageExample10 = {"milestones":["arrays/search","graphs","dynamic programming","capstone visualizer"],"page_marker":"010-course_map_and_capst"};
function summarizePage10(sample = pageExample10) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Course map and capstone outcomes",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage10());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['milestones'], then compare it with the first line produced by Course map and capstone outcomes.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 010.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement course map and capstone outcomes twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 011 / 561Chapter 2: Math and Complexity Foundations
Discrete math objects used by algorithms
Page-local deep read
Mental model for Discrete math objects used by algorithms: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 011, the goal is not memorizing discrete math objects used by algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Discrete math objects used by algorithms is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Discrete math objects used by algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Compare two functions over increasing input sizes and report which one dominates empirically. This turns asymptotic language into something you can inspect.
Use this when stuck:
Return here whenever a page in this chapter feels too thin. This chapter opening now carries a hand-authored implementation and a custom diagram.
This is a chapter-level anchor example. Read it alongside the page-specific labs lower down.
import math
from typing import Callable
def compare_growth(f: Callable[[int], float], g: Callable[[int], float], sizes: list[int]) -> list[tuple[int, float, float, str]]:
rows = []
for n in sizes:
left = f(n)
right = g(n)
winner = 'f' if left < right else 'g' if right < left else 'tie'
rows.append((n, left, right, winner))
return rows
f = lambda n: n * math.log2(max(2, n))
g = lambda n: n * n
for row in compare_growth(f, g, [2, 4, 8, 16, 32, 64]):
print(row)
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 2: Math and Complexity Foundations
function compareGrowth(sizes) {
return sizes.map(n => ({ n, nLogN: n * Math.log2(Math.max(2, n)), nSquared: n * n }));
}
console.log(compareGrowth([2, 4, 8, 16, 32]));
Chapter anchor: This page is the Chapter 02 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Math and Complexity Foundations.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 011: Discrete math objects used by algorithms
EXAMPLE = {'page': 11, 'topic': 'Discrete math objects used by algorithms', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Discrete math objects used by algorithms.', 'sample_input': {'objects': {'items': ['a', 'b', 'a', 'c'], 'pairs': [['a', 'b'], ['b', 'c']], 'mapping': {'a': 1, 'b': 2}, 'edges': [['a', 'b'], ['b', 'c']]}, 'page_marker': '011-discrete_math_object'}, 'expected_output': 'Inspectable result for Discrete math objects used by algorithms', 'watch_for': 'The invariant that makes Discrete math objects used by algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 011; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'objects'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def discrete_math_objects_used_by_algorithms_p011(objects):
return {
'set_size': len(set(objects['items'])),
'ordered_pair_count': len(objects['pairs']),
'mapping_defined_for': sorted(objects['mapping']),
'graph_vertices': sorted({u for edge in objects['edges'] for u in edge}),
}
def run_example(example=EXAMPLE):
data = {'items':['a','b','a','c'], 'pairs':[('a','b'),('b','c')], 'mapping':{'a':1,'b':2}, 'edges':[('a','b'),('b','c')]}
return discrete_math_objects_used_by_algorithms_p011(data)
Manual review notes for students
What to inspect first
Track objects before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Discrete math objects used by algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 011 curation harness: Discrete math objects used by algorithms
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Discrete math objects used by algorithms"
SAMPLE = {
"objects": {
"items": [
"a",
"b",
"a",
"c"
],
"pairs": [
[
"a",
"b"
],
[
"b",
"c"
]
],
"mapping": {
"a": 1,
"b": 2
},
"edges": [
[
"a",
"b"
],
[
"b",
"c"
]
]
},
"page_marker": "011-discrete_math_object"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "objects",
"marker": sample.get("page_marker", "011-discrete_math_object"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "objects": []} if "objects" in sample else dict(sample)),
("single-step", {**sample, "objects": sample.get("objects", [])[:1]} if isinstance(sample.get("objects"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "011-discrete_math_object"))
Browser JavaScript companion
// Page 011 browser-side experiment: Discrete math objects used by algorithms
const pageExample11 = {"objects":{"items":["a","b","a","c"],"pairs":[["a","b"],["b","c"]],"mapping":{"a":1,"b":2},"edges":[["a","b"],["b","c"]]},"page_marker":"011-discrete_math_object"};
function summarizePage11(sample = pageExample11) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Discrete math objects used by algorithms",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage11());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['objects'], then compare it with the first line produced by Discrete math objects used by algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 011.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for discrete math objects used by algorithms and explain what each one stresses.
Page 012 / 561Chapter 2: Math and Complexity Foundations
Sets, relations, and functions
Page-local deep read
Mental model for Sets, relations, and functions: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 012, the goal is not memorizing sets, relations, and functions; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sets, relations, and functions is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sets, relations, and functions before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
# Page 012: Sets, relations, and functions
EXAMPLE = {'page': 12, 'topic': 'Sets, relations, and functions', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Sets, relations, and functions.', 'sample_input': {'domain': ['red', 'blue', 'green'], 'relation': [['red', 'red'], ['blue', 'blue'], ['green', 'green'], ['red', 'blue'], ['blue', 'red']], 'function': {'red': 'warm', 'blue': 'cool', 'green': 'cool'}, 'page_marker': '012-sets_relations_and_f'}, 'expected_output': 'Inspectable result for Sets, relations, and functions', 'watch_for': 'The invariant that makes Sets, relations, and functions safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 012; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'domain'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def sets_relations_and_functions_p012(domain, relation, function):
image = {function[x] for x in domain if x in function}
inverse = {y: sorted(x for x in domain if function.get(x)==y) for y in image}
reflexive = all((x, x) in relation for x in domain)
symmetric = all((b, a) in relation for (a, b) in relation)
return {'image': sorted(image), 'preimage': inverse, 'relation_reflexive': reflexive, 'relation_symmetric': symmetric}
def run_example(example=EXAMPLE):
domain = {'red','blue','green'}
relation = {('red','red'),('blue','blue'),('green','green'),('red','blue'),('blue','red')}
function = {'red':'warm', 'blue':'cool', 'green':'cool'}
return sets_relations_and_functions_p012(domain, relation, function)
Manual review notes for students
What to inspect first
Track domain, relation, function before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Sets, relations, and functions, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 012 curation harness: Sets, relations, and functions
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Sets, relations, and functions"
SAMPLE = {
"domain": [
"red",
"blue",
"green"
],
"relation": [
[
"red",
"red"
],
[
"blue",
"blue"
],
[
"green",
"green"
],
[
"red",
"blue"
],
[
"blue",
"red"
]
],
"function": {
"red": "warm",
"blue": "cool",
"green": "cool"
},
"page_marker": "012-sets_relations_and_f"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "domain",
"marker": sample.get("page_marker", "012-sets_relations_and_f"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "domain": []} if "domain" in sample else dict(sample)),
("single-step", {**sample, "domain": sample.get("domain", [])[:1]} if isinstance(sample.get("domain"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "012-sets_relations_and_f"))
Browser JavaScript companion
// Page 012 browser-side experiment: Sets, relations, and functions
const pageExample12 = {"domain":["red","blue","green"],"relation":[["red","red"],["blue","blue"],["green","green"],["red","blue"],["blue","red"]],"function":{"red":"warm","blue":"cool","green":"cool"},"page_marker":"012-sets_relations_and_f"};
function summarizePage12(sample = pageExample12) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Sets, relations, and functions",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage12());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['domain'], then compare it with the first line produced by Sets, relations, and functions.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 012.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for sets, relations, and functions, then point to the line of code that preserves it.
Page 013 / 561Chapter 2: Math and Complexity Foundations
Sequences, sums, and products
Page-local deep read
Mental model for Sequences, sums, and products: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 013, the goal is not memorizing sequences, sums, and products; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sequences, sums, and products is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sequences, sums, and products before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
# Page 013: Sequences, sums, and products
EXAMPLE = {'page': 13, 'topic': 'Sequences, sums, and products', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Sequences, sums, and products.', 'sample_input': {'values': [2, 3, 5, 7], 'page_marker': '013-sequences_sums_and_p'}, 'expected_output': 'Inspectable result for Sequences, sums, and products', 'watch_for': 'The invariant that makes Sequences, sums, and products safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 013; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'values'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def sequences_sums_and_products_p013(values):
total, product, rows = 0, 1, []
for i, value in enumerate(values, 1):
total += value; product *= value
rows.append({'i': i, 'partial_sum': total, 'partial_product': product})
return rows
def run_example(example=EXAMPLE):
return sequences_sums_and_products_p013([2, 3, 5, 7])
Manual review notes for students
What to inspect first
Track values before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Sequences, sums, and products, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 013 curation harness: Sequences, sums, and products
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Sequences, sums, and products"
SAMPLE = {
"values": [
2,
3,
5,
7
],
"page_marker": "013-sequences_sums_and_p"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "013-sequences_sums_and_p"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "013-sequences_sums_and_p"))
Browser JavaScript companion
// Page 013 browser-side experiment: Sequences, sums, and products
const pageExample13 = {"values":[2,3,5,7],"page_marker":"013-sequences_sums_and_p"};
function summarizePage13(sample = pageExample13) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Sequences, sums, and products",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage13());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Sequences, sums, and products.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 013.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 014 / 561Chapter 2: Math and Complexity Foundations
Logarithms and exponentials in running time
Page-local deep read
Mental model for Logarithms and exponentials in running time: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 014, the goal is not memorizing logarithms and exponentials in running time; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Logarithms and exponentials in running time is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Logarithms and exponentials in running time before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 014: Logarithms and exponentials in running time
EXAMPLE = {'page': 14, 'topic': 'Logarithms and exponentials in running time', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Logarithms and exponentials in running time.', 'sample_input': {'n': 1000, 'page_marker': '014-logarithms_and_expon'}, 'expected_output': 'Inspectable result for Logarithms and exponentials in running time', 'watch_for': 'The invariant that makes Logarithms and exponentials in running time safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 014; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'n'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def logarithms_and_exponentials_in_running_time_p014(n):
halving_steps, x = 0, n
while x > 1:
x //= 2; halving_steps += 1
doubling, y = 0, 1
while y < n:
y *= 2; doubling += 1
return {'n': n, 'floor_log2_by_halving': halving_steps, 'ceiling_log2_by_doubling': doubling}
def run_example(example=EXAMPLE):
return logarithms_and_exponentials_in_running_time_p014(1000)
Manual review notes for students
What to inspect first
Track n before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Logarithms and exponentials in running time, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 014 curation harness: Logarithms and exponentials in running time
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Logarithms and exponentials in running time"
SAMPLE = {
"n": 1000,
"page_marker": "014-logarithms_and_expon"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "014-logarithms_and_expon"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "014-logarithms_and_expon"))
Browser JavaScript companion
// Page 014 browser-side experiment: Logarithms and exponentials in running time
const pageExample14 = {"n":1000,"page_marker":"014-logarithms_and_expon"};
function summarizePage14(sample = pageExample14) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Logarithms and exponentials in running time",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage14());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Logarithms and exponentials in running time.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 014.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 015 / 561Chapter 2: Math and Complexity Foundations
Big-O, Big-Omega, and Big-Theta
Page-local deep read
Mental model for Big-O, Big-Omega, and Big-Theta: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 015, the goal is not memorizing big-o, big-omega, and big-theta; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Big-O, Big-Omega, and Big-Theta is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Big-O, Big-Omega, and Big-Theta before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 015: Big-O, Big-Omega, and Big-Theta
EXAMPLE = {'page': 15, 'topic': 'Big-O, Big-Omega, and Big-Theta', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Big-O, Big-Omega, and Big-Theta.', 'sample_input': {'sizes': [10, 100, 1000, 10000], 'page_marker': '015-big_o_big_omega_and_'}, 'expected_output': 'Inspectable result for Big-O, Big-Omega, and Big-Theta', 'watch_for': 'The invariant that makes Big-O, Big-Omega, and Big-Theta safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 015; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'sizes'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def big_o_big_omega_and_big_theta_p015(sizes):
return [{'n': n, 'f=n log n': round(n*(n.bit_length()-1), 2), 'g=n^2': n*n, 'ratio_f_over_g': round((n*(n.bit_length()-1))/(n*n), 4)} for n in sizes]
def run_example(example=EXAMPLE):
return big_o_big_omega_and_big_theta_p015([10, 100, 1000, 10000])
Manual review notes for students
What to inspect first
Track sizes before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Big-O, Big-Omega, and Big-Theta, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 015 curation harness: Big-O, Big-Omega, and Big-Theta
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Big-O, Big-Omega, and Big-Theta"
SAMPLE = {
"sizes": [
10,
100,
1000,
10000
],
"page_marker": "015-big_o_big_omega_and_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "sizes",
"marker": sample.get("page_marker", "015-big_o_big_omega_and_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "sizes": []} if "sizes" in sample else dict(sample)),
("single-step", {**sample, "sizes": sample.get("sizes", [])[:1]} if isinstance(sample.get("sizes"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "015-big_o_big_omega_and_"))
Browser JavaScript companion
// Page 015 browser-side experiment: Big-O, Big-Omega, and Big-Theta
const pageExample15 = {"sizes":[10,100,1000,10000],"page_marker":"015-big_o_big_omega_and_"};
function summarizePage15(sample = pageExample15) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Big-O, Big-Omega, and Big-Theta",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage15());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['sizes'], then compare it with the first line produced by Big-O, Big-Omega, and Big-Theta.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 015.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement big-o, big-omega, and big-theta twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 016 / 561Chapter 2: Math and Complexity Foundations
Little-o and tight asymptotic language
Page-local deep read
Mental model for Little-o and tight asymptotic language: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 016, the goal is not memorizing little-o and tight asymptotic language; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Little-o and tight asymptotic language is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Little-o and tight asymptotic language before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 016: Little-o and tight asymptotic language
EXAMPLE = {'page': 16, 'topic': 'Little-o and tight asymptotic language', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Little-o and tight asymptotic language.', 'sample_input': {'sizes': [16, 256, 4096, 65536], 'page_marker': '016-little_o_and_tight_a'}, 'expected_output': 'Inspectable result for Little-o and tight asymptotic language', 'watch_for': 'The invariant that makes Little-o and tight asymptotic language safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 016; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'sizes'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def little_o_and_tight_asymptotic_language_p016(sizes):
return [{'n': n, 'n_over_nlogn': round(n/(n*max(1,n.bit_length()-1)), 5), 'interpretation': 'ratio trends toward 0 for little-o comparison'} for n in sizes]
def run_example(example=EXAMPLE):
return little_o_and_tight_asymptotic_language_p016([16, 256, 4096, 65536])
Complexity Explorer
Choose a growth function and input size. The curve is scaled to fit so you can compare shapes.
Manual review notes for students
What to inspect first
Track sizes before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Little-o and tight asymptotic language, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 016 curation harness: Little-o and tight asymptotic language
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Little-o and tight asymptotic language"
SAMPLE = {
"sizes": [
16,
256,
4096,
65536
],
"page_marker": "016-little_o_and_tight_a"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "sizes",
"marker": sample.get("page_marker", "016-little_o_and_tight_a"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "sizes": []} if "sizes" in sample else dict(sample)),
("single-step", {**sample, "sizes": sample.get("sizes", [])[:1]} if isinstance(sample.get("sizes"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "016-little_o_and_tight_a"))
Browser JavaScript companion
// Page 016 browser-side experiment: Little-o and tight asymptotic language
const pageExample16 = {"sizes":[16,256,4096,65536],"page_marker":"016-little_o_and_tight_a"};
function summarizePage16(sample = pageExample16) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Little-o and tight asymptotic language",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage16());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['sizes'], then compare it with the first line produced by Little-o and tight asymptotic language.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 016.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for little-o and tight asymptotic language and explain what each one stresses.
Page 017 / 561Chapter 2: Math and Complexity Foundations
Common growth-rate hierarchy
Page-local deep read
Mental model for Common growth-rate hierarchy: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 017, the goal is not memorizing common growth-rate hierarchy; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Common growth-rate hierarchy is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Common growth-rate hierarchy before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 017: Common growth-rate hierarchy
EXAMPLE = {'page': 17, 'topic': 'Common growth-rate hierarchy', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Common growth-rate hierarchy.', 'sample_input': {'n': 32, 'page_marker': '017-common_growth_rate_h'}, 'expected_output': 'Inspectable result for Common growth-rate hierarchy', 'watch_for': 'The invariant that makes Common growth-rate hierarchy safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 017; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'n'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def common_growth_rate_hierarchy_p017(n):
return [('1',1), ('log n', n.bit_length()-1), ('n',n), ('n log n', n*(n.bit_length()-1)), ('n^2',n*n), ('2^n', 2**min(n,20))]
def run_example(example=EXAMPLE):
return common_growth_rate_hierarchy_p017(32)
Manual review notes for students
What to inspect first
Track n before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Common growth-rate hierarchy, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 017 curation harness: Common growth-rate hierarchy
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Common growth-rate hierarchy"
SAMPLE = {
"n": 32,
"page_marker": "017-common_growth_rate_h"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "017-common_growth_rate_h"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "017-common_growth_rate_h"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Common growth-rate hierarchy.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 017.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for common growth-rate hierarchy, then point to the line of code that preserves it.
Page 018 / 561Chapter 2: Math and Complexity Foundations
Best, worst, average, and amortized cost
Page-local deep read
Mental model for Best, worst, average, and amortized cost: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 018, the goal is not memorizing best, worst, average, and amortized cost; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Best, worst, average, and amortized cost is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Best, worst, average, and amortized cost before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
Look for Best, worst, average, and amortized cost whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 018: Best, worst, average, and amortized cost
EXAMPLE = {'page': 18, 'topic': 'Best, worst, average, and amortized cost', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Best, worst, average, and amortized cost.', 'sample_input': {'values': [10, 20, 30, 40, 50], 'page_marker': '018-best_worst_average_a'}, 'expected_output': 'Inspectable result for Best, worst, average, and amortized cost', 'watch_for': 'The invariant that makes Best, worst, average, and amortized cost safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 018; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'values'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def best_worst_average_and_amortized_cost_p018(values):
best = 1 if values else 0
worst = len(values)
average_probe_count = sum(range(1, len(values)+1)) / max(1, len(values))
return {'best_case_find_first': best, 'worst_case_missing': worst, 'average_successful_linear_search': average_probe_count}
def run_example(example=EXAMPLE):
return best_worst_average_and_amortized_cost_p018([10,20,30,40,50])
Manual review notes for students
What to inspect first
Track values before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Best, worst, average, and amortized cost, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 018 curation harness: Best, worst, average, and amortized cost
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Best, worst, average, and amortized cost"
SAMPLE = {
"values": [
10,
20,
30,
40,
50
],
"page_marker": "018-best_worst_average_a"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "018-best_worst_average_a"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "018-best_worst_average_a"))
Browser JavaScript companion
// Page 018 browser-side experiment: Best, worst, average, and amortized cost
const pageExample18 = {"values":[10,20,30,40,50],"page_marker":"018-best_worst_average_a"};
function summarizePage18(sample = pageExample18) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Best, worst, average, and amortized cost",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage18());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Best, worst, average, and amortized cost.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 018.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 019 / 561Chapter 2: Math and Complexity Foundations
Counting operations without fooling yourself
Page-local deep read
Mental model for Counting operations without fooling yourself: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 019, the goal is not memorizing counting operations without fooling yourself; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Counting operations without fooling yourself is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Counting operations without fooling yourself before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
# Page 019: Counting operations without fooling yourself
EXAMPLE = {'page': 19, 'topic': 'Counting operations without fooling yourself', 'chapter': 'Math and Complexity Foundations', 'kind': 'counter', 'scenario': 'Run a concrete counter miniature for Counting operations without fooling yourself.', 'sample_input': {'values': [5, 3, 4, 1, 2], 'page_marker': '019-counting_operations_'}, 'expected_output': 'Inspectable result for Counting operations without fooling yourself', 'watch_for': 'The invariant that makes Counting operations without fooling yourself safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the counter example changes first.', 'docs': [['Python collections deque/Counter', 'https://docs.python.org/3/library/collections.html']], 'visual_gate_note': 'This is page 019; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'values'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def counting_operations_without_fooling_yourself_p019(values):
comparisons = assignments = 0
best = None
for value in values:
comparisons += 1
if best is None or value < best:
best = value; assignments += 1
return {'min': best, 'comparisons': comparisons, 'assignments': assignments}
def run_example(example=EXAMPLE):
return counting_operations_without_fooling_yourself_p019([5,3,4,1,2])
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Counting operations without fooling yourself, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 019 curation harness: Counting operations without fooling yourself
EXAMPLE_KIND = "counter"
EXAMPLE_TITLE = "Counting operations without fooling yourself"
SAMPLE = {
"values": [
5,
3,
4,
1,
2
],
"page_marker": "019-counting_operations_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "019-counting_operations_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "019-counting_operations_"))
Browser JavaScript companion
// Page 019 browser-side experiment: Counting operations without fooling yourself
const pageExample19 = {"values":[5,3,4,1,2],"page_marker":"019-counting_operations_"};
function summarizePage19(sample = pageExample19) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Counting operations without fooling yourself",
kind: "counter",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage19());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Counting operations without fooling yourself.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the counter invariant described in the code comments and return a stable, inspectable result for page 019.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 020 / 561Chapter 2: Math and Complexity Foundations
Recurrences and recursion trees
Page-local deep read
Mental model for Recurrences and recursion trees: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 020, the goal is not memorizing recurrences and recursion trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Recurrences and recursion trees is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Recurrences and recursion trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
# Page 020: Recurrences and recursion trees
EXAMPLE = {'page': 20, 'topic': 'Recurrences and recursion trees', 'chapter': 'Math and Complexity Foundations', 'kind': 'recursion_pattern', 'scenario': 'Run a concrete recursion pattern miniature for Recurrences and recursion trees.', 'sample_input': {'n': 64, 'branch': 2, 'page_marker': '020-recurrences_and_recu'}, 'expected_output': 'Inspectable result for Recurrences and recursion trees', 'watch_for': 'The invariant that makes Recurrences and recursion trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the recursion pattern example changes first.', 'docs': [], 'visual_gate_note': 'This is page 020; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'n'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def recurrences_and_recursion_trees_p020(n, branch=2):
level, size, rows = 0, n, []
while size >= 1:
rows.append({'level': level, 'subproblems': branch**level, 'subproblem_size': size})
level += 1; size //= 2
return rows
def run_example(example=EXAMPLE):
return recurrences_and_recursion_trees_p020(64)
Manual review notes for students
What to inspect first
Track n, branch before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Recurrences and recursion trees, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 020 curation harness: Recurrences and recursion trees
EXAMPLE_KIND = "recursion_pattern"
EXAMPLE_TITLE = "Recurrences and recursion trees"
SAMPLE = {
"n": 64,
"branch": 2,
"page_marker": "020-recurrences_and_recu"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "020-recurrences_and_recu"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "020-recurrences_and_recu"))
Browser JavaScript companion
// Page 020 browser-side experiment: Recurrences and recursion trees
const pageExample20 = {"n":64,"branch":2,"page_marker":"020-recurrences_and_recu"};
function summarizePage20(sample = pageExample20) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Recurrences and recursion trees",
kind: "recursion_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage20());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Recurrences and recursion trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the recursion pattern invariant described in the code comments and return a stable, inspectable result for page 020.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement recurrences and recursion trees twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 021 / 561Chapter 2: Math and Complexity Foundations
The Master theorem in practice
Page-local deep read
Mental model for The Master theorem in practice: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 021, the goal is not memorizing the master theorem in practice; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: The Master theorem in practice is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for The Master theorem in practice before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 021: The Master theorem in practice
EXAMPLE = {'page': 21, 'topic': 'The Master theorem in practice', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for The Master theorem in practice.', 'sample_input': {'a': 2, 'b': 2, 'd': 1, 'page_marker': '021-the_master_theorem_i'}, 'expected_output': 'Inspectable result for The Master theorem in practice', 'watch_for': 'The invariant that makes The Master theorem in practice safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 021; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'a'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def the_master_theorem_in_practice_p021(a, b, d):
from math import log
critical = log(a, b)
if d < critical: case = 'case 1: recursive leaves dominate'
elif d == critical: case = 'case 2: balanced levels add log factor'
else: case = 'case 3: combine work dominates'
return {'a': a, 'b': b, 'd': d, 'log_b_a': round(critical, 3), 'master_case': case}
def run_example(example=EXAMPLE):
return the_master_theorem_in_practice_p021(2, 2, 1)
Manual review notes for students
What to inspect first
Track a, b, d before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of The Master theorem in practice, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 021 curation harness: The Master theorem in practice
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "The Master theorem in practice"
SAMPLE = {
"a": 2,
"b": 2,
"d": 1,
"page_marker": "021-the_master_theorem_i"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "a",
"marker": sample.get("page_marker", "021-the_master_theorem_i"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "a": []} if "a" in sample else dict(sample)),
("single-step", {**sample, "a": sample.get("a", [])[:1]} if isinstance(sample.get("a"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "021-the_master_theorem_i"))
Browser JavaScript companion
// Page 021 browser-side experiment: The Master theorem in practice
const pageExample21 = {"a":2,"b":2,"d":1,"page_marker":"021-the_master_theorem_i"};
function summarizePage21(sample = pageExample21) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "The Master theorem in practice",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage21());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by The Master theorem in practice.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 021.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for the master theorem in practice and explain what each one stresses.
Page 022 / 561Chapter 2: Math and Complexity Foundations
Substitution method for recurrences
Page-local deep read
Mental model for Substitution method for recurrences: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 022, the goal is not memorizing substitution method for recurrences; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Substitution method for recurrences is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Substitution method for recurrences before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
# Page 022: Substitution method for recurrences
EXAMPLE = {'page': 22, 'topic': 'Substitution method for recurrences', 'chapter': 'Math and Complexity Foundations', 'kind': 'balanced_tree', 'scenario': 'Run a concrete balanced tree miniature for Substitution method for recurrences.', 'sample_input': {'n': 64, 'guess': 2, 'page_marker': '022-substitution_method_'}, 'expected_output': 'Inspectable result for Substitution method for recurrences', 'watch_for': 'The invariant that makes Substitution method for recurrences safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the balanced tree example changes first.', 'docs': [], 'visual_gate_note': 'This is page 022; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'n'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def substitution_method_for_recurrences_p022(n, guess):
# Verify a simple recurrence T(n)=T(n/2)+n against a proposed bound C*n.
rows = []
while n >= 1:
rows.append({'n': n, 'work_this_level': n, 'guess_bound': guess*n})
n //= 2
return rows
def run_example(example=EXAMPLE):
return substitution_method_for_recurrences_p022(64, 2)
Manual review notes for students
What to inspect first
Track n, guess before reading the answer.
Common trap
Do not memorize the label "Substitution method for recurrences" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 022 curation harness: Substitution method for recurrences
EXAMPLE_KIND = "balanced_tree"
EXAMPLE_TITLE = "Substitution method for recurrences"
SAMPLE = {
"n": 64,
"guess": 2,
"page_marker": "022-substitution_method_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "022-substitution_method_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "022-substitution_method_"))
Browser JavaScript companion
// Page 022 browser-side experiment: Substitution method for recurrences
const pageExample22 = {"n":64,"guess":2,"page_marker":"022-substitution_method_"};
function summarizePage22(sample = pageExample22) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Substitution method for recurrences",
kind: "balanced_tree",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage22());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Substitution method for recurrences.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the balanced tree invariant described in the code comments and return a stable, inspectable result for page 022.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for substitution method for recurrences, then point to the line of code that preserves it.
Page 023 / 561Chapter 2: Math and Complexity Foundations
Lower bounds and decision trees
Page-local deep read
Mental model for Lower bounds and decision trees: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 023, the goal is not memorizing lower bounds and decision trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Lower bounds and decision trees is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Lower bounds and decision trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
# Page 023: Lower bounds and decision trees
EXAMPLE = {'page': 23, 'topic': 'Lower bounds and decision trees', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Lower bounds and decision trees.', 'sample_input': {'items': ['a', 'b', 'c', 'd'], 'page_marker': '023-lower_bounds_and_dec'}, 'expected_output': 'Inspectable result for Lower bounds and decision trees', 'watch_for': 'The invariant that makes Lower bounds and decision trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 023; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'items'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def lower_bounds_and_decision_trees_p023(items):
import math
leaves = math.factorial(len(items))
comparisons_needed = math.ceil(math.log2(leaves)) if leaves else 0
return {'permutations_to_distinguish': leaves, 'decision_tree_height_lower_bound': comparisons_needed}
def run_example(example=EXAMPLE):
return lower_bounds_and_decision_trees_p023(['a','b','c','d'])
Manual review notes for students
What to inspect first
Track items before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Lower bounds and decision trees, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 023 curation harness: Lower bounds and decision trees
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Lower bounds and decision trees"
SAMPLE = {
"items": [
"a",
"b",
"c",
"d"
],
"page_marker": "023-lower_bounds_and_dec"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "items",
"marker": sample.get("page_marker", "023-lower_bounds_and_dec"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "items": []} if "items" in sample else dict(sample)),
("single-step", {**sample, "items": sample.get("items", [])[:1]} if isinstance(sample.get("items"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "023-lower_bounds_and_dec"))
Browser JavaScript companion
// Page 023 browser-side experiment: Lower bounds and decision trees
const pageExample23 = {"items":["a","b","c","d"],"page_marker":"023-lower_bounds_and_dec"};
function summarizePage23(sample = pageExample23) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Lower bounds and decision trees",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage23());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Lower bounds and decision trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 023.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 024 / 561Chapter 2: Math and Complexity Foundations
Adversarial inputs and input distributions
Page-local deep read
Mental model for Adversarial inputs and input distributions: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 024, the goal is not memorizing adversarial inputs and input distributions; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Adversarial inputs and input distributions is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Adversarial inputs and input distributions before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 024: Adversarial inputs and input distributions
EXAMPLE = {'page': 24, 'topic': 'Adversarial inputs and input distributions', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Adversarial inputs and input distributions.', 'sample_input': {'values': [1, 2, 3, 4, 5, 6], 'page_marker': '024-adversarial_inputs_a'}, 'expected_output': 'Inspectable result for Adversarial inputs and input distributions', 'watch_for': 'The invariant that makes Adversarial inputs and input distributions safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 024; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'values'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def adversarial_inputs_and_input_distributions_p024(values):
return {
'already_sorted': values == sorted(values),
'reverse_sorted': values == sorted(values, reverse=True),
'all_equal': len(set(values)) <= 1,
'candidate_adversary_for_quicksort_first_pivot': values == sorted(values),
}
def run_example(example=EXAMPLE):
return adversarial_inputs_and_input_distributions_p024([1,2,3,4,5,6])
Manual review notes for students
What to inspect first
Track values before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Adversarial inputs and input distributions, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 024 curation harness: Adversarial inputs and input distributions
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Adversarial inputs and input distributions"
SAMPLE = {
"values": [
1,
2,
3,
4,
5,
6
],
"page_marker": "024-adversarial_inputs_a"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "024-adversarial_inputs_a"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "024-adversarial_inputs_a"))
Browser JavaScript companion
// Page 024 browser-side experiment: Adversarial inputs and input distributions
const pageExample24 = {"values":[1,2,3,4,5,6],"page_marker":"024-adversarial_inputs_a"};
function summarizePage24(sample = pageExample24) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Adversarial inputs and input distributions",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage24());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Adversarial inputs and input distributions.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 024.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 025 / 561Chapter 2: Math and Complexity Foundations
Potential functions for amortized analysis
Page-local deep read
Mental model for Potential functions for amortized analysis: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 025, the goal is not memorizing potential functions for amortized analysis; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Potential functions for amortized analysis is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Potential functions for amortized analysis before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 025: Potential functions for amortized analysis
EXAMPLE = {'page': 25, 'topic': 'Potential functions for amortized analysis', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Potential functions for amortized analysis.', 'sample_input': {'operations': ['append', 'append', 'append', 'append', 'append', 'append'], 'page_marker': '025-potential_functions_'}, 'expected_output': 'Inspectable result for Potential functions for amortized analysis', 'watch_for': 'The invariant that makes Potential functions for amortized analysis safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 025; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'operations'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def potential_functions_for_amortized_analysis_p025(operations):
size = capacity = potential = 0; trace = []
for op in operations:
actual = 1
if op == 'append' and size == capacity:
actual += size; capacity = max(1, 2*capacity)
if op == 'append': size += 1
old_potential, potential = potential, 2*size - capacity
trace.append({'op': op, 'actual_cost': actual, 'delta_potential': potential-old_potential, 'amortized': actual + potential-old_potential, 'size': size, 'capacity': capacity})
return trace
def run_example(example=EXAMPLE):
return potential_functions_for_amortized_analysis_p025(['append']*6)
Manual review notes for students
What to inspect first
Track operations before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Potential functions for amortized analysis, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 025 curation harness: Potential functions for amortized analysis
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Potential functions for amortized analysis"
SAMPLE = {
"operations": [
"append",
"append",
"append",
"append",
"append",
"append"
],
"page_marker": "025-potential_functions_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "operations",
"marker": sample.get("page_marker", "025-potential_functions_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "operations": []} if "operations" in sample else dict(sample)),
("single-step", {**sample, "operations": sample.get("operations", [])[:1]} if isinstance(sample.get("operations"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "025-potential_functions_"))
Browser JavaScript companion
// Page 025 browser-side experiment: Potential functions for amortized analysis
const pageExample25 = {"operations":["append","append","append","append","append","append"],"page_marker":"025-potential_functions_"};
function summarizePage25(sample = pageExample25) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Potential functions for amortized analysis",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage25());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['operations'], then compare it with the first line produced by Potential functions for amortized analysis.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 025.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement potential functions for amortized analysis twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 026 / 561Chapter 2: Math and Complexity Foundations
Aggregate analysis examples
Page-local deep read
Mental model for Aggregate analysis examples: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 026, the goal is not memorizing aggregate analysis examples; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Aggregate analysis examples is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Aggregate analysis examples before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 026: Aggregate analysis examples
EXAMPLE = {'page': 26, 'topic': 'Aggregate analysis examples', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Aggregate analysis examples.', 'sample_input': {'pushes': 8, 'pops': 5, 'page_marker': '026-aggregate_analysis_e'}, 'expected_output': 'Inspectable result for Aggregate analysis examples', 'watch_for': 'The invariant that makes Aggregate analysis examples safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 026; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'pushes'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def aggregate_analysis_examples_p026(pushes, pops):
return {'total_push_cost': pushes, 'total_pop_cost': pops, 'aggregate_cost': pushes+pops, 'cost_per_operation': (pushes+pops)/(pushes+pops)}
def run_example(example=EXAMPLE):
return aggregate_analysis_examples_p026(8, 5)
Manual review notes for students
What to inspect first
Track pushes, pops before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Aggregate analysis examples, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 026 curation harness: Aggregate analysis examples
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Aggregate analysis examples"
SAMPLE = {
"pushes": 8,
"pops": 5,
"page_marker": "026-aggregate_analysis_e"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "pushes",
"marker": sample.get("page_marker", "026-aggregate_analysis_e"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "pushes": []} if "pushes" in sample else dict(sample)),
("single-step", {**sample, "pushes": sample.get("pushes", [])[:1]} if isinstance(sample.get("pushes"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "026-aggregate_analysis_e"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['pushes'], then compare it with the first line produced by Aggregate analysis examples.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 026.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for aggregate analysis examples and explain what each one stresses.
Page 027 / 561Chapter 2: Math and Complexity Foundations
Space complexity and memory traffic
Page-local deep read
Mental model for Space complexity and memory traffic: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 027, the goal is not memorizing space complexity and memory traffic; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Space complexity and memory traffic is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Space complexity and memory traffic before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 027: Space complexity and memory traffic
EXAMPLE = {'page': 27, 'topic': 'Space complexity and memory traffic', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Space complexity and memory traffic.', 'sample_input': {'n': 1000, 'recursion_depth': 10, 'table_cells': 200, 'page_marker': '027-space_complexity_and'}, 'expected_output': 'Inspectable result for Space complexity and memory traffic', 'watch_for': 'The invariant that makes Space complexity and memory traffic safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [['Python functools.cache/lru_cache', 'https://docs.python.org/3/library/functools.html']], 'visual_gate_note': 'This is page 027; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'n'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def space_complexity_and_memory_traffic_p027(n, recursion_depth, table_cells):
return {'input_array_cells': n, 'call_stack_cells': recursion_depth, 'dp_table_cells': table_cells, 'total_auxiliary_cells': recursion_depth + table_cells}
def run_example(example=EXAMPLE):
return space_complexity_and_memory_traffic_p027(1000, 10, 200)
Track n, recursion_depth, table_cells before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Space complexity and memory traffic, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 027 curation harness: Space complexity and memory traffic
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Space complexity and memory traffic"
SAMPLE = {
"n": 1000,
"recursion_depth": 10,
"table_cells": 200,
"page_marker": "027-space_complexity_and"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "027-space_complexity_and"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "027-space_complexity_and"))
Browser JavaScript companion
// Page 027 browser-side experiment: Space complexity and memory traffic
const pageExample27 = {"n":1000,"recursion_depth":10,"table_cells":200,"page_marker":"027-space_complexity_and"};
function summarizePage27(sample = pageExample27) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Space complexity and memory traffic",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage27());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Space complexity and memory traffic.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 027.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for space complexity and memory traffic, then point to the line of code that preserves it.
Page 028 / 561Chapter 2: Math and Complexity Foundations
Benchmarking versus asymptotic reasoning
Page-local deep read
Mental model for Benchmarking versus asymptotic reasoning: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 028, the goal is not memorizing benchmarking versus asymptotic reasoning; it is recognizing the representation, the safe transition, and the stopping condition inside the Math and Complexity Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Benchmarking versus asymptotic reasoning is one small tool in the larger Math and Complexity Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Benchmarking versus asymptotic reasoning before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Complexity analysis abstracts away machine details so you can predict how a solution scales. The goal is not to count every instruction; it is to identify the term that dominates as input size grows.
Use asymptotic notation to compare designs, derive recurrences for recursive algorithms, and decide whether an optimization changes the class of the algorithm or only the constant factors.
Look for Benchmarking versus asymptotic reasoning whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: watch hidden input size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting that input size may be number of bits, vertices plus edges, or rows times columns is a common source of wrong bounds.
# Page 028: Benchmarking versus asymptotic reasoning
EXAMPLE = {'page': 28, 'topic': 'Benchmarking versus asymptotic reasoning', 'chapter': 'Math and Complexity Foundations', 'kind': 'math', 'scenario': 'Run a concrete math miniature for Benchmarking versus asymptotic reasoning.', 'sample_input': {'measurements': [[100, 0.2], [1000, 2.5], [10000, 33.0]], 'page_marker': '028-benchmarking_versus_'}, 'expected_output': 'Inspectable result for Benchmarking versus asymptotic reasoning', 'watch_for': 'The invariant that makes Benchmarking versus asymptotic reasoning safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the math example changes first.', 'docs': [], 'visual_gate_note': 'This is page 028; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'measurements'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def benchmarking_versus_asymptotic_reasoning_p028(measurements):
return [{'n': n, 'milliseconds': ms, 'ms_per_nlogn': round(ms/max(1,n*(n.bit_length()-1)), 6)} for n, ms in measurements]
def run_example(example=EXAMPLE):
return benchmarking_versus_asymptotic_reasoning_p028([(100,0.2), (1000,2.5), (10000,33.0)])
Manual review notes for students
What to inspect first
Track measurements before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Benchmarking versus asymptotic reasoning, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 028 curation harness: Benchmarking versus asymptotic reasoning
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Benchmarking versus asymptotic reasoning"
SAMPLE = {
"measurements": [
[
100,
0.2
],
[
1000,
2.5
],
[
10000,
33
]
],
"page_marker": "028-benchmarking_versus_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "measurements",
"marker": sample.get("page_marker", "028-benchmarking_versus_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "measurements": []} if "measurements" in sample else dict(sample)),
("single-step", {**sample, "measurements": sample.get("measurements", [])[:1]} if isinstance(sample.get("measurements"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "028-benchmarking_versus_"))
Browser JavaScript companion
// Page 028 browser-side experiment: Benchmarking versus asymptotic reasoning
const pageExample28 = {"measurements":[[100,0.2],[1000,2.5],[10000,33]],"page_marker":"028-benchmarking_versus_"};
function summarizePage28(sample = pageExample28) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Benchmarking versus asymptotic reasoning",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage28());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['measurements'], then compare it with the first line produced by Benchmarking versus asymptotic reasoning.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the math invariant described in the code comments and return a stable, inspectable result for page 028.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 029 / 561Chapter 3: Correctness, Proofs, and Testing
Preconditions, postconditions, and contracts
Page-local deep read
Mental model for Preconditions, postconditions, and contracts: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 029, the goal is not memorizing preconditions, postconditions, and contracts; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Preconditions, postconditions, and contracts is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Preconditions, postconditions, and contracts before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 3: Correctness, Proofs, and Testing
function insertionSortChecked(values) {
const a = [...values];
for (let i = 1; i < a.length; i++) {
const key = a[i]; let j = i - 1;
while (j >= 0 && a[j] > key) { a[j + 1] = a[j]; j--; }
a[j + 1] = key;
const prefix = a.slice(0, i + 1);
if (prefix.join(',') !== [...prefix].sort((x, y) => x - y).join(',')) throw new Error('invariant failed');
}
return a;
}
console.log(insertionSortChecked([3, 1, 2]));
Chapter anchor: This page is the Chapter 03 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Correctness, Proofs, and Testing.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
# Page 029: Preconditions, postconditions, and contracts
EXAMPLE = {'page': 29, 'topic': 'Preconditions, postconditions, and contracts', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Preconditions, postconditions, and contracts.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '029-preconditions_postco'}, 'expected_output': 'Inspectable result for Preconditions, postconditions, and contracts', 'watch_for': 'The invariant that makes Preconditions, postconditions, and contracts safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 029; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def preconditions_postconditions_and_contracts_p029(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Preconditions, postconditions, and contracts'}
def run_example(example=EXAMPLE):
return preconditions_postconditions_and_contracts_p029([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Preconditions, postconditions, and contracts, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 029 curation harness: Preconditions, postconditions, and contracts
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Preconditions, postconditions, and contracts"
SAMPLE = {
"candidate": [
1,
2,
3
],
"checker": "nondecreasing order",
"page_marker": "029-preconditions_postco"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "candidate",
"marker": sample.get("page_marker", "029-preconditions_postco"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "candidate": []} if "candidate" in sample else dict(sample)),
("single-step", {**sample, "candidate": sample.get("candidate", [])[:1]} if isinstance(sample.get("candidate"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "029-preconditions_postco"))
Browser JavaScript companion
// Page 029 browser-side experiment: Preconditions, postconditions, and contracts
const pageExample29 = {"candidate":[1,2,3],"checker":"nondecreasing order","page_marker":"029-preconditions_postco"};
function summarizePage29(sample = pageExample29) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Preconditions, postconditions, and contracts",
kind: "proof",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage29());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Preconditions, postconditions, and contracts.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 029.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 030 / 561Chapter 3: Correctness, Proofs, and Testing
Loop invariants
Page-local deep read
Mental model for Loop invariants: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 030, the goal is not memorizing loop invariants; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Loop invariants is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Loop invariants before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
# Page 030: Loop invariants
EXAMPLE = {'page': 30, 'topic': 'Loop invariants', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Loop invariants.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '030-loop_invariants'}, 'expected_output': 'Inspectable result for Loop invariants', 'watch_for': 'The invariant that makes Loop invariants safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 030; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def loop_invariants_p030(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Loop invariants'}
def run_example(example=EXAMPLE):
return loop_invariants_p030([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Loop invariants, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 030 curation harness: Loop invariants
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Loop invariants"
SAMPLE = {
"candidate": [
1,
2,
3
],
"checker": "nondecreasing order",
"page_marker": "030-loop_invariants"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "candidate",
"marker": sample.get("page_marker", "030-loop_invariants"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "candidate": []} if "candidate" in sample else dict(sample)),
("single-step", {**sample, "candidate": sample.get("candidate", [])[:1]} if isinstance(sample.get("candidate"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "030-loop_invariants"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Loop invariants.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 030.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement loop invariants twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 031 / 561Chapter 3: Correctness, Proofs, and Testing
Induction and structural induction
Page-local deep read
Mental model for Induction and structural induction: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 031, the goal is not memorizing induction and structural induction; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Induction and structural induction is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Induction and structural induction before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: missing edge cases. Make this risk visible in tests and in code comments.
Common pitfall: A test suite can show a bug, but it cannot replace a proof that covers all valid inputs.
# Page 031: Induction and structural induction
EXAMPLE = {'page': 31, 'topic': 'Induction and structural induction', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Induction and structural induction.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '031-induction_and_struct'}, 'expected_output': 'Inspectable result for Induction and structural induction', 'watch_for': 'The invariant that makes Induction and structural induction safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 031; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def induction_and_structural_induction_p031(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Induction and structural induction'}
def run_example(example=EXAMPLE):
return induction_and_structural_induction_p031([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Induction and structural induction, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 031 curation harness: Induction and structural induction
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Induction and structural induction"
SAMPLE = {
"candidate": [
1,
2,
3
],
"checker": "nondecreasing order",
"page_marker": "031-induction_and_struct"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "candidate",
"marker": sample.get("page_marker", "031-induction_and_struct"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "candidate": []} if "candidate" in sample else dict(sample)),
("single-step", {**sample, "candidate": sample.get("candidate", [])[:1]} if isinstance(sample.get("candidate"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "031-induction_and_struct"))
Browser JavaScript companion
// Page 031 browser-side experiment: Induction and structural induction
const pageExample31 = {"candidate":[1,2,3],"checker":"nondecreasing order","page_marker":"031-induction_and_struct"};
function summarizePage31(sample = pageExample31) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Induction and structural induction",
kind: "proof",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage31());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Induction and structural induction.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 031.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for induction and structural induction and explain what each one stresses.
Page 032 / 561Chapter 3: Correctness, Proofs, and Testing
Exchange arguments
Page-local deep read
Mental model for Exchange arguments: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 032, the goal is not memorizing exchange arguments; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Exchange arguments is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Exchange arguments before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
# Page 032: Exchange arguments
EXAMPLE = {'page': 32, 'topic': 'Exchange arguments', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Exchange arguments.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '032-exchange_arguments'}, 'expected_output': 'Inspectable result for Exchange arguments', 'watch_for': 'The invariant that makes Exchange arguments safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 032; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def exchange_arguments_p032(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Exchange arguments'}
def run_example(example=EXAMPLE):
return exchange_arguments_p032([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Exchange arguments, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 032 curation harness: Exchange arguments
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Exchange arguments"
SAMPLE = {
"candidate": [
1,
2,
3
],
"checker": "nondecreasing order",
"page_marker": "032-exchange_arguments"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "candidate",
"marker": sample.get("page_marker", "032-exchange_arguments"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "candidate": []} if "candidate" in sample else dict(sample)),
("single-step", {**sample, "candidate": sample.get("candidate", [])[:1]} if isinstance(sample.get("candidate"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "032-exchange_arguments"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Exchange arguments.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 032.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for exchange arguments, then point to the line of code that preserves it.
Page 033 / 561Chapter 3: Correctness, Proofs, and Testing
Cut and cycle properties
Page-local deep read
Mental model for Cut and cycle properties: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 033, the goal is not memorizing cut and cycle properties; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Cut and cycle properties is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Cut and cycle properties before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
# Page 033: Cut and cycle properties
EXAMPLE = {'page': 33, 'topic': 'Cut and cycle properties', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Cut and cycle properties.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '033-cut_and_cycle_proper'}, 'expected_output': 'Inspectable result for Cut and cycle properties', 'watch_for': 'The invariant that makes Cut and cycle properties safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 033; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def cut_and_cycle_properties_p033(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Cut and cycle properties'}
def run_example(example=EXAMPLE):
return cut_and_cycle_properties_p033([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Cut and cycle properties, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 033 curation harness: Cut and cycle properties
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Cut and cycle properties"
SAMPLE = {
"candidate": [
1,
2,
3
],
"checker": "nondecreasing order",
"page_marker": "033-cut_and_cycle_proper"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "candidate",
"marker": sample.get("page_marker", "033-cut_and_cycle_proper"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "candidate": []} if "candidate" in sample else dict(sample)),
("single-step", {**sample, "candidate": sample.get("candidate", [])[:1]} if isinstance(sample.get("candidate"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "033-cut_and_cycle_proper"))
Browser JavaScript companion
// Page 033 browser-side experiment: Cut and cycle properties
const pageExample33 = {"candidate":[1,2,3],"checker":"nondecreasing order","page_marker":"033-cut_and_cycle_proper"};
function summarizePage33(sample = pageExample33) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Cut and cycle properties",
kind: "proof",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage33());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Cut and cycle properties.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 033.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 034 / 561Chapter 3: Correctness, Proofs, and Testing
Greedy stays-ahead proofs
Page-local deep read
Mental model for Greedy stays-ahead proofs: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 034, the goal is not memorizing greedy stays-ahead proofs; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Greedy stays-ahead proofs is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Greedy stays-ahead proofs before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: missing edge cases. Make this risk visible in tests and in code comments.
Common pitfall: A test suite can show a bug, but it cannot replace a proof that covers all valid inputs.
# Page 034: Greedy stays-ahead proofs
EXAMPLE = {'page': 34, 'topic': 'Greedy stays-ahead proofs', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Greedy stays-ahead proofs.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '034-greedy_stays_ahead_p'}, 'expected_output': 'Inspectable result for Greedy stays-ahead proofs', 'watch_for': 'The invariant that makes Greedy stays-ahead proofs safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 034; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def greedy_stays_ahead_proofs_p034(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Greedy stays-ahead proofs'}
def run_example(example=EXAMPLE):
return greedy_stays_ahead_proofs_p034([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Greedy stays-ahead proofs, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Greedy stays-ahead proofs.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 034.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 035 / 561Chapter 3: Correctness, Proofs, and Testing
Minimal counterexample proofs
Page-local deep read
Mental model for Minimal counterexample proofs: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 035, the goal is not memorizing minimal counterexample proofs; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Minimal counterexample proofs is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Minimal counterexample proofs before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: missing edge cases. Make this risk visible in tests and in code comments.
Common pitfall: A test suite can show a bug, but it cannot replace a proof that covers all valid inputs.
# Page 035: Minimal counterexample proofs
EXAMPLE = {'page': 35, 'topic': 'Minimal counterexample proofs', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Minimal counterexample proofs.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '035-minimal_counterexamp'}, 'expected_output': 'Inspectable result for Minimal counterexample proofs', 'watch_for': 'The invariant that makes Minimal counterexample proofs safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [['Python collections deque/Counter', 'https://docs.python.org/3/library/collections.html']], 'visual_gate_note': 'This is page 035; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def minimal_counterexample_proofs_p035(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Minimal counterexample proofs'}
def run_example(example=EXAMPLE):
return minimal_counterexample_proofs_p035([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Minimal counterexample proofs, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Minimal counterexample proofs.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 035.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement minimal counterexample proofs twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 036 / 561Chapter 3: Correctness, Proofs, and Testing
Termination and variants
Page-local deep read
Mental model for Termination and variants: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 036, the goal is not memorizing termination and variants; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Termination and variants is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Termination and variants before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: missing edge cases. Make this risk visible in tests and in code comments.
Common pitfall: A test suite can show a bug, but it cannot replace a proof that covers all valid inputs.
# Page 036: Termination and variants
EXAMPLE = {'page': 36, 'topic': 'Termination and variants', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Termination and variants.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '036-termination_and_vari'}, 'expected_output': 'Inspectable result for Termination and variants', 'watch_for': 'The invariant that makes Termination and variants safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 036; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def termination_and_variants_p036(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Termination and variants'}
def run_example(example=EXAMPLE):
return termination_and_variants_p036([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Termination and variants, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 036 curation harness: Termination and variants
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Termination and variants"
SAMPLE = {
"candidate": [
1,
2,
3
],
"checker": "nondecreasing order",
"page_marker": "036-termination_and_vari"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "candidate",
"marker": sample.get("page_marker", "036-termination_and_vari"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "candidate": []} if "candidate" in sample else dict(sample)),
("single-step", {**sample, "candidate": sample.get("candidate", [])[:1]} if isinstance(sample.get("candidate"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "036-termination_and_vari"))
Browser JavaScript companion
// Page 036 browser-side experiment: Termination and variants
const pageExample36 = {"candidate":[1,2,3],"checker":"nondecreasing order","page_marker":"036-termination_and_vari"};
function summarizePage36(sample = pageExample36) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Termination and variants",
kind: "proof",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage36());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Termination and variants.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 036.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for termination and variants and explain what each one stresses.
Page 037 / 561Chapter 3: Correctness, Proofs, and Testing
Randomized algorithm correctness
Page-local deep read
Mental model for Randomized algorithm correctness: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 037, the goal is not memorizing randomized algorithm correctness; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Randomized algorithm correctness is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Randomized algorithm correctness before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: missing edge cases. Make this risk visible in tests and in code comments.
Common pitfall: A test suite can show a bug, but it cannot replace a proof that covers all valid inputs.
# Page 037: Randomized algorithm correctness
EXAMPLE = {'page': 37, 'topic': 'Randomized algorithm correctness', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Randomized algorithm correctness.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '037-randomized_algorithm'}, 'expected_output': 'Inspectable result for Randomized algorithm correctness', 'watch_for': 'The invariant that makes Randomized algorithm correctness safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 037; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def randomized_algorithm_correctness_p037(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Randomized algorithm correctness'}
def run_example(example=EXAMPLE):
return randomized_algorithm_correctness_p037([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Randomized algorithm correctness, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Randomized algorithm correctness.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 037.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for randomized algorithm correctness, then point to the line of code that preserves it.
Page 038 / 561Chapter 3: Correctness, Proofs, and Testing
Property-based testing for algorithms
Page-local deep read
Mental model for Property-based testing for algorithms: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 038, the goal is not memorizing property-based testing for algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Property-based testing for algorithms is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Property-based testing for algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
Look for Property-based testing for algorithms whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: missing edge cases. Make this risk visible in tests and in code comments.
Common pitfall: A test suite can show a bug, but it cannot replace a proof that covers all valid inputs.
# Page 038: Property-based testing for algorithms
EXAMPLE = {'page': 38, 'topic': 'Property-based testing for algorithms', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Property-based testing for algorithms.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '038-property_based_testi'}, 'expected_output': 'Inspectable result for Property-based testing for algorithms', 'watch_for': 'The invariant that makes Property-based testing for algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 038; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def property_based_testing_for_algorithms_p038(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Property-based testing for algorithms'}
def run_example(example=EXAMPLE):
return property_based_testing_for_algorithms_p038([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Property-based testing for algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 038 curation harness: Property-based testing for algorithms
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Property-based testing for algorithms"
SAMPLE = {
"candidate": [
1,
2,
3
],
"checker": "nondecreasing order",
"page_marker": "038-property_based_testi"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "candidate",
"marker": sample.get("page_marker", "038-property_based_testi"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "candidate": []} if "candidate" in sample else dict(sample)),
("single-step", {**sample, "candidate": sample.get("candidate", [])[:1]} if isinstance(sample.get("candidate"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "038-property_based_testi"))
Browser JavaScript companion
// Page 038 browser-side experiment: Property-based testing for algorithms
const pageExample38 = {"candidate":[1,2,3],"checker":"nondecreasing order","page_marker":"038-property_based_testi"};
function summarizePage38(sample = pageExample38) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Property-based testing for algorithms",
kind: "proof",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage38());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Property-based testing for algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 038.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 039 / 561Chapter 3: Correctness, Proofs, and Testing
Metamorphic tests and oracle design
Page-local deep read
Mental model for Metamorphic tests and oracle design: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 039, the goal is not memorizing metamorphic tests and oracle design; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Metamorphic tests and oracle design is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Metamorphic tests and oracle design before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
# Page 039: Metamorphic tests and oracle design
EXAMPLE = {'page': 39, 'topic': 'Metamorphic tests and oracle design', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Metamorphic tests and oracle design.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '039-metamorphic_tests_an'}, 'expected_output': 'Inspectable result for Metamorphic tests and oracle design', 'watch_for': 'The invariant that makes Metamorphic tests and oracle design safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 039; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def metamorphic_tests_and_oracle_design_p039(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Metamorphic tests and oracle design'}
def run_example(example=EXAMPLE):
return metamorphic_tests_and_oracle_design_p039([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Metamorphic tests and oracle design, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 039 curation harness: Metamorphic tests and oracle design
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Metamorphic tests and oracle design"
SAMPLE = {
"candidate": [
1,
2,
3
],
"checker": "nondecreasing order",
"page_marker": "039-metamorphic_tests_an"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "candidate",
"marker": sample.get("page_marker", "039-metamorphic_tests_an"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "candidate": []} if "candidate" in sample else dict(sample)),
("single-step", {**sample, "candidate": sample.get("candidate", [])[:1]} if isinstance(sample.get("candidate"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "039-metamorphic_tests_an"))
Browser JavaScript companion
// Page 039 browser-side experiment: Metamorphic tests and oracle design
const pageExample39 = {"candidate":[1,2,3],"checker":"nondecreasing order","page_marker":"039-metamorphic_tests_an"};
function summarizePage39(sample = pageExample39) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Metamorphic tests and oracle design",
kind: "proof",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage39());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Metamorphic tests and oracle design.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 039.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 040 / 561Chapter 3: Correctness, Proofs, and Testing
Debugging by invariant violation
Page-local deep read
Mental model for Debugging by invariant violation: Treat the algorithm as a claim that needs evidence. The important beginner move is to connect each line of code to a precondition, invariant, or postcondition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 040, the goal is not memorizing debugging by invariant violation; it is recognizing the representation, the safe transition, and the stopping condition inside the Correctness, Proofs, and Testing chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Debugging by invariant violation is one small tool in the larger Correctness, Proofs, and Testing toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Debugging by invariant violation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Correctness is the claim that every valid input produces the required output. Proofs explain why; tests give evidence that the implementation matches the proof assumptions.
Use invariants for loops, induction for recursive structures, exchange arguments for greedy algorithms, and property tests when enumerating expected answers is hard.
# Page 040: Debugging by invariant violation
EXAMPLE = {'page': 40, 'topic': 'Debugging by invariant violation', 'chapter': 'Correctness, Proofs, and Testing', 'kind': 'proof', 'scenario': 'Run a concrete proof miniature for Debugging by invariant violation.', 'sample_input': {'candidate': [1, 2, 3], 'checker': 'nondecreasing order', 'page_marker': '040-debugging_by_invaria'}, 'expected_output': 'Inspectable result for Debugging by invariant violation', 'watch_for': 'The invariant that makes Debugging by invariant violation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the proof example changes first.', 'docs': [], 'visual_gate_note': 'This is page 040; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'candidate'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def debugging_by_invariant_violation_p040(candidate, checker):
result = checker(candidate)
return {'candidate': candidate, 'passes_checker': bool(result), 'proof_note': 'checker models the page invariant for Debugging by invariant violation'}
def run_example(example=EXAMPLE):
return debugging_by_invariant_violation_p040([1,2,3], lambda xs: all(xs[i] <= xs[i+1] for i in range(len(xs)-1)))
Manual review notes for students
What to inspect first
Track candidate, checker before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Debugging by invariant violation, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 040 curation harness: Debugging by invariant violation
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Debugging by invariant violation"
SAMPLE = {
"candidate": [
1,
2,
3
],
"checker": "nondecreasing order",
"page_marker": "040-debugging_by_invaria"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "candidate",
"marker": sample.get("page_marker", "040-debugging_by_invaria"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "candidate": []} if "candidate" in sample else dict(sample)),
("single-step", {**sample, "candidate": sample.get("candidate", [])[:1]} if isinstance(sample.get("candidate"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "040-debugging_by_invaria"))
Browser JavaScript companion
// Page 040 browser-side experiment: Debugging by invariant violation
const pageExample40 = {"candidate":[1,2,3],"checker":"nondecreasing order","page_marker":"040-debugging_by_invaria"};
function summarizePage40(sample = pageExample40) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Debugging by invariant violation",
kind: "proof",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage40());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['candidate'], then compare it with the first line produced by Debugging by invariant violation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the proof invariant described in the code comments and return a stable, inspectable result for page 040.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement debugging by invariant violation twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 041 / 561Chapter 4: Python and JavaScript Algorithm Tooling
Algorithmic Python: lists, tuples, dicts, and sets
Page-local deep read
Mental model for Algorithmic Python: lists, tuples, dicts, and sets: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 041, the goal is not memorizing algorithmic python: lists, tuples, dicts, and sets; it is recognizing the representation, the safe transition, and the stopping condition inside the Python and JavaScript Algorithm Tooling chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Algorithmic Python: lists, tuples, dicts, and sets is one small tool in the larger Python and JavaScript Algorithm Tooling toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Algorithmic Python: lists, tuples, dicts, and sets before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 4: Python and JavaScript Algorithm Tooling
function benchmarkOnce(fn, input) {
const start = performance.now ? performance.now() : Date.now();
const output = fn(input);
const end = performance.now ? performance.now() : Date.now();
return { milliseconds: end - start, output };
}
console.log(benchmarkOnce(xs => [...xs].sort((a, b) => a - b), [4, 1, 3]));
Chapter anchor: This page is the Chapter 04 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Python and JavaScript Algorithm Tooling.
Language libraries encode mature implementations of common algorithmic building blocks. Knowing their contracts prevents accidental O(n²) code and makes reference implementations shorter.
Use deque for FIFO queues, heapq for priority queues, bisect for insertion points in sorted lists, functools for memoization, itertools for combinatorial iteration, and graphlib for DAG ordering.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: know mutation and comparator rules. Make this risk visible in tests and in code comments.
Common pitfall: Relying on a library without reading its ordering, mutation, or thread-safety contract can silently invalidate an algorithm.
# Page 041: Algorithmic Python: lists, tuples, dicts, and sets
EXAMPLE = {'page': 41, 'topic': 'Algorithmic Python: lists, tuples, dicts, and sets', 'chapter': 'Python and JavaScript Algorithm Tooling', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for Algorithmic Python: lists, tuples, dicts, and sets.', 'sample_input': {'notebook_cells': [{'cell_type': 'markdown', 'source': '# Lab'}, {'cell_type': 'code', 'source': 'run_example()'}], 'page_marker': '041-algorithmic_python_l'}, 'expected_output': 'Inspectable result for Algorithmic Python: lists, tuples, dicts, and sets', 'watch_for': 'The invariant that makes Algorithmic Python: lists, tuples, dicts, and sets safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': [], 'visual_gate_note': 'This is page 041; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'notebook_cells'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def algorithmic_python_lists_tuples_dicts_and_sets_p041(notebook_cells):
return [{'cell': i, 'kind': cell['cell_type'], 'has_source': bool(cell.get('source'))} for i, cell in enumerate(notebook_cells)]
def run_example(example=EXAMPLE):
return algorithmic_python_lists_tuples_dicts_and_sets_p041([{'cell_type':'markdown','source':'# Lab'}, {'cell_type':'code','source':'run_example()'}])
Manual review notes for students
What to inspect first
Track notebook_cells before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Algorithmic Python: lists, tuples, dicts, and sets, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['notebook_cells'], then compare it with the first line produced by Algorithmic Python: lists, tuples, dicts, and sets.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 041.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for algorithmic python: lists, tuples, dicts, and sets and explain what each one stresses.
Page 042 / 561Chapter 4: Python and JavaScript Algorithm Tooling
Using collections.deque for queues
Page-local deep read
Mental model for Using collections.deque for queues: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 042, the goal is not memorizing using collections.deque for queues; it is recognizing the representation, the safe transition, and the stopping condition inside the Python and JavaScript Algorithm Tooling chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Using collections.deque for queues is one small tool in the larger Python and JavaScript Algorithm Tooling toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Using collections.deque for queues before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Language libraries encode mature implementations of common algorithmic building blocks. Knowing their contracts prevents accidental O(n²) code and makes reference implementations shorter.
Use deque for FIFO queues, heapq for priority queues, bisect for insertion points in sorted lists, functools for memoization, itertools for combinatorial iteration, and graphlib for DAG ordering.
# Page 042: Using collections.deque for queues
EXAMPLE = {'page': 42, 'topic': 'Using collections.deque for queues', 'chapter': 'Python and JavaScript Algorithm Tooling', 'kind': 'deque', 'scenario': 'Run a concrete deque miniature for Using collections.deque for queues.', 'sample_input': {'events': ['first', 'second', 'third'], 'page_marker': '042-using_collections_de'}, 'expected_output': 'Inspectable result for Using collections.deque for queues', 'watch_for': 'The invariant that makes Using collections.deque for queues safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the deque example changes first.', 'docs': [['Python collections deque/Counter', 'https://docs.python.org/3/library/collections.html']], 'visual_gate_note': 'This is page 042; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'events'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
from collections import deque
def using_collections_deque_for_queues_p042(events):
q = deque(events)
served = []
while q:
served.append(q.popleft())
return served
def run_example(example=EXAMPLE):
return using_collections_deque_for_queues_p042(['first','second','third'])
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Using collections.deque for queues, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 042 curation harness: Using collections.deque for queues
EXAMPLE_KIND = "deque"
EXAMPLE_TITLE = "Using collections.deque for queues"
SAMPLE = {
"events": [
"first",
"second",
"third"
],
"page_marker": "042-using_collections_de"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "events",
"marker": sample.get("page_marker", "042-using_collections_de"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "events": []} if "events" in sample else dict(sample)),
("single-step", {**sample, "events": sample.get("events", [])[:1]} if isinstance(sample.get("events"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "042-using_collections_de"))
Browser JavaScript companion
// Page 042 browser-side experiment: Using collections.deque for queues
const pageExample42 = {"events":["first","second","third"],"page_marker":"042-using_collections_de"};
function summarizePage42(sample = pageExample42) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Using collections.deque for queues",
kind: "deque",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage42());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['events'], then compare it with the first line produced by Using collections.deque for queues.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the deque invariant described in the code comments and return a stable, inspectable result for page 042.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for using collections.deque for queues, then point to the line of code that preserves it.
Page 043 / 561Chapter 4: Python and JavaScript Algorithm Tooling
Using heapq for priority queues
Page-local deep read
Mental model for Using heapq for priority queues: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 043, the goal is not memorizing using heapq for priority queues; it is recognizing the representation, the safe transition, and the stopping condition inside the Python and JavaScript Algorithm Tooling chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Using heapq for priority queues is one small tool in the larger Python and JavaScript Algorithm Tooling toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Using heapq for priority queues before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Language libraries encode mature implementations of common algorithmic building blocks. Knowing their contracts prevents accidental O(n²) code and makes reference implementations shorter.
Use deque for FIFO queues, heapq for priority queues, bisect for insertion points in sorted lists, functools for memoization, itertools for combinatorial iteration, and graphlib for DAG ordering.
# Page 043: Using heapq for priority queues
EXAMPLE = {'page': 43, 'topic': 'Using heapq for priority queues', 'chapter': 'Python and JavaScript Algorithm Tooling', 'kind': 'heap', 'scenario': 'Run a concrete heap miniature for Using heapq for priority queues.', 'sample_input': {'tasks': [[3, 'write tests'], [1, 'fix bug'], [2, 'refactor']], 'page_marker': '043-using_heapq_for_prio'}, 'expected_output': 'Inspectable result for Using heapq for priority queues', 'watch_for': 'The invariant that makes Using heapq for priority queues safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the heap example changes first.', 'docs': [['Python heapq priority queues', 'https://docs.python.org/3/library/heapq.html']], 'visual_gate_note': 'This is page 043; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'tasks'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
import heapq
def using_heapq_for_priority_queues_p043(tasks):
heap = []
for priority, task in tasks:
heapq.heappush(heap, (priority, task))
return [heapq.heappop(heap)[1] for _ in range(len(heap))]
def run_example(example=EXAMPLE):
return using_heapq_for_priority_queues_p043([(3,'write tests'), (1,'fix bug'), (2,'refactor')])
Do not memorize the label "Using heapq for priority queues" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Using heapq for priority queues, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 043 curation harness: Using heapq for priority queues
EXAMPLE_KIND = "heap"
EXAMPLE_TITLE = "Using heapq for priority queues"
SAMPLE = {
"tasks": [
[
3,
"write tests"
],
[
1,
"fix bug"
],
[
2,
"refactor"
]
],
"page_marker": "043-using_heapq_for_prio"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "tasks",
"marker": sample.get("page_marker", "043-using_heapq_for_prio"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "tasks": []} if "tasks" in sample else dict(sample)),
("single-step", {**sample, "tasks": sample.get("tasks", [])[:1]} if isinstance(sample.get("tasks"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "043-using_heapq_for_prio"))
Browser JavaScript companion
// Page 043 browser-side experiment: Using heapq for priority queues
const pageExample43 = {"tasks":[[3,"write tests"],[1,"fix bug"],[2,"refactor"]],"page_marker":"043-using_heapq_for_prio"};
function summarizePage43(sample = pageExample43) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Using heapq for priority queues",
kind: "heap",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage43());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['tasks'], then compare it with the first line produced by Using heapq for priority queues.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 043.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 044 / 561Chapter 4: Python and JavaScript Algorithm Tooling
Using bisect for sorted insertion points
Page-local deep read
Mental model for Using bisect for sorted insertion points: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 044, the goal is not memorizing using bisect for sorted insertion points; it is recognizing the representation, the safe transition, and the stopping condition inside the Python and JavaScript Algorithm Tooling chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Using bisect for sorted insertion points is one small tool in the larger Python and JavaScript Algorithm Tooling toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Using bisect for sorted insertion points before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Language libraries encode mature implementations of common algorithmic building blocks. Knowing their contracts prevents accidental O(n²) code and makes reference implementations shorter.
Use deque for FIFO queues, heapq for priority queues, bisect for insertion points in sorted lists, functools for memoization, itertools for combinatorial iteration, and graphlib for DAG ordering.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: know mutation and comparator rules. Make this risk visible in tests and in code comments.
Common pitfall: Relying on a library without reading its ordering, mutation, or thread-safety contract can silently invalidate an algorithm.
# Page 044: Using bisect for sorted insertion points
EXAMPLE = {'page': 44, 'topic': 'Using bisect for sorted insertion points', 'chapter': 'Python and JavaScript Algorithm Tooling', 'kind': 'bisect_bounds', 'scenario': 'Run a concrete bisect bounds miniature for Using bisect for sorted insertion points.', 'sample_input': {'values': [1, 4, 9], 'inserts': [3, 9, 0], 'page_marker': '044-using_bisect_for_sor'}, 'expected_output': 'Inspectable result for Using bisect for sorted insertion points', 'watch_for': 'The invariant that makes Using bisect for sorted insertion points safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the bisect bounds example changes first.', 'docs': [['Python bisect sorted insertion/search', 'https://docs.python.org/3/library/bisect.html']], 'visual_gate_note': 'This is page 044; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'values'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
from bisect import bisect_left, insort
def using_bisect_for_sorted_insertion_points_p044(values, inserts):
values = sorted(values); trace = []
for item in inserts:
pos = bisect_left(values, item)
insort(values, item)
trace.append({'inserted': item, 'position': pos, 'values': values.copy()})
return trace
def run_example(example=EXAMPLE):
return using_bisect_for_sorted_insertion_points_p044([1,4,9], [3,9,0])
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Using bisect for sorted insertion points, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 044 curation harness: Using bisect for sorted insertion points
EXAMPLE_KIND = "bisect_bounds"
EXAMPLE_TITLE = "Using bisect for sorted insertion points"
SAMPLE = {
"values": [
1,
4,
9
],
"inserts": [
3,
9,
0
],
"page_marker": "044-using_bisect_for_sor"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "044-using_bisect_for_sor"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "044-using_bisect_for_sor"))
Browser JavaScript companion
// Page 044 browser-side experiment: Using bisect for sorted insertion points
const pageExample44 = {"values":[1,4,9],"inserts":[3,9,0],"page_marker":"044-using_bisect_for_sor"};
function summarizePage44(sample = pageExample44) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Using bisect for sorted insertion points",
kind: "bisect_bounds",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage44());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Using bisect for sorted insertion points.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the bisect bounds invariant described in the code comments and return a stable, inspectable result for page 044.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 045 / 561Chapter 4: Python and JavaScript Algorithm Tooling
Using functools.cache for memoized DP
Page-local deep read
Mental model for Using functools.cache for memoized DP: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 045, the goal is not memorizing using functools.cache for memoized dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Python and JavaScript Algorithm Tooling chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Using functools.cache for memoized DP is one small tool in the larger Python and JavaScript Algorithm Tooling toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Using functools.cache for memoized DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Language libraries encode mature implementations of common algorithmic building blocks. Knowing their contracts prevents accidental O(n²) code and makes reference implementations shorter.
Use deque for FIFO queues, heapq for priority queues, bisect for insertion points in sorted lists, functools for memoization, itertools for combinatorial iteration, and graphlib for DAG ordering.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Relying on a library without reading its ordering, mutation, or thread-safety contract can silently invalidate an algorithm.
# Page 045: Using functools.cache for memoized DP
EXAMPLE = {'page': 45, 'topic': 'Using functools.cache for memoized DP', 'chapter': 'Python and JavaScript Algorithm Tooling', 'kind': 'dp', 'scenario': 'Run a concrete dp miniature for Using functools.cache for memoized DP.', 'sample_input': {'n': 10, 'page_marker': '045-using_functools_cach'}, 'expected_output': 'Inspectable result for Using functools.cache for memoized DP', 'watch_for': 'The invariant that makes Using functools.cache for memoized DP safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dp example changes first.', 'docs': [['Python functools.cache/lru_cache', 'https://docs.python.org/3/library/functools.html']], 'visual_gate_note': 'This is page 045; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'n'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
from functools import cache
def using_functools_cache_for_memoized_dp_p045(n):
calls = {'count': 0}
@cache
def fib(k):
calls['count'] += 1
return k if k < 2 else fib(k-1) + fib(k-2)
return {'fib': fib(n), 'distinct_states_evaluated': calls['count']}
def run_example(example=EXAMPLE):
return using_functools_cache_for_memoized_dp_p045(10)
Do not memorize the label "Using functools.cache for memoized DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 045 curation harness: Using functools.cache for memoized DP
EXAMPLE_KIND = "dp"
EXAMPLE_TITLE = "Using functools.cache for memoized DP"
SAMPLE = {
"n": 10,
"page_marker": "045-using_functools_cach"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "045-using_functools_cach"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "045-using_functools_cach"))
Browser JavaScript companion
// Page 045 browser-side experiment: Using functools.cache for memoized DP
const pageExample45 = {"n":10,"page_marker":"045-using_functools_cach"};
function summarizePage45(sample = pageExample45) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Using functools.cache for memoized DP",
kind: "dp",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage45());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Using functools.cache for memoized DP.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dp invariant described in the code comments and return a stable, inspectable result for page 045.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement using functools.cache for memoized dp twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 046 / 561Chapter 4: Python and JavaScript Algorithm Tooling
Using itertools for search spaces
Page-local deep read
Mental model for Using itertools for search spaces: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 046, the goal is not memorizing using itertools for search spaces; it is recognizing the representation, the safe transition, and the stopping condition inside the Python and JavaScript Algorithm Tooling chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Using itertools for search spaces is one small tool in the larger Python and JavaScript Algorithm Tooling toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Using itertools for search spaces before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Language libraries encode mature implementations of common algorithmic building blocks. Knowing their contracts prevents accidental O(n²) code and makes reference implementations shorter.
Use deque for FIFO queues, heapq for priority queues, bisect for insertion points in sorted lists, functools for memoization, itertools for combinatorial iteration, and graphlib for DAG ordering.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: know mutation and comparator rules. Make this risk visible in tests and in code comments.
Common pitfall: Relying on a library without reading its ordering, mutation, or thread-safety contract can silently invalidate an algorithm.
# Page 046: Using itertools for search spaces
EXAMPLE = {'page': 46, 'topic': 'Using itertools for search spaces', 'chapter': 'Python and JavaScript Algorithm Tooling', 'kind': 'permutations', 'scenario': 'Run a concrete permutations miniature for Using itertools for search spaces.', 'sample_input': {'items': ['A', 'B', 'C', 'D'], 'r': 2, 'page_marker': '046-using_itertools_for_'}, 'expected_output': 'Inspectable result for Using itertools for search spaces', 'watch_for': 'The invariant that makes Using itertools for search spaces safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the permutations example changes first.', 'docs': [['Python itertools combinatorics', 'https://docs.python.org/3/library/itertools.html']], 'visual_gate_note': 'This is page 046; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'items'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
from itertools import combinations
def using_itertools_for_search_spaces_p046(items, r):
return list(combinations(items, r))
def run_example(example=EXAMPLE):
return using_itertools_for_search_spaces_p046(['A','B','C','D'], 2)
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Using itertools for search spaces, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 046 curation harness: Using itertools for search spaces
EXAMPLE_KIND = "permutations"
EXAMPLE_TITLE = "Using itertools for search spaces"
SAMPLE = {
"items": [
"A",
"B",
"C",
"D"
],
"r": 2,
"page_marker": "046-using_itertools_for_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "items",
"marker": sample.get("page_marker", "046-using_itertools_for_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "items": []} if "items" in sample else dict(sample)),
("single-step", {**sample, "items": sample.get("items", [])[:1]} if isinstance(sample.get("items"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "046-using_itertools_for_"))
Browser JavaScript companion
// Page 046 browser-side experiment: Using itertools for search spaces
const pageExample46 = {"items":["A","B","C","D"],"r":2,"page_marker":"046-using_itertools_for_"};
function summarizePage46(sample = pageExample46) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Using itertools for search spaces",
kind: "permutations",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage46());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Using itertools for search spaces.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the permutations invariant described in the code comments and return a stable, inspectable result for page 046.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for using itertools for search spaces and explain what each one stresses.
Page 047 / 561Chapter 4: Python and JavaScript Algorithm Tooling
Using graphlib for topological sorting
Page-local deep read
Mental model for Using graphlib for topological sorting: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 047, the goal is not memorizing using graphlib for topological sorting; it is recognizing the representation, the safe transition, and the stopping condition inside the Python and JavaScript Algorithm Tooling chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Using graphlib for topological sorting is one small tool in the larger Python and JavaScript Algorithm Tooling toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Using graphlib for topological sorting before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Language libraries encode mature implementations of common algorithmic building blocks. Knowing their contracts prevents accidental O(n²) code and makes reference implementations shorter.
Use deque for FIFO queues, heapq for priority queues, bisect for insertion points in sorted lists, functools for memoization, itertools for combinatorial iteration, and graphlib for DAG ordering.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: Relying on a library without reading its ordering, mutation, or thread-safety contract can silently invalidate an algorithm.
# Page 047: Using graphlib for topological sorting
EXAMPLE = {'page': 47, 'topic': 'Using graphlib for topological sorting', 'chapter': 'Python and JavaScript Algorithm Tooling', 'kind': 'toposort', 'scenario': 'Run a concrete toposort miniature for Using graphlib for topological sorting.', 'sample_input': {'dependencies': {'cook': ['shop'], 'eat': ['cook'], 'clean': ['eat'], 'shop': []}, 'page_marker': '047-using_graphlib_for_t'}, 'expected_output': 'Inspectable result for Using graphlib for topological sorting', 'watch_for': 'The invariant that makes Using graphlib for topological sorting safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the toposort example changes first.', 'docs': [['Python graphlib.TopologicalSorter', 'https://docs.python.org/3/library/graphlib.html']], 'visual_gate_note': 'This is page 047; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'dependencies'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
from graphlib import TopologicalSorter
def using_graphlib_for_topological_sorting_p047(dependencies):
return list(TopologicalSorter(dependencies).static_order())
def run_example(example=EXAMPLE):
return using_graphlib_for_topological_sorting_p047({'cook':['shop'], 'eat':['cook'], 'clean':['eat'], 'shop':[]})
Do not memorize the label "Using graphlib for topological sorting" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 047 curation harness: Using graphlib for topological sorting
EXAMPLE_KIND = "toposort"
EXAMPLE_TITLE = "Using graphlib for topological sorting"
SAMPLE = {
"dependencies": {
"cook": [
"shop"
],
"eat": [
"cook"
],
"clean": [
"eat"
],
"shop": []
},
"page_marker": "047-using_graphlib_for_t"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "dependencies",
"marker": sample.get("page_marker", "047-using_graphlib_for_t"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "dependencies": []} if "dependencies" in sample else dict(sample)),
("single-step", {**sample, "dependencies": sample.get("dependencies", [])[:1]} if isinstance(sample.get("dependencies"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "047-using_graphlib_for_t"))
Browser JavaScript companion
// Page 047 browser-side experiment: Using graphlib for topological sorting
const pageExample47 = {"dependencies":{"cook":["shop"],"eat":["cook"],"clean":["eat"],"shop":[]},"page_marker":"047-using_graphlib_for_t"};
function summarizePage47(sample = pageExample47) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Using graphlib for topological sorting",
kind: "toposort",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage47());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['dependencies'], then compare it with the first line produced by Using graphlib for topological sorting.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the toposort invariant described in the code comments and return a stable, inspectable result for page 047.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for using graphlib for topological sorting, then point to the line of code that preserves it.
Page 048 / 561Chapter 4: Python and JavaScript Algorithm Tooling
JavaScript arrays and comparator pitfalls
Page-local deep read
Mental model for JavaScript arrays and comparator pitfalls: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 048, the goal is not memorizing javascript arrays and comparator pitfalls; it is recognizing the representation, the safe transition, and the stopping condition inside the Python and JavaScript Algorithm Tooling chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: JavaScript arrays and comparator pitfalls is one small tool in the larger Python and JavaScript Algorithm Tooling toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for JavaScript arrays and comparator pitfalls before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Language libraries encode mature implementations of common algorithmic building blocks. Knowing their contracts prevents accidental O(n²) code and makes reference implementations shorter.
Use deque for FIFO queues, heapq for priority queues, bisect for insertion points in sorted lists, functools for memoization, itertools for combinatorial iteration, and graphlib for DAG ordering.
Look for JavaScript arrays and comparator pitfalls whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: know mutation and comparator rules. Make this risk visible in tests and in code comments.
Common pitfall: Relying on a library without reading its ordering, mutation, or thread-safety contract can silently invalidate an algorithm.
Do not memorize the label "JavaScript arrays and comparator pitfalls" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 048 curation harness: JavaScript arrays and comparator pitfalls
EXAMPLE_KIND = "sort_pattern"
EXAMPLE_TITLE = "JavaScript arrays and comparator pitfalls"
SAMPLE = {
"values": [
10,
2,
1
],
"records": [
{
"name": "A",
"score": 2
},
{
"name": "B",
"score": 1
},
{
"name": "C",
"score": 2
}
],
"page_marker": "048-javascript_arrays_an"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "048-javascript_arrays_an"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "048-javascript_arrays_an"))
Browser JavaScript companion
// Page 048 browser-side experiment: JavaScript arrays and comparator pitfalls
const pageExample48 = {"values":[10,2,1],"records":[{"name":"A","score":2},{"name":"B","score":1},{"name":"C","score":2}],"page_marker":"048-javascript_arrays_an"};
function summarizePage48(sample = pageExample48) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "JavaScript arrays and comparator pitfalls",
kind: "sort_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage48());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by JavaScript arrays and comparator pitfalls.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 048.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 049 / 561Chapter 4: Python and JavaScript Algorithm Tooling
Canvas-based visualizations in the browser
Page-local deep read
Mental model for Canvas-based visualizations in the browser: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 049, the goal is not memorizing canvas-based visualizations in the browser; it is recognizing the representation, the safe transition, and the stopping condition inside the Python and JavaScript Algorithm Tooling chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Canvas-based visualizations in the browser is one small tool in the larger Python and JavaScript Algorithm Tooling toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Canvas-based visualizations in the browser before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Language libraries encode mature implementations of common algorithmic building blocks. Knowing their contracts prevents accidental O(n²) code and makes reference implementations shorter.
Use deque for FIFO queues, heapq for priority queues, bisect for insertion points in sorted lists, functools for memoization, itertools for combinatorial iteration, and graphlib for DAG ordering.
// Page 049: Canvas-based visualizations in the browser
const EXAMPLE = {
"page": 49,
"topic": "Canvas-based visualizations in the browser",
"chapter": "Python and JavaScript Algorithm Tooling",
"kind": "canvas_js",
"scenario": "Run a concrete canvas js miniature for Canvas-based visualizations in the browser.",
"sample_input": {
"values": [
5,
9,
4,
12,
8
],
"page_marker": "049-canvas_based_visuali"
},
"expected_output": "Inspectable result for Canvas-based visualizations in the browser",
"watch_for": "The invariant that makes Canvas-based visualizations in the browser safe is checked before the next transition.",
"try_next": "Change the sample input and predict which line in the canvas js example changes first.",
"docs": [
[
"MDN Canvas API",
"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API"
]
],
"visual_gate_note": "This is page 049; neighboring pages intentionally use different samples and outputs.",
"first_sample_key": "values"
};
function drawStateBars(ctx, values) {
const max = Math.max(...values, 1);
values.forEach((value, i) => {
const h = value / max * 120;
ctx.fillRect(10 + i * 28, 140 - h, 20, h);
});
}
console.log('Canvas lab data points:', EXAMPLE.sample_input.values.length);
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Canvas-based visualizations in the browser, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 049 curation harness: Canvas-based visualizations in the browser
EXAMPLE_KIND = "canvas_js"
EXAMPLE_TITLE = "Canvas-based visualizations in the browser"
SAMPLE = {
"values": [
5,
9,
4,
12,
8
],
"page_marker": "049-canvas_based_visuali"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "049-canvas_based_visuali"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "049-canvas_based_visuali"))
Browser JavaScript companion
// Page 049 browser-side experiment: Canvas-based visualizations in the browser
const pageExample49 = {"values":[5,9,4,12,8],"page_marker":"049-canvas_based_visuali"};
function summarizePage49(sample = pageExample49) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Canvas-based visualizations in the browser",
kind: "canvas_js",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage49());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Canvas-based visualizations in the browser.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the canvas js invariant described in the code comments and return a stable, inspectable result for page 049.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 050 / 561Chapter 4: Python and JavaScript Algorithm Tooling
Notebook labs and reproducibility
Page-local deep read
Mental model for Notebook labs and reproducibility: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 050, the goal is not memorizing notebook labs and reproducibility; it is recognizing the representation, the safe transition, and the stopping condition inside the Python and JavaScript Algorithm Tooling chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Notebook labs and reproducibility is one small tool in the larger Python and JavaScript Algorithm Tooling toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Notebook labs and reproducibility before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Language libraries encode mature implementations of common algorithmic building blocks. Knowing their contracts prevents accidental O(n²) code and makes reference implementations shorter.
Use deque for FIFO queues, heapq for priority queues, bisect for insertion points in sorted lists, functools for memoization, itertools for combinatorial iteration, and graphlib for DAG ordering.
# Page 050: Notebook labs and reproducibility
EXAMPLE = {'page': 50, 'topic': 'Notebook labs and reproducibility', 'chapter': 'Python and JavaScript Algorithm Tooling', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Notebook labs and reproducibility.', 'sample_input': {'notebook_cells': [{'cell_type': 'markdown', 'source': '# Lab'}, {'cell_type': 'code', 'source': 'run_example()'}], 'page_marker': '050-notebook_labs_and_re'}, 'expected_output': 'Inspectable result for Notebook labs and reproducibility', 'watch_for': 'The invariant that makes Notebook labs and reproducibility safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': [['Jupyter nbformat schema', 'https://nbformat.readthedocs.io/en/latest/format_description.html']], 'visual_gate_note': 'This is page 050; neighboring pages intentionally use different samples and outputs.', 'first_sample_key': 'notebook_cells'}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input']))
EDGE_CASES = ['empty input', 'single element', 'duplicates or repeated states', 'largest reasonable boundary']
def notebook_labs_and_reproducibility_p050(notebook_cells):
return [{'cell': i, 'kind': cell['cell_type'], 'has_source': bool(cell.get('source'))} for i, cell in enumerate(notebook_cells)]
def run_example(example=EXAMPLE):
return notebook_labs_and_reproducibility_p050([{'cell_type':'markdown','source':'# Lab'}, {'cell_type':'code','source':'run_example()'}])
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Notebook labs and reproducibility, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 050 curation harness: Notebook labs and reproducibility
EXAMPLE_KIND = "project"
EXAMPLE_TITLE = "Notebook labs and reproducibility"
SAMPLE = {
"notebook_cells": [
{
"cell_type": "markdown",
"source": "# Lab"
},
{
"cell_type": "code",
"source": "run_example()"
}
],
"page_marker": "050-notebook_labs_and_re"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "notebook_cells",
"marker": sample.get("page_marker", "050-notebook_labs_and_re"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "notebook_cells": []} if "notebook_cells" in sample else dict(sample)),
("single-step", {**sample, "notebook_cells": sample.get("notebook_cells", [])[:1]} if isinstance(sample.get("notebook_cells"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "050-notebook_labs_and_re"))
Browser JavaScript companion
// Page 050 browser-side experiment: Notebook labs and reproducibility
const pageExample50 = {"notebook_cells":[{"cell_type":"markdown","source":"# Lab"},{"cell_type":"code","source":"run_example()"}],"page_marker":"050-notebook_labs_and_re"};
function summarizePage50(sample = pageExample50) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Notebook labs and reproducibility",
kind: "project",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage50());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['notebook_cells'], then compare it with the first line produced by Notebook labs and reproducibility.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 050.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement notebook labs and reproducibility twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 051 / 561Chapter 5: Arrays, Strings, and Memory
Static arrays and memory locality
Page-local deep read
Mental model for Static arrays and memory locality: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 051, the goal is not memorizing static arrays and memory locality; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Static arrays and memory locality is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Static arrays and memory locality before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 5: Arrays, Strings, and Memory
class PrefixSums {
constructor(values) { this.pref = [0]; for (const x of values) this.pref.push(this.pref.at(-1) + x); }
rangeSum(left, right) { return this.pref[right + 1] - this.pref[left]; }
}
const ps = new PrefixSums([3, 1, 4, 1, 5]);
console.log(ps.rangeSum(1, 3));
Chapter anchor: This page is the Chapter 05 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Arrays, Strings, and Memory.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: off-by-one and resizing. Make this risk visible in tests and in code comments.
Common pitfall: A logically simple operation such as insertion at the front of an array can be linear because many elements must move.
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Static arrays and memory locality.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the array pattern invariant described in the code comments and return a stable, inspectable result for page 051.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for static arrays and memory locality and explain what each one stresses.
Page 052 / 561Chapter 5: Arrays, Strings, and Memory
Dynamic arrays and amortized append
Page-local deep read
Mental model for Dynamic arrays and amortized append: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 052, the goal is not memorizing dynamic arrays and amortized append; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Dynamic arrays and amortized append is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Dynamic arrays and amortized append before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 052: Dynamic arrays and amortized append
EXAMPLE = {'page': 52, 'topic': 'Dynamic arrays and amortized append', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'dynamic_array', 'scenario': 'Run a concrete dynamic array miniature for Dynamic arrays and amortized append.', 'sample_input': {'values': [5, 16, 27, 38, 9, 20, 31], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Dynamic arrays and amortized append', 'watch_for': 'The invariant that makes Dynamic arrays and amortized append safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dynamic array example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='052-dynamic_arrays_and-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def dynamic_arrays_and_amortized_append_p052(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return dynamic_arrays_and_amortized_append_p052(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 052 curation harness: Dynamic arrays and amortized append
EXAMPLE_KIND = "dynamic_array"
EXAMPLE_TITLE = "Dynamic arrays and amortized append"
SAMPLE = {
"values": [
5,
16,
27,
38,
9,
20,
31
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "052-dynamic_arrays_and_a"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "052-dynamic_arrays_and_a"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "052-dynamic_arrays_and_a"))
Browser JavaScript companion
// Page 052 browser-side experiment: Dynamic arrays and amortized append
const pageExample52 = {"values":[5,16,27,38,9,20,31],"steps":["read","update","verify"],"page_marker":"052-dynamic_arrays_and_a"};
function summarizePage52(sample = pageExample52) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Dynamic arrays and amortized append",
kind: "dynamic_array",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage52());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Dynamic arrays and amortized append.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dynamic array invariant described in the code comments and return a stable, inspectable result for page 052.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for dynamic arrays and amortized append, then point to the line of code that preserves it.
Page 053 / 561Chapter 5: Arrays, Strings, and Memory
Index arithmetic and sentinels
Page-local deep read
Mental model for Index arithmetic and sentinels: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 053, the goal is not memorizing index arithmetic and sentinels; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Index arithmetic and sentinels is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Index arithmetic and sentinels before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 053: Index arithmetic and sentinels
EXAMPLE = {'page': 53, 'topic': 'Index arithmetic and sentinels', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'sentinel_scan', 'scenario': 'Run a concrete sentinel scan miniature for Index arithmetic and sentinels.', 'sample_input': {'values': [12, 23, 34, 5, 16, 27, 38], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Index arithmetic and sentinels', 'watch_for': 'The invariant that makes Index arithmetic and sentinels safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sentinel scan example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='053-index_arithmetic_a-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def index_arithmetic_and_sentinels_p053(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return index_arithmetic_and_sentinels_p053(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Index arithmetic and sentinels, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 053 curation harness: Index arithmetic and sentinels
EXAMPLE_KIND = "sentinel_scan"
EXAMPLE_TITLE = "Index arithmetic and sentinels"
SAMPLE = {
"values": [
12,
23,
34,
5,
16,
27,
38
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "053-index_arithmetic_and"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "053-index_arithmetic_and"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "053-index_arithmetic_and"))
Browser JavaScript companion
// Page 053 browser-side experiment: Index arithmetic and sentinels
const pageExample53 = {"values":[12,23,34,5,16,27,38],"steps":["read","update","verify"],"page_marker":"053-index_arithmetic_and"};
function summarizePage53(sample = pageExample53) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Index arithmetic and sentinels",
kind: "sentinel_scan",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage53());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Index arithmetic and sentinels.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sentinel scan invariant described in the code comments and return a stable, inspectable result for page 053.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 054 / 561Chapter 5: Arrays, Strings, and Memory
Prefix sums
Page-local deep read
Mental model for Prefix sums: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 054, the goal is not memorizing prefix sums; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Prefix sums is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Prefix sums before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: off-by-one and resizing. Make this risk visible in tests and in code comments.
Common pitfall: A logically simple operation such as insertion at the front of an array can be linear because many elements must move.
# Page 054: Prefix sums
EXAMPLE = {'page': 54, 'topic': 'Prefix sums', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'prefix_sum', 'scenario': 'Run a concrete prefix sum miniature for Prefix sums.', 'sample_input': {'values': [19, 30, 1, 12, 23, 34, 5], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Prefix sums', 'watch_for': 'The invariant that makes Prefix sums safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the prefix sum example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='054-prefix_sums-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def build_prefix(values):
prefix = [0]
for value in values:
prefix.append(prefix[-1] + value)
return prefix
def prefix_sums_p054(values, queries):
prefix = build_prefix(values)
return [prefix[right] - prefix[left] for left, right in queries]
def run_example(example=EXAMPLE):
values = example['sample_input']['values']
queries = [(0, min(3, len(values))), (1, min(5, len(values)))]
return prefix_sums_p054(values, queries)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Prefix sums, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Prefix sums.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the prefix sum invariant described in the code comments and return a stable, inspectable result for page 054.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 055 / 561Chapter 5: Arrays, Strings, and Memory
Difference arrays
Page-local deep read
Mental model for Difference arrays: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 055, the goal is not memorizing difference arrays; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Difference arrays is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Difference arrays before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: off-by-one and resizing. Make this risk visible in tests and in code comments.
Common pitfall: A logically simple operation such as insertion at the front of an array can be linear because many elements must move.
# Page 055: Difference arrays
EXAMPLE = {'page': 55, 'topic': 'Difference arrays', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'difference_array', 'scenario': 'Run a concrete difference array miniature for Difference arrays.', 'sample_input': {'values': [26, 37, 8, 19, 30, 1, 12], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Difference arrays', 'watch_for': 'The invariant that makes Difference arrays safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the difference array example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='055-difference_arrays-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def difference_arrays_p055(n, updates):
diff = [0] * (n + 1)
for left, right, delta in updates:
diff[left] += delta
if right < n: diff[right] -= delta
values, running = [], 0
for i in range(n):
running += diff[i]
values.append(running)
return values
def run_example(example=EXAMPLE):
return difference_arrays_p055(8, [(1,4,3), (3,7,2), (0,2,1)])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Difference arrays.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the difference array invariant described in the code comments and return a stable, inspectable result for page 055.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement difference arrays twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 056 / 561Chapter 5: Arrays, Strings, and Memory
Two pointers
Page-local deep read
Mental model for Two pointers: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 056, the goal is not memorizing two pointers; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Two pointers is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Two pointers before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: off-by-one and resizing. Make this risk visible in tests and in code comments.
Common pitfall: A logically simple operation such as insertion at the front of an array can be linear because many elements must move.
# Page 056: Two pointers
EXAMPLE = {'page': 56, 'topic': 'Two pointers', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'two_pointers', 'scenario': 'Run a concrete two pointers miniature for Two pointers.', 'sample_input': {'values': [33, 4, 15, 26, 37, 8, 19], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Two pointers', 'watch_for': 'The invariant that makes Two pointers safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the two pointers example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='056-two_pointers-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def two_pointers_p056(values, target):
left, right = 0, len(values) - 1
while left < right:
total = values[left] + values[right]
if total == target: return (left, right)
if total < target: left += 1
else: right -= 1
return None
def run_example(example=EXAMPLE):
values = sorted(example['sample_input']['values'])
return two_pointers_p056(values, values[1] + values[-2])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Two pointers, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Two pointers.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the two pointers invariant described in the code comments and return a stable, inspectable result for page 056.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for two pointers and explain what each one stresses.
Page 057 / 561Chapter 5: Arrays, Strings, and Memory
Sliding windows
Page-local deep read
Mental model for Sliding windows: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 057, the goal is not memorizing sliding windows; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sliding windows is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sliding windows before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: off-by-one and resizing. Make this risk visible in tests and in code comments.
Common pitfall: A logically simple operation such as insertion at the front of an array can be linear because many elements must move.
# Page 057: Sliding windows
EXAMPLE = {'page': 57, 'topic': 'Sliding windows', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'sliding_window', 'scenario': 'Run a concrete sliding window miniature for Sliding windows.', 'sample_input': {'values': [40, 11, 22, 33, 4, 15, 26], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Sliding windows', 'watch_for': 'The invariant that makes Sliding windows safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sliding window example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='057-sliding_windows-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def sliding_windows_p057(values, limit):
left = total = best = 0
for right, value in enumerate(values):
total += value
while total > limit and left <= right:
total -= values[left]; left += 1
best = max(best, right - left + 1)
return best
def run_example(example=EXAMPLE):
return sliding_windows_p057(example['sample_input']['values'], 45)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Sliding windows, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Sliding windows.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sliding window invariant described in the code comments and return a stable, inspectable result for page 057.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for sliding windows, then point to the line of code that preserves it.
Page 058 / 561Chapter 5: Arrays, Strings, and Memory
Partitioning arrays in place
Page-local deep read
Mental model for Partitioning arrays in place: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 058, the goal is not memorizing partitioning arrays in place; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Partitioning arrays in place is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Partitioning arrays in place before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Partitioning arrays in place whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: off-by-one and resizing. Make this risk visible in tests and in code comments.
Common pitfall: A logically simple operation such as insertion at the front of an array can be linear because many elements must move.
# Page 058: Partitioning arrays in place
EXAMPLE = {'page': 58, 'topic': 'Partitioning arrays in place', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'partition_array', 'scenario': 'Run a concrete partition array miniature for Partitioning arrays in place.', 'sample_input': {'values': [7, 18, 29, 40, 11, 22, 33], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Partitioning arrays in place', 'watch_for': 'The invariant that makes Partitioning arrays in place safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the partition array example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='058-partitioning_array-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def partitioning_arrays_in_place_p058(values, pivot):
smaller, equal, greater = [], [], []
for value in values:
if value < pivot: smaller.append(value)
elif value == pivot: equal.append(value)
else: greater.append(value)
return smaller + equal + greater
def run_example(example=EXAMPLE):
vals=example['sample_input']['values']; return partitioning_arrays_in_place_p058(vals, vals[len(vals)//2])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 058 curation harness: Partitioning arrays in place
EXAMPLE_KIND = "partition_array"
EXAMPLE_TITLE = "Partitioning arrays in place"
SAMPLE = {
"values": [
7,
18,
29,
40,
11,
22,
33
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "058-partitioning_arrays_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "058-partitioning_arrays_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "058-partitioning_arrays_"))
Browser JavaScript companion
// Page 058 browser-side experiment: Partitioning arrays in place
const pageExample58 = {"values":[7,18,29,40,11,22,33],"steps":["read","update","verify"],"page_marker":"058-partitioning_arrays_"};
function summarizePage58(sample = pageExample58) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Partitioning arrays in place",
kind: "partition_array",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage58());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Partitioning arrays in place.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the partition array invariant described in the code comments and return a stable, inspectable result for page 058.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 059 / 561Chapter 5: Arrays, Strings, and Memory
Stable versus unstable rearrangement
Page-local deep read
Mental model for Stable versus unstable rearrangement: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 059, the goal is not memorizing stable versus unstable rearrangement; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Stable versus unstable rearrangement is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Stable versus unstable rearrangement before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 059: Stable versus unstable rearrangement
EXAMPLE = {'page': 59, 'topic': 'Stable versus unstable rearrangement', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'array_pattern', 'scenario': 'Run a concrete array pattern miniature for Stable versus unstable rearrangement.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [14, 25, 36, 7, 18, 29, 40], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Stable versus unstable rearrangement', 'watch_for': 'The invariant that makes Stable versus unstable rearrangement safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the array pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='059-stable_versus_unst-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def build_prefix(values):
prefix = [0]
for value in values:
prefix.append(prefix[-1] + value)
return prefix
def stable_versus_unstable_rearrangement_p059(values, queries):
prefix = build_prefix(values)
return [prefix[right] - prefix[left] for left, right in queries]
def run_example(example=EXAMPLE):
values = example['sample_input']['values']
queries = [(0, min(3, len(values))), (1, min(5, len(values)))]
return stable_versus_unstable_rearrangement_p059(values, queries)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 059 curation harness: Stable versus unstable rearrangement
EXAMPLE_KIND = "array_pattern"
EXAMPLE_TITLE = "Stable versus unstable rearrangement"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"perform transition",
"check output"
],
"values": [
14,
25,
36,
7,
18,
29,
40
],
"sizes": [
4,
8,
16,
32
],
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "059-stable_versus_unstab"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "059-stable_versus_unstab"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "059-stable_versus_unstab"))
Browser JavaScript companion
// Page 059 browser-side experiment: Stable versus unstable rearrangement
const pageExample59 = {"steps":["read input","state invariant","perform transition","check output"],"values":[14,25,36,7,18,29,40],"sizes":[4,8,16,32],"requests":["A","B","A","C","D","A"],"page_marker":"059-stable_versus_unstab"};
function summarizePage59(sample = pageExample59) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Stable versus unstable rearrangement",
kind: "array_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage59());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Stable versus unstable rearrangement.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the array pattern invariant described in the code comments and return a stable, inspectable result for page 059.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 060 / 561Chapter 5: Arrays, Strings, and Memory
In-place reversal and rotation
Page-local deep read
Mental model for In-place reversal and rotation: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 060, the goal is not memorizing in-place reversal and rotation; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: In-place reversal and rotation is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for In-place reversal and rotation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 060: In-place reversal and rotation
EXAMPLE = {'page': 60, 'topic': 'In-place reversal and rotation', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'rotate_array', 'scenario': 'Run a concrete rotate array miniature for In-place reversal and rotation.', 'sample_input': {'values': [21, 32, 3, 14, 25, 36, 7], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for In-place reversal and rotation', 'watch_for': 'The invariant that makes In-place reversal and rotation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the rotate array example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='060-in_place_reversal_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def reverse(values, left, right):
while left < right:
values[left], values[right] = values[right], values[left]
left += 1; right -= 1
def in_place_reversal_and_rotation_p060(values, k):
values = list(values); n = len(values); k %= n or 1
reverse(values, 0, n-1); reverse(values, 0, k-1); reverse(values, k, n-1)
return values
def run_example(example=EXAMPLE):
return in_place_reversal_and_rotation_p060(example['sample_input']['values'], 3)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 060 curation harness: In-place reversal and rotation
EXAMPLE_KIND = "rotate_array"
EXAMPLE_TITLE = "In-place reversal and rotation"
SAMPLE = {
"values": [
21,
32,
3,
14,
25,
36,
7
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "060-in_place_reversal_an"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "060-in_place_reversal_an"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "060-in_place_reversal_an"))
Browser JavaScript companion
// Page 060 browser-side experiment: In-place reversal and rotation
const pageExample60 = {"values":[21,32,3,14,25,36,7],"steps":["read","update","verify"],"page_marker":"060-in_place_reversal_an"};
function summarizePage60(sample = pageExample60) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "In-place reversal and rotation",
kind: "rotate_array",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage60());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by In-place reversal and rotation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the rotate array invariant described in the code comments and return a stable, inspectable result for page 060.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement in-place reversal and rotation twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 061 / 561Chapter 5: Arrays, Strings, and Memory
Matrix storage orders
Page-local deep read
Mental model for Matrix storage orders: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 061, the goal is not memorizing matrix storage orders; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Matrix storage orders is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Matrix storage orders before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: off-by-one and resizing. Make this risk visible in tests and in code comments.
Common pitfall: A logically simple operation such as insertion at the front of an array can be linear because many elements must move.
# Page 061: Matrix storage orders
EXAMPLE = {'page': 61, 'topic': 'Matrix storage orders', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'array_pattern', 'scenario': 'Run a concrete array pattern miniature for Matrix storage orders.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [28, 39, 10, 21, 32, 3, 14], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Matrix storage orders', 'watch_for': 'The invariant that makes Matrix storage orders safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the array pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='061-matrix_storage_ord-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def build_prefix(values):
prefix = [0]
for value in values:
prefix.append(prefix[-1] + value)
return prefix
def matrix_storage_orders_p061(values, queries):
prefix = build_prefix(values)
return [prefix[right] - prefix[left] for left, right in queries]
def run_example(example=EXAMPLE):
values = example['sample_input']['values']
queries = [(0, min(3, len(values))), (1, min(5, len(values)))]
return matrix_storage_orders_p061(values, queries)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Matrix storage orders.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the array pattern invariant described in the code comments and return a stable, inspectable result for page 061.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for matrix storage orders and explain what each one stresses.
Page 062 / 561Chapter 5: Arrays, Strings, and Memory
Sparse arrays and coordinate lists
Page-local deep read
Mental model for Sparse arrays and coordinate lists: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 062, the goal is not memorizing sparse arrays and coordinate lists; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sparse arrays and coordinate lists is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sparse arrays and coordinate lists before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 062: Sparse arrays and coordinate lists
EXAMPLE = {'page': 62, 'topic': 'Sparse arrays and coordinate lists', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'sparse_coo', 'scenario': 'Run a concrete sparse coo miniature for Sparse arrays and coordinate lists.', 'sample_input': {'values': [35, 6, 17, 28, 39, 10, 21], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Sparse arrays and coordinate lists', 'watch_for': 'The invariant that makes Sparse arrays and coordinate lists safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sparse coo example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='062-sparse_arrays_and_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def sparse_arrays_and_coordinate_lists_p062(rows, cols, entries):
dense = [[0 for _ in range(cols)] for _ in range(rows)]
for r, c, value in entries:
dense[r][c] = value
return dense
def run_example(example=EXAMPLE):
return sparse_arrays_and_coordinate_lists_p062(3, 4, [(0,1,7), (2,3,5), (1,1,2)])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Sparse arrays and coordinate lists, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 062 curation harness: Sparse arrays and coordinate lists
EXAMPLE_KIND = "sparse_coo"
EXAMPLE_TITLE = "Sparse arrays and coordinate lists"
SAMPLE = {
"values": [
35,
6,
17,
28,
39,
10,
21
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "062-sparse_arrays_and_co"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "062-sparse_arrays_and_co"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "062-sparse_arrays_and_co"))
Browser JavaScript companion
// Page 062 browser-side experiment: Sparse arrays and coordinate lists
const pageExample62 = {"values":[35,6,17,28,39,10,21],"steps":["read","update","verify"],"page_marker":"062-sparse_arrays_and_co"};
function summarizePage62(sample = pageExample62) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Sparse arrays and coordinate lists",
kind: "sparse_coo",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage62());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Sparse arrays and coordinate lists.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sparse coo invariant described in the code comments and return a stable, inspectable result for page 062.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for sparse arrays and coordinate lists, then point to the line of code that preserves it.
Page 063 / 561Chapter 5: Arrays, Strings, and Memory
String representation and Unicode caution
Page-local deep read
Mental model for String representation and Unicode caution: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 063, the goal is not memorizing string representation and unicode caution; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: String representation and Unicode caution is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for String representation and Unicode caution before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 063: String representation and Unicode caution
EXAMPLE = {'page': 63, 'topic': 'String representation and Unicode caution', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'array_pattern', 'scenario': 'Run a concrete array pattern miniature for String representation and Unicode caution.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [2, 13, 24, 35, 6, 17, 28], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for String representation and Unicode caution', 'watch_for': 'The invariant that makes String representation and Unicode caution safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the array pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='063-string_representat-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def build_prefix(values):
prefix = [0]
for value in values:
prefix.append(prefix[-1] + value)
return prefix
def string_representation_and_unicode_caution_p063(values, queries):
prefix = build_prefix(values)
return [prefix[right] - prefix[left] for left, right in queries]
def run_example(example=EXAMPLE):
values = example['sample_input']['values']
queries = [(0, min(3, len(values))), (1, min(5, len(values)))]
return string_representation_and_unicode_caution_p063(values, queries)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by String representation and Unicode caution.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the array pattern invariant described in the code comments and return a stable, inspectable result for page 063.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 064 / 561Chapter 5: Arrays, Strings, and Memory
Character frequency tables
Page-local deep read
Mental model for Character frequency tables: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 064, the goal is not memorizing character frequency tables; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Character frequency tables is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Character frequency tables before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: off-by-one and resizing. Make this risk visible in tests and in code comments.
Common pitfall: A logically simple operation such as insertion at the front of an array can be linear because many elements must move.
# Page 064: Character frequency tables
EXAMPLE = {'page': 64, 'topic': 'Character frequency tables', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'counter', 'scenario': 'Run a concrete counter miniature for Character frequency tables.', 'sample_input': {'values': [9, 20, 31, 2, 13, 24, 35], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Character frequency tables', 'watch_for': 'The invariant that makes Character frequency tables safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the counter example changes first.', 'docs': [('Python collections deque/Counter', 'https://docs.python.org/3/library/collections.html')]}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='064-character_frequenc-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import Counter
def character_frequency_tables_p064(items):
counts = Counter(items)
total = sum(counts.values())
return {item: {'count': count, 'frequency': count/total} for item, count in counts.items()}
def run_example(example=EXAMPLE):
return character_frequency_tables_p064(example['sample_input']['items'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Character frequency tables, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 064 curation harness: Character frequency tables
EXAMPLE_KIND = "counter"
EXAMPLE_TITLE = "Character frequency tables"
SAMPLE = {
"values": [
9,
20,
31,
2,
13,
24,
35
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "064-character_frequency_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "064-character_frequency_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "064-character_frequency_"))
Browser JavaScript companion
// Page 064 browser-side experiment: Character frequency tables
const pageExample64 = {"values":[9,20,31,2,13,24,35],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"064-character_frequency_"};
function summarizePage64(sample = pageExample64) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Character frequency tables",
kind: "counter",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage64());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Character frequency tables.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the counter invariant described in the code comments and return a stable, inspectable result for page 064.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 065 / 561Chapter 5: Arrays, Strings, and Memory
Intervals on arrays
Page-local deep read
Mental model for Intervals on arrays: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 065, the goal is not memorizing intervals on arrays; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Intervals on arrays is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Intervals on arrays before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: off-by-one and resizing. Make this risk visible in tests and in code comments.
Common pitfall: A logically simple operation such as insertion at the front of an array can be linear because many elements must move.
# Page 065: Intervals on arrays
EXAMPLE = {'page': 65, 'topic': 'Intervals on arrays', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'merge_intervals', 'scenario': 'Run a concrete merge intervals miniature for Intervals on arrays.', 'sample_input': {'values': [16, 27, 38, 9, 20, 31, 2], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Intervals on arrays', 'watch_for': 'The invariant that makes Intervals on arrays safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the merge intervals example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='065-intervals_on_array-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def intervals_on_arrays_p065(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return intervals_on_arrays_p065(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Intervals on arrays, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 065 curation harness: Intervals on arrays
EXAMPLE_KIND = "merge_intervals"
EXAMPLE_TITLE = "Intervals on arrays"
SAMPLE = {
"values": [
16,
27,
38,
9,
20,
31,
2
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "065-intervals_on_arrays"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "065-intervals_on_arrays"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "065-intervals_on_arrays"))
Browser JavaScript companion
// Page 065 browser-side experiment: Intervals on arrays
const pageExample65 = {"values":[16,27,38,9,20,31,2],"steps":["read","update","verify"],"page_marker":"065-intervals_on_arrays"};
function summarizePage65(sample = pageExample65) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Intervals on arrays",
kind: "merge_intervals",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage65());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Intervals on arrays.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the merge intervals invariant described in the code comments and return a stable, inspectable result for page 065.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement intervals on arrays twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 066 / 561Chapter 5: Arrays, Strings, and Memory
Cache behavior in scans
Page-local deep read
Mental model for Cache behavior in scans: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 066, the goal is not memorizing cache behavior in scans; it is recognizing the representation, the safe transition, and the stopping condition inside the Arrays, Strings, and Memory chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Cache behavior in scans is one small tool in the larger Arrays, Strings, and Memory toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Cache behavior in scans before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: off-by-one and resizing. Make this risk visible in tests and in code comments.
Common pitfall: A logically simple operation such as insertion at the front of an array can be linear because many elements must move.
# Page 066: Cache behavior in scans
EXAMPLE = {'page': 66, 'topic': 'Cache behavior in scans', 'chapter': 'Arrays, Strings, and Memory', 'kind': 'chunked_scan', 'scenario': 'Run a concrete chunked scan miniature for Cache behavior in scans.', 'sample_input': {'values': [23, 34, 5, 16, 27, 38, 9], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Cache behavior in scans', 'watch_for': 'The invariant that makes Cache behavior in scans safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the chunked scan example changes first.', 'docs': [('Python functools.cache/lru_cache', 'https://docs.python.org/3/library/functools.html')]}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='066-cache_behavior_in_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cache_behavior_in_scans_p066(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return cache_behavior_in_scans_p066(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Cache behavior in scans, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 066 curation harness: Cache behavior in scans
EXAMPLE_KIND = "chunked_scan"
EXAMPLE_TITLE = "Cache behavior in scans"
SAMPLE = {
"values": [
23,
34,
5,
16,
27,
38,
9
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "066-cache_behavior_in_sc"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "066-cache_behavior_in_sc"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "066-cache_behavior_in_sc"))
Browser JavaScript companion
// Page 066 browser-side experiment: Cache behavior in scans
const pageExample66 = {"values":[23,34,5,16,27,38,9],"steps":["read","update","verify"],"page_marker":"066-cache_behavior_in_sc"};
function summarizePage66(sample = pageExample66) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Cache behavior in scans",
kind: "chunked_scan",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage66());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Cache behavior in scans.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the chunked scan invariant described in the code comments and return a stable, inspectable result for page 066.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for cache behavior in scans and explain what each one stresses.
Page 067 / 561Chapter 6: Search and Binary Search
Linear search as a baseline
Page-local deep read
Mental model for Linear search as a baseline: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 067, the goal is not memorizing linear search as a baseline; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Linear search as a baseline is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Linear search as a baseline before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
This is a chapter-level anchor example. Read it alongside the page-specific labs lower down.
def lower_bound(arr: list[int], target: int) -> int:
lo, hi = 0, len(arr)
while lo < hi:
mid = (lo + hi) // 2
if arr[mid] < target:
lo = mid + 1
else:
hi = mid
return lo
data = [2, 4, 4, 7, 9, 12]
for t in [0, 4, 5, 12, 20]:
idx = lower_bound(data, t)
print(t, idx)
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 6: Search and Binary Search
function lowerBound(arr, target) {
let lo = 0, hi = arr.length;
while (lo < hi) { const mid = Math.floor((lo + hi) / 2); if (arr[mid] < target) lo = mid + 1; else hi = mid; }
return lo;
}
console.log(lowerBound([2, 4, 4, 7, 9], 4));
Chapter anchor: This page is the Chapter 06 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Search and Binary Search.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: Mixing closed and half-open intervals in the same implementation is the fastest route to infinite loops.
# Page 067: Linear search as a baseline
EXAMPLE = {'page': 67, 'topic': 'Linear search as a baseline', 'chapter': 'Search and Binary Search', 'kind': 'linear_search', 'scenario': 'Run a concrete linear search miniature for Linear search as a baseline.', 'sample_input': {'values': [1, 5, 7, 12, 16, 23, 30, 34], 'target': 16, 'matrix': [[1, 3, 5], [7, 9, 11], [13, 15, 17]], 'capacity': 17}, 'expected_output': 'Inspectable result for Linear search as a baseline', 'watch_for': 'The invariant that makes Linear search as a baseline safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linear search example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='067-linear_search_as_a-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def linear_search_as_a_baseline_p067(values, target):
for index, value in enumerate(values):
if value == target:
return {'found': True, 'index': index, 'comparisons': index + 1}
return {'found': False, 'index': -1, 'comparisons': len(values)}
def run_example(example=EXAMPLE):
return linear_search_as_a_baseline_p067(example['sample_input']['values'], example['sample_input']['target'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, target, matrix, capacity before reading the answer.
Common trap
Do not memorize the label "Linear search as a baseline" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 067 curation harness: Linear search as a baseline
EXAMPLE_KIND = "linear_search"
EXAMPLE_TITLE = "Linear search as a baseline"
SAMPLE = {
"values": [
1,
5,
7,
12,
16,
23,
30,
34
],
"target": 16,
"matrix": [
[
1,
3,
5
],
[
7,
9,
11
],
[
13,
15,
17
]
],
"capacity": 17,
"page_marker": "067-linear_search_as_a_b"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "067-linear_search_as_a_b"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "067-linear_search_as_a_b"))
Browser JavaScript companion
// Page 067 browser-side experiment: Linear search as a baseline
const pageExample67 = {"values":[1,5,7,12,16,23,30,34],"target":16,"matrix":[[1,3,5],[7,9,11],[13,15,17]],"capacity":17,"page_marker":"067-linear_search_as_a_b"};
function summarizePage67(sample = pageExample67) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Linear search as a baseline",
kind: "linear_search",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage67());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Linear search as a baseline.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the linear search invariant described in the code comments and return a stable, inspectable result for page 067.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for linear search as a baseline, then point to the line of code that preserves it.
Page 068 / 561Chapter 6: Search and Binary Search
Binary search over sorted arrays
Page-local deep read
Mental model for Binary search over sorted arrays: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 068, the goal is not memorizing binary search over sorted arrays; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Binary search over sorted arrays is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Binary search over sorted arrays before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
Look for Binary search over sorted arrays whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: Mixing closed and half-open intervals in the same implementation is the fastest route to infinite loops.
Find the target by maintaining a half-open search interval.
Manual review notes for students
What to inspect first
Track values, target, matrix, capacity before reading the answer.
Common trap
Do not memorize the label "Binary search over sorted arrays" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 068 curation harness: Binary search over sorted arrays
EXAMPLE_KIND = "binary_search"
EXAMPLE_TITLE = "Binary search over sorted arrays"
SAMPLE = {
"values": [
1,
8,
12,
13,
19,
23,
30,
37
],
"target": 19,
"matrix": [
[
1,
3,
5
],
[
7,
9,
11
],
[
13,
15,
17
]
],
"capacity": 18,
"page_marker": "068-binary_search_over_s"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "068-binary_search_over_s"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "068-binary_search_over_s"))
Browser JavaScript companion
// Page 068 browser-side experiment: Binary search over sorted arrays
const pageExample68 = {"values":[1,8,12,13,19,23,30,37],"target":19,"matrix":[[1,3,5],[7,9,11],[13,15,17]],"capacity":18,"page_marker":"068-binary_search_over_s"};
function summarizePage68(sample = pageExample68) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Binary search over sorted arrays",
kind: "binary_search",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage68());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Binary search over sorted arrays.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the binary search invariant described in the code comments and return a stable, inspectable result for page 068.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 069 / 561Chapter 6: Search and Binary Search
Lower_bound and upper_bound patterns
Page-local deep read
Mental model for Lower_bound and upper_bound patterns: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 069, the goal is not memorizing lower_bound and upper_bound patterns; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Lower_bound and upper_bound patterns is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Lower_bound and upper_bound patterns before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
Track values, target, matrix, capacity before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Lower_bound and upper_bound patterns, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 069 curation harness: Lower_bound and upper_bound patterns
EXAMPLE_KIND = "bisect_bounds"
EXAMPLE_TITLE = "Lower_bound and upper_bound patterns"
SAMPLE = {
"values": [
4,
8,
9,
14,
15,
19,
26,
30,
37
],
"target": 15,
"matrix": [
[
1,
3,
5
],
[
7,
9,
11
],
[
13,
15,
17
]
],
"capacity": 19,
"page_marker": "069-lower_bound_and_uppe"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "069-lower_bound_and_uppe"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "069-lower_bound_and_uppe"))
Browser JavaScript companion
// Page 069 browser-side experiment: Lower_bound and upper_bound patterns
const pageExample69 = {"values":[4,8,9,14,15,19,26,30,37],"target":15,"matrix":[[1,3,5],[7,9,11],[13,15,17]],"capacity":19,"page_marker":"069-lower_bound_and_uppe"};
function summarizePage69(sample = pageExample69) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Lower_bound and upper_bound patterns",
kind: "bisect_bounds",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage69());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Lower_bound and upper_bound patterns.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the bisect bounds invariant described in the code comments and return a stable, inspectable result for page 069.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 070 / 561Chapter 6: Search and Binary Search
Binary search on answer
Page-local deep read
Mental model for Binary search on answer: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 070, the goal is not memorizing binary search on answer; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Binary search on answer is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Binary search on answer before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
# Page 070: Binary search on answer
EXAMPLE = {'page': 70, 'topic': 'Binary search on answer', 'chapter': 'Search and Binary Search', 'kind': 'answer_search', 'scenario': 'Run a concrete answer search miniature for Binary search on answer.', 'sample_input': {'values': [4, 10, 11, 15, 22, 26, 33, 37], 'target': 22, 'matrix': [[1, 3, 5], [7, 9, 11], [13, 15, 17]], 'capacity': 10}, 'expected_output': 'Inspectable result for Binary search on answer', 'watch_for': 'The invariant that makes Binary search on answer safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the answer search example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='070-binary_search_on_a-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def feasible(limit, jobs, workers):
used, load = 1, 0
for job in jobs:
if job > limit:
return False
if load + job <= limit:
load += job
else:
used += 1; load = job
return used <= workers
def binary_search_on_answer_p070(jobs, workers):
lo, hi = max(jobs), sum(jobs)
while lo < hi:
mid = (lo + hi) // 2
if feasible(mid, jobs, workers):
hi = mid
else:
lo = mid + 1
return lo
def run_example(example=EXAMPLE):
return binary_search_on_answer_p070([7, 2, 5, 10, 8], 2)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, target, matrix, capacity before reading the answer.
Common trap
Do not memorize the label "Binary search on answer" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 070 curation harness: Binary search on answer
EXAMPLE_KIND = "answer_search"
EXAMPLE_TITLE = "Binary search on answer"
SAMPLE = {
"values": [
4,
10,
11,
15,
22,
26,
33,
37
],
"target": 22,
"matrix": [
[
1,
3,
5
],
[
7,
9,
11
],
[
13,
15,
17
]
],
"capacity": 10,
"page_marker": "070-binary_search_on_ans"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "070-binary_search_on_ans"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "070-binary_search_on_ans"))
Browser JavaScript companion
// Page 070 browser-side experiment: Binary search on answer
const pageExample70 = {"values":[4,10,11,15,22,26,33,37],"target":22,"matrix":[[1,3,5],[7,9,11],[13,15,17]],"capacity":10,"page_marker":"070-binary_search_on_ans"};
function summarizePage70(sample = pageExample70) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Binary search on answer",
kind: "answer_search",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage70());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Binary search on answer.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the answer search invariant described in the code comments and return a stable, inspectable result for page 070.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement binary search on answer twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 071 / 561Chapter 6: Search and Binary Search
Ternary search on unimodal functions
Page-local deep read
Mental model for Ternary search on unimodal functions: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 071, the goal is not memorizing ternary search on unimodal functions; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Ternary search on unimodal functions is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Ternary search on unimodal functions before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: Mixing closed and half-open intervals in the same implementation is the fastest route to infinite loops.
# Page 071: Ternary search on unimodal functions
EXAMPLE = {'page': 71, 'topic': 'Ternary search on unimodal functions', 'chapter': 'Search and Binary Search', 'kind': 'ternary_search', 'scenario': 'Run a concrete ternary search miniature for Ternary search on unimodal functions.', 'sample_input': {'values': [4, 11, 16, 18, 22, 29, 33, 40], 'target': 22, 'matrix': [[1, 3, 5], [7, 9, 11], [13, 15, 17]], 'capacity': 11}, 'expected_output': 'Inspectable result for Ternary search on unimodal functions', 'watch_for': 'The invariant that makes Ternary search on unimodal functions safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the ternary search example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='071-ternary_search_on_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def score(x):
return -(x - 3) ** 2 + 10
def ternary_search_on_unimodal_functions_p071(lo=-10.0, hi=10.0, rounds=80):
for _ in range(rounds):
m1 = lo + (hi - lo) / 3
m2 = hi - (hi - lo) / 3
if score(m1) < score(m2):
lo = m1
else:
hi = m2
x = (lo + hi) / 2
return {'argmax': x, 'value': score(x)}
def run_example(example=EXAMPLE):
return ternary_search_on_unimodal_functions_p071()
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, target, matrix, capacity before reading the answer.
Common trap
Do not memorize the label "Ternary search on unimodal functions" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 071 curation harness: Ternary search on unimodal functions
EXAMPLE_KIND = "ternary_search"
EXAMPLE_TITLE = "Ternary search on unimodal functions"
SAMPLE = {
"values": [
4,
11,
16,
18,
22,
29,
33,
40
],
"target": 22,
"matrix": [
[
1,
3,
5
],
[
7,
9,
11
],
[
13,
15,
17
]
],
"capacity": 11,
"page_marker": "071-ternary_search_on_un"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "071-ternary_search_on_un"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "071-ternary_search_on_un"))
Browser JavaScript companion
// Page 071 browser-side experiment: Ternary search on unimodal functions
const pageExample71 = {"values":[4,11,16,18,22,29,33,40],"target":22,"matrix":[[1,3,5],[7,9,11],[13,15,17]],"capacity":11,"page_marker":"071-ternary_search_on_un"};
function summarizePage71(sample = pageExample71) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Ternary search on unimodal functions",
kind: "ternary_search",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage71());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Ternary search on unimodal functions.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the ternary search invariant described in the code comments and return a stable, inspectable result for page 071.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for ternary search on unimodal functions and explain what each one stresses.
Page 072 / 561Chapter 6: Search and Binary Search
Exponential search
Page-local deep read
Mental model for Exponential search: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 072, the goal is not memorizing exponential search; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Exponential search is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Exponential search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
# Page 072: Exponential search
EXAMPLE = {'page': 72, 'topic': 'Exponential search', 'chapter': 'Search and Binary Search', 'kind': 'exponential_search', 'scenario': 'Run a concrete exponential search miniature for Exponential search.', 'sample_input': {'values': [3, 7, 8, 11, 18, 25, 29, 36, 40], 'target': 18, 'matrix': [[1, 3, 5], [7, 9, 11], [13, 15, 17]], 'capacity': 12}, 'expected_output': 'Inspectable result for Exponential search', 'watch_for': 'The invariant that makes Exponential search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the exponential search example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='072-exponential_search-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def exponential_search_p072(values, target):
if not values:
return -1
if values[0] == target:
return 0
bound = 1
while bound < len(values) and values[bound] < target:
bound *= 2
lo, hi = bound // 2 + 1, min(bound + 1, len(values))
while lo < hi:
mid = (lo + hi) // 2
if values[mid] < target: lo = mid + 1
else: hi = mid
return lo if lo < len(values) and values[lo] == target else -1
def run_example(example=EXAMPLE):
d = example['sample_input']; return exponential_search_p072(d['values'], d['target'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, target, matrix, capacity before reading the answer.
Common trap
Do not memorize the label "Exponential search" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Exponential search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the exponential search invariant described in the code comments and return a stable, inspectable result for page 072.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for exponential search, then point to the line of code that preserves it.
Page 073 / 561Chapter 6: Search and Binary Search
Interpolation search
Page-local deep read
Mental model for Interpolation search: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 073, the goal is not memorizing interpolation search; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Interpolation search is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Interpolation search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
# Page 073: Interpolation search
EXAMPLE = {'page': 73, 'topic': 'Interpolation search', 'chapter': 'Search and Binary Search', 'kind': 'interpolation_search', 'scenario': 'Run a concrete interpolation search miniature for Interpolation search.', 'sample_input': {'values': [3, 4, 7, 9, 14, 18, 25, 32, 36], 'target': 14, 'matrix': [[1, 3, 5], [7, 9, 11], [13, 15, 17]], 'capacity': 13}, 'expected_output': 'Inspectable result for Interpolation search', 'watch_for': 'The invariant that makes Interpolation search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the interpolation search example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='073-interpolation_sear-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def interpolation_search_p073(values, target):
lo, hi, probes = 0, len(values) - 1, []
while lo <= hi and values[lo] <= target <= values[hi]:
if values[lo] == values[hi]:
pos = lo
else:
pos = lo + (target - values[lo]) * (hi - lo) // (values[hi] - values[lo])
probes.append(pos)
if values[pos] == target: return {'index': pos, 'probes': probes}
if values[pos] < target: lo = pos + 1
else: hi = pos - 1
return {'index': -1, 'probes': probes}
def run_example(example=EXAMPLE):
d=example['sample_input']; return interpolation_search_p073(d['values'], d['target'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, target, matrix, capacity before reading the answer.
Common trap
Do not memorize the label "Interpolation search" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Interpolation search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the interpolation search invariant described in the code comments and return a stable, inspectable result for page 073.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 074 / 561Chapter 6: Search and Binary Search
Search in rotated arrays
Page-local deep read
Mental model for Search in rotated arrays: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 074, the goal is not memorizing search in rotated arrays; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Search in rotated arrays is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Search in rotated arrays before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: Mixing closed and half-open intervals in the same implementation is the fastest route to infinite loops.
# Page 074: Search in rotated arrays
EXAMPLE = {'page': 74, 'topic': 'Search in rotated arrays', 'chapter': 'Search and Binary Search', 'kind': 'rotated_search', 'scenario': 'Run a concrete rotated search miniature for Search in rotated arrays.', 'sample_input': {'values': [3, 5, 10, 14, 21, 25, 32, 39], 'target': 21, 'matrix': [[1, 3, 5], [7, 9, 11], [13, 15, 17]], 'capacity': 14}, 'expected_output': 'Inspectable result for Search in rotated arrays', 'watch_for': 'The invariant that makes Search in rotated arrays safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the rotated search example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='074-search_in_rotated_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def search_in_rotated_arrays_p074(values, target):
lo, hi = 0, len(values) - 1
while lo <= hi:
mid = (lo + hi) // 2
if values[mid] == target: return mid
if values[lo] <= values[mid]:
if values[lo] <= target < values[mid]: hi = mid - 1
else: lo = mid + 1
else:
if values[mid] < target <= values[hi]: lo = mid + 1
else: hi = mid - 1
return -1
def run_example(example=EXAMPLE):
return search_in_rotated_arrays_p074([13,15,17,1,3,5,7,9,11], 5)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, target, matrix, capacity before reading the answer.
Common trap
Do not memorize the label "Search in rotated arrays" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 074 curation harness: Search in rotated arrays
EXAMPLE_KIND = "rotated_search"
EXAMPLE_TITLE = "Search in rotated arrays"
SAMPLE = {
"values": [
3,
5,
10,
14,
21,
25,
32,
39
],
"target": 21,
"matrix": [
[
1,
3,
5
],
[
7,
9,
11
],
[
13,
15,
17
]
],
"capacity": 14,
"page_marker": "074-search_in_rotated_ar"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "074-search_in_rotated_ar"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "074-search_in_rotated_ar"))
Browser JavaScript companion
// Page 074 browser-side experiment: Search in rotated arrays
const pageExample74 = {"values":[3,5,10,14,21,25,32,39],"target":21,"matrix":[[1,3,5],[7,9,11],[13,15,17]],"capacity":14,"page_marker":"074-search_in_rotated_ar"};
function summarizePage74(sample = pageExample74) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Search in rotated arrays",
kind: "rotated_search",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage74());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Search in rotated arrays.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the rotated search invariant described in the code comments and return a stable, inspectable result for page 074.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 075 / 561Chapter 6: Search and Binary Search
Search in 2D matrices
Page-local deep read
Mental model for Search in 2D matrices: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 075, the goal is not memorizing search in 2d matrices; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Search in 2D matrices is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Search in 2D matrices before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: Mixing closed and half-open intervals in the same implementation is the fastest route to infinite loops.
# Page 075: Search in 2D matrices
EXAMPLE = {'page': 75, 'topic': 'Search in 2D matrices', 'chapter': 'Search and Binary Search', 'kind': 'matrix_search', 'scenario': 'Run a concrete matrix search miniature for Search in 2D matrices.', 'sample_input': {'values': [6, 10, 11, 17, 21, 28, 32, 39], 'target': 21, 'matrix': [[1, 3, 5], [7, 9, 11], [13, 15, 17]], 'capacity': 15}, 'expected_output': 'Inspectable result for Search in 2D matrices', 'watch_for': 'The invariant that makes Search in 2D matrices safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the matrix search example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='075-search_in_2d_matri-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def search_in_2d_matrices_p075(matrix, target):
if not matrix or not matrix[0]: return False
rows, cols = len(matrix), len(matrix[0])
lo, hi = 0, rows * cols
while lo < hi:
mid = (lo + hi) // 2
value = matrix[mid // cols][mid % cols]
if value < target: lo = mid + 1
else: hi = mid
return lo < rows * cols and matrix[lo // cols][lo % cols] == target
def run_example(example=EXAMPLE):
d=example['sample_input']; return search_in_2d_matrices_p075(d['matrix'], d['target'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, target, matrix, capacity before reading the answer.
Common trap
Do not memorize the label "Search in 2D matrices" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 075 curation harness: Search in 2D matrices
EXAMPLE_KIND = "matrix_search"
EXAMPLE_TITLE = "Search in 2D matrices"
SAMPLE = {
"values": [
6,
10,
11,
17,
21,
28,
32,
39
],
"target": 21,
"matrix": [
[
1,
3,
5
],
[
7,
9,
11
],
[
13,
15,
17
]
],
"capacity": 15,
"page_marker": "075-search_in_2d_matrice"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "075-search_in_2d_matrice"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "075-search_in_2d_matrice"))
Browser JavaScript companion
// Page 075 browser-side experiment: Search in 2D matrices
const pageExample75 = {"values":[6,10,11,17,21,28,32,39],"target":21,"matrix":[[1,3,5],[7,9,11],[13,15,17]],"capacity":15,"page_marker":"075-search_in_2d_matrice"};
function summarizePage75(sample = pageExample75) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Search in 2D matrices",
kind: "matrix_search",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage75());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Search in 2D matrices.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the matrix search invariant described in the code comments and return a stable, inspectable result for page 075.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement search in 2d matrices twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 076 / 561Chapter 6: Search and Binary Search
Meet-in-the-middle search
Page-local deep read
Mental model for Meet-in-the-middle search: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 076, the goal is not memorizing meet-in-the-middle search; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Meet-in-the-middle search is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Meet-in-the-middle search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: Mixing closed and half-open intervals in the same implementation is the fastest route to infinite loops.
# Page 076: Meet-in-the-middle search
EXAMPLE = {'page': 76, 'topic': 'Meet-in-the-middle search', 'chapter': 'Search and Binary Search', 'kind': 'meet_middle', 'scenario': 'Run a concrete meet middle miniature for Meet-in-the-middle search.', 'sample_input': {'values': [13, 24, 35, 6, 17, 28, 39], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Meet-in-the-middle search', 'watch_for': 'The invariant that makes Meet-in-the-middle search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the meet middle example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='076-meet_in_the_middle-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def meet_in_the_middle_search_p076(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return meet_in_the_middle_search_p076(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Meet-in-the-middle search, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Meet-in-the-middle search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the meet middle invariant described in the code comments and return a stable, inspectable result for page 076.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for meet-in-the-middle search and explain what each one stresses.
Page 077 / 561Chapter 6: Search and Binary Search
Pruning search spaces
Page-local deep read
Mental model for Pruning search spaces: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 077, the goal is not memorizing pruning search spaces; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Pruning search spaces is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Pruning search spaces before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: Mixing closed and half-open intervals in the same implementation is the fastest route to infinite loops.
# Page 077: Pruning search spaces
EXAMPLE = {'page': 77, 'topic': 'Pruning search spaces', 'chapter': 'Search and Binary Search', 'kind': 'prune_search', 'scenario': 'Run a concrete prune search miniature for Pruning search spaces.', 'sample_input': {'values': [20, 31, 2, 13, 24, 35, 6], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Pruning search spaces', 'watch_for': 'The invariant that makes Pruning search spaces safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the prune search example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='077-pruning_search_spa-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def pruning_search_spaces_p077(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return pruning_search_spaces_p077(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Do not memorize the label "Pruning search spaces" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Pruning search spaces.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the prune search invariant described in the code comments and return a stable, inspectable result for page 077.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for pruning search spaces, then point to the line of code that preserves it.
Page 078 / 561Chapter 6: Search and Binary Search
Debugging off-by-one errors
Page-local deep read
Mental model for Debugging off-by-one errors: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 078, the goal is not memorizing debugging off-by-one errors; it is recognizing the representation, the safe transition, and the stopping condition inside the Search and Binary Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Debugging off-by-one errors is one small tool in the larger Search and Binary Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Debugging off-by-one errors before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Search algorithms exploit structure. Binary search works not because the data is numeric, but because a predicate changes from false to true only once across an ordered domain.
Look for Debugging off-by-one errors whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: Mixing closed and half-open intervals in the same implementation is the fastest route to infinite loops.
# Page 078: Debugging off-by-one errors
EXAMPLE = {'page': 78, 'topic': 'Debugging off-by-one errors', 'chapter': 'Search and Binary Search', 'kind': 'bounds_test', 'scenario': 'Run a concrete bounds test miniature for Debugging off-by-one errors.', 'sample_input': {'values': [27, 38, 9, 20, 31, 2, 13], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Debugging off-by-one errors', 'watch_for': 'The invariant that makes Debugging off-by-one errors safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the bounds test example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='078-debugging_off_by_o-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def debugging_off_by_one_errors_p078(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return debugging_off_by_one_errors_p078(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Debugging off-by-one errors, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Debugging off-by-one errors.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the bounds test invariant described in the code comments and return a stable, inspectable result for page 078.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 079 / 561Chapter 7: Sorting Algorithms
Sorting problem model
Page-local deep read
Mental model for Sorting problem model: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 079, the goal is not memorizing sorting problem model; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sorting problem model is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sorting problem model before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 7: Sorting Algorithms
function mergeSort(arr) {
if (arr.length <= 1) return [...arr];
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid)), right = mergeSort(arr.slice(mid));
const out = []; let i = 0, j = 0;
while (i < left.length && j < right.length) out.push(left[i] <= right[j] ? left[i++] : right[j++]);
return out.concat(left.slice(i), right.slice(j));
}
console.log(mergeSort([31, 2, 13, 24, 35, 6, 17]));
Chapter anchor: This page is the Chapter 07 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Sorting Algorithms.
# Page 079: Sorting problem model
EXAMPLE = {'page': 79, 'topic': 'Sorting problem model', 'chapter': 'Sorting Algorithms', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for Sorting problem model.', 'sample_input': {'values': [34, 5, 16, 27, 38, 9, 20], 'records': [{'name': 'A', 'score': 34}, {'name': 'B', 'score': 5}, {'name': 'C', 'score': 16}]}, 'expected_output': 'Inspectable result for Sorting problem model', 'watch_for': 'The invariant that makes Sorting problem model safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='079-sorting_problem_mo-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def sorting_problem_model_p079(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return sorting_problem_model_p079(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Sorting Visualizer
Randomize an array, then animate a sorting algorithm.
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Sorting problem model" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 079 curation harness: Sorting problem model
EXAMPLE_KIND = "sort_pattern"
EXAMPLE_TITLE = "Sorting problem model"
SAMPLE = {
"values": [
34,
5,
16,
27,
38,
9,
20
],
"records": [
{
"name": "A",
"score": 34
},
{
"name": "B",
"score": 5
},
{
"name": "C",
"score": 16
}
],
"page_marker": "079-sorting_problem_mode"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "079-sorting_problem_mode"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "079-sorting_problem_mode"))
Browser JavaScript companion
// Page 079 browser-side experiment: Sorting problem model
const pageExample79 = {"values":[34,5,16,27,38,9,20],"records":[{"name":"A","score":34},{"name":"B","score":5},{"name":"C","score":16}],"page_marker":"079-sorting_problem_mode"};
function summarizePage79(sample = pageExample79) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Sorting problem model",
kind: "sort_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage79());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Sorting problem model.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 079.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 080 / 561Chapter 7: Sorting Algorithms
Insertion sort
Page-local deep read
Mental model for Insertion sort: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 080, the goal is not memorizing insertion sort; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Insertion sort is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Insertion sort before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 080: Insertion sort
EXAMPLE = {'page': 80, 'topic': 'Insertion sort', 'chapter': 'Sorting Algorithms', 'kind': 'insertion_sort', 'scenario': 'Run a concrete insertion sort miniature for Insertion sort.', 'sample_input': {'values': [1, 12, 23, 34, 5, 16, 27], 'records': [{'name': 'A', 'score': 1}, {'name': 'B', 'score': 12}, {'name': 'C', 'score': 23}]}, 'expected_output': 'Inspectable result for Insertion sort', 'watch_for': 'The invariant that makes Insertion sort safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the insertion sort example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='080-insertion_sort-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def insertion_sort_p080(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return insertion_sort_p080(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Insertion sort" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Insertion sort.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the insertion sort invariant described in the code comments and return a stable, inspectable result for page 080.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement insertion sort twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 081 / 561Chapter 7: Sorting Algorithms
Selection sort
Page-local deep read
Mental model for Selection sort: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 081, the goal is not memorizing selection sort; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Selection sort is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Selection sort before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: A comparator that is not transitive can make even a correct sorting implementation produce surprising results.
# Page 081: Selection sort
EXAMPLE = {'page': 81, 'topic': 'Selection sort', 'chapter': 'Sorting Algorithms', 'kind': 'selection_sort', 'scenario': 'Run a concrete selection sort miniature for Selection sort.', 'sample_input': {'values': [8, 19, 30, 1, 12, 23, 34], 'records': [{'name': 'A', 'score': 8}, {'name': 'B', 'score': 19}, {'name': 'C', 'score': 30}]}, 'expected_output': 'Inspectable result for Selection sort', 'watch_for': 'The invariant that makes Selection sort safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the selection sort example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='081-selection_sort-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def selection_sort_p081(values):
values = list(values); swaps = []
for i in range(len(values)):
m = min(range(i, len(values)), key=values.__getitem__)
values[i], values[m] = values[m], values[i]
swaps.append((i, m, values.copy()))
return swaps
def run_example(example=EXAMPLE):
return selection_sort_p081(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Selection sort" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Selection sort.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the selection sort invariant described in the code comments and return a stable, inspectable result for page 081.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for selection sort and explain what each one stresses.
Page 082 / 561Chapter 7: Sorting Algorithms
Bubble sort and teaching value
Page-local deep read
Mental model for Bubble sort and teaching value: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 082, the goal is not memorizing bubble sort and teaching value; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bubble sort and teaching value is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bubble sort and teaching value before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 082: Bubble sort and teaching value
EXAMPLE = {'page': 82, 'topic': 'Bubble sort and teaching value', 'chapter': 'Sorting Algorithms', 'kind': 'bubble_sort', 'scenario': 'Run a concrete bubble sort miniature for Bubble sort and teaching value.', 'sample_input': {'values': [15, 26, 37, 8, 19, 30, 1], 'records': [{'name': 'A', 'score': 15}, {'name': 'B', 'score': 26}, {'name': 'C', 'score': 37}]}, 'expected_output': 'Inspectable result for Bubble sort and teaching value', 'watch_for': 'The invariant that makes Bubble sort and teaching value safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the bubble sort example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='082-bubble_sort_and_te-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def bubble_sort_and_teaching_value_p082(values):
values = list(values); passes = []
for end in range(len(values)-1, 0, -1):
changed = False
for i in range(end):
if values[i] > values[i+1]:
values[i], values[i+1] = values[i+1], values[i]; changed = True
passes.append(values.copy())
if not changed: break
return passes
def run_example(example=EXAMPLE):
return bubble_sort_and_teaching_value_p082(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Bubble sort and teaching value" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 082 curation harness: Bubble sort and teaching value
EXAMPLE_KIND = "bubble_sort"
EXAMPLE_TITLE = "Bubble sort and teaching value"
SAMPLE = {
"values": [
15,
26,
37,
8,
19,
30,
1
],
"records": [
{
"name": "A",
"score": 15
},
{
"name": "B",
"score": 26
},
{
"name": "C",
"score": 37
}
],
"page_marker": "082-bubble_sort_and_teac"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "082-bubble_sort_and_teac"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "082-bubble_sort_and_teac"))
Browser JavaScript companion
// Page 082 browser-side experiment: Bubble sort and teaching value
const pageExample82 = {"values":[15,26,37,8,19,30,1],"records":[{"name":"A","score":15},{"name":"B","score":26},{"name":"C","score":37}],"page_marker":"082-bubble_sort_and_teac"};
function summarizePage82(sample = pageExample82) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Bubble sort and teaching value",
kind: "bubble_sort",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage82());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Bubble sort and teaching value.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the bubble sort invariant described in the code comments and return a stable, inspectable result for page 082.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for bubble sort and teaching value, then point to the line of code that preserves it.
Page 083 / 561Chapter 7: Sorting Algorithms
Merge sort
Page-local deep read
Mental model for Merge sort: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 083, the goal is not memorizing merge sort; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Merge sort is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Merge sort before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 083: Merge sort
EXAMPLE = {'page': 83, 'topic': 'Merge sort', 'chapter': 'Sorting Algorithms', 'kind': 'merge_sort', 'scenario': 'Run a concrete merge sort miniature for Merge sort.', 'sample_input': {'values': [22, 33, 4, 15, 26, 37, 8], 'records': [{'name': 'A', 'score': 22}, {'name': 'B', 'score': 33}, {'name': 'C', 'score': 4}]}, 'expected_output': 'Inspectable result for Merge sort', 'watch_for': 'The invariant that makes Merge sort safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the merge sort example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='083-merge_sort-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def merge_sort_p083(values):
values = list(values)
if len(values) <= 1: return values
mid = len(values) // 2
left, right = merge_sort_p083(values[:mid]), merge_sort_p083(values[mid:])
merged = []
while left and right:
merged.append((left if left[0] <= right[0] else right).pop(0))
return merged + left + right
def run_example(example=EXAMPLE):
return merge_sort_p083(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Merge sort" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Merge sort.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the merge sort invariant described in the code comments and return a stable, inspectable result for page 083.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 084 / 561Chapter 7: Sorting Algorithms
Quick sort
Page-local deep read
Mental model for Quick sort: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 084, the goal is not memorizing quick sort; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Quick sort is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Quick sort before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: A comparator that is not transitive can make even a correct sorting implementation produce surprising results.
# Page 084: Quick sort
EXAMPLE = {'page': 84, 'topic': 'Quick sort', 'chapter': 'Sorting Algorithms', 'kind': 'quick_sort', 'scenario': 'Run a concrete quick sort miniature for Quick sort.', 'sample_input': {'values': [29, 40, 11, 22, 33, 4, 15], 'records': [{'name': 'A', 'score': 29}, {'name': 'B', 'score': 40}, {'name': 'C', 'score': 11}]}, 'expected_output': 'Inspectable result for Quick sort', 'watch_for': 'The invariant that makes Quick sort safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the quick sort example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='084-quick_sort-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def quick_sort_p084(values):
if len(values) <= 1: return list(values)
pivot = values[len(values)//2]
lo = [x for x in values if x < pivot]
eq = [x for x in values if x == pivot]
hi = [x for x in values if x > pivot]
return quick_sort_p084(lo) + eq + quick_sort_p084(hi)
def run_example(example=EXAMPLE):
return quick_sort_p084(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Quick sort" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Quick sort.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the quick sort invariant described in the code comments and return a stable, inspectable result for page 084.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 085 / 561Chapter 7: Sorting Algorithms
Partition schemes
Page-local deep read
Mental model for Partition schemes: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 085, the goal is not memorizing partition schemes; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Partition schemes is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Partition schemes before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: A comparator that is not transitive can make even a correct sorting implementation produce surprising results.
# Page 085: Partition schemes
EXAMPLE = {'page': 85, 'topic': 'Partition schemes', 'chapter': 'Sorting Algorithms', 'kind': 'partition_array', 'scenario': 'Run a concrete partition array miniature for Partition schemes.', 'sample_input': {'values': [36, 7, 18, 29, 40, 11, 22], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Partition schemes', 'watch_for': 'The invariant that makes Partition schemes safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the partition array example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='085-partition_schemes-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def partition_schemes_p085(values, pivot):
smaller, equal, greater = [], [], []
for value in values:
if value < pivot: smaller.append(value)
elif value == pivot: equal.append(value)
else: greater.append(value)
return smaller + equal + greater
def run_example(example=EXAMPLE):
vals=example['sample_input']['values']; return partition_schemes_p085(vals, vals[len(vals)//2])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Partition schemes.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the partition array invariant described in the code comments and return a stable, inspectable result for page 085.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement partition schemes twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 086 / 561Chapter 7: Sorting Algorithms
Heap sort
Page-local deep read
Mental model for Heap sort: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 086, the goal is not memorizing heap sort; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Heap sort is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Heap sort before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: A comparator that is not transitive can make even a correct sorting implementation produce surprising results.
Do not memorize the label "Heap sort" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Heap sort.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap sort invariant described in the code comments and return a stable, inspectable result for page 086.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for heap sort and explain what each one stresses.
Page 087 / 561Chapter 7: Sorting Algorithms
Counting sort
Page-local deep read
Mental model for Counting sort: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 087, the goal is not memorizing counting sort; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Counting sort is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Counting sort before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: A comparator that is not transitive can make even a correct sorting implementation produce surprising results.
# Page 087: Counting sort
EXAMPLE = {'page': 87, 'topic': 'Counting sort', 'chapter': 'Sorting Algorithms', 'kind': 'counting_sort', 'scenario': 'Run a concrete counting sort miniature for Counting sort.', 'sample_input': {'values': [10, 21, 32, 3, 14, 25, 36], 'records': [{'name': 'A', 'score': 10}, {'name': 'B', 'score': 21}, {'name': 'C', 'score': 32}]}, 'expected_output': 'Inspectable result for Counting sort', 'watch_for': 'The invariant that makes Counting sort safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the counting sort example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='087-counting_sort-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def counting_sort_p087(values):
if not values: return []
offset = min(values); counts = [0] * (max(values) - offset + 1)
for value in values: counts[value - offset] += 1
out = []
for i, count in enumerate(counts): out.extend([i + offset] * count)
return out
def run_example(example=EXAMPLE):
return counting_sort_p087([v % 10 for v in example['sample_input']['values']])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Counting sort" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Counting sort.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the counting sort invariant described in the code comments and return a stable, inspectable result for page 087.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for counting sort, then point to the line of code that preserves it.
Page 088 / 561Chapter 7: Sorting Algorithms
Radix sort
Page-local deep read
Mental model for Radix sort: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 088, the goal is not memorizing radix sort; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Radix sort is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Radix sort before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Radix sort whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: A comparator that is not transitive can make even a correct sorting implementation produce surprising results.
# Page 088: Radix sort
EXAMPLE = {'page': 88, 'topic': 'Radix sort', 'chapter': 'Sorting Algorithms', 'kind': 'radix_sort', 'scenario': 'Run a concrete radix sort miniature for Radix sort.', 'sample_input': {'values': [17, 28, 39, 10, 21, 32, 3], 'records': [{'name': 'A', 'score': 17}, {'name': 'B', 'score': 28}, {'name': 'C', 'score': 39}]}, 'expected_output': 'Inspectable result for Radix sort', 'watch_for': 'The invariant that makes Radix sort safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the radix sort example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='088-radix_sort-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def radix_sort_p088(values):
values = list(values); exp = 1
while values and max(values) // exp > 0:
buckets = [[] for _ in range(10)]
for value in values: buckets[(value // exp) % 10].append(value)
values = [x for bucket in buckets for x in bucket]
exp *= 10
return values
def run_example(example=EXAMPLE):
return radix_sort_p088(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Radix sort" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Radix sort.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the radix sort invariant described in the code comments and return a stable, inspectable result for page 088.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 089 / 561Chapter 7: Sorting Algorithms
Bucket sort
Page-local deep read
Mental model for Bucket sort: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 089, the goal is not memorizing bucket sort; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bucket sort is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bucket sort before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 089: Bucket sort
EXAMPLE = {'page': 89, 'topic': 'Bucket sort', 'chapter': 'Sorting Algorithms', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for Bucket sort.', 'sample_input': {'values': [24, 35, 6, 17, 28, 39, 10], 'records': [{'name': 'A', 'score': 24}, {'name': 'B', 'score': 35}, {'name': 'C', 'score': 6}]}, 'expected_output': 'Inspectable result for Bucket sort', 'watch_for': 'The invariant that makes Bucket sort safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='089-bucket_sort-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def bucket_sort_p089(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return bucket_sort_p089(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Bucket sort" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Bucket sort.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 089.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 090 / 561Chapter 7: Sorting Algorithms
Shell sort
Page-local deep read
Mental model for Shell sort: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 090, the goal is not memorizing shell sort; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Shell sort is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Shell sort before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 090: Shell sort
EXAMPLE = {'page': 90, 'topic': 'Shell sort', 'chapter': 'Sorting Algorithms', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for Shell sort.', 'sample_input': {'values': [31, 2, 13, 24, 35, 6, 17], 'records': [{'name': 'A', 'score': 31}, {'name': 'B', 'score': 2}, {'name': 'C', 'score': 13}]}, 'expected_output': 'Inspectable result for Shell sort', 'watch_for': 'The invariant that makes Shell sort safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='090-shell_sort-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def shell_sort_p090(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return shell_sort_p090(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Shell sort" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Shell sort.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 090.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement shell sort twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 091 / 561Chapter 7: Sorting Algorithms
Timsort intuition
Page-local deep read
Mental model for Timsort intuition: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 091, the goal is not memorizing timsort intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Timsort intuition is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Timsort intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: A comparator that is not transitive can make even a correct sorting implementation produce surprising results.
# Page 091: Timsort intuition
EXAMPLE = {'page': 91, 'topic': 'Timsort intuition', 'chapter': 'Sorting Algorithms', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for Timsort intuition.', 'sample_input': {'values': [38, 9, 20, 31, 2, 13, 24], 'records': [{'name': 'A', 'score': 38}, {'name': 'B', 'score': 9}, {'name': 'C', 'score': 20}]}, 'expected_output': 'Inspectable result for Timsort intuition', 'watch_for': 'The invariant that makes Timsort intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='091-timsort_intuition-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def timsort_intuition_p091(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return timsort_intuition_p091(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Timsort intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Timsort intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 091.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for timsort intuition and explain what each one stresses.
Page 092 / 561Chapter 7: Sorting Algorithms
Stability and tie-breaking
Page-local deep read
Mental model for Stability and tie-breaking: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 092, the goal is not memorizing stability and tie-breaking; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Stability and tie-breaking is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Stability and tie-breaking before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 092: Stability and tie-breaking
EXAMPLE = {'page': 92, 'topic': 'Stability and tie-breaking', 'chapter': 'Sorting Algorithms', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for Stability and tie-breaking.', 'sample_input': {'values': [5, 16, 27, 38, 9, 20, 31], 'records': [{'name': 'A', 'score': 5}, {'name': 'B', 'score': 16}, {'name': 'C', 'score': 27}]}, 'expected_output': 'Inspectable result for Stability and tie-breaking', 'watch_for': 'The invariant that makes Stability and tie-breaking safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='092-stability_and_tie_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def stability_and_tie_breaking_p092(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return stability_and_tie_breaking_p092(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Stability and tie-breaking" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 092 curation harness: Stability and tie-breaking
EXAMPLE_KIND = "sort_pattern"
EXAMPLE_TITLE = "Stability and tie-breaking"
SAMPLE = {
"values": [
5,
16,
27,
38,
9,
20,
31
],
"records": [
{
"name": "A",
"score": 5
},
{
"name": "B",
"score": 16
},
{
"name": "C",
"score": 27
}
],
"page_marker": "092-stability_and_tie_br"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "092-stability_and_tie_br"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "092-stability_and_tie_br"))
Browser JavaScript companion
// Page 092 browser-side experiment: Stability and tie-breaking
const pageExample92 = {"values":[5,16,27,38,9,20,31],"records":[{"name":"A","score":5},{"name":"B","score":16},{"name":"C","score":27}],"page_marker":"092-stability_and_tie_br"};
function summarizePage92(sample = pageExample92) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Stability and tie-breaking",
kind: "sort_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage92());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Stability and tie-breaking.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 092.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for stability and tie-breaking, then point to the line of code that preserves it.
Page 093 / 561Chapter 7: Sorting Algorithms
External sorting
Page-local deep read
Mental model for External sorting: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 093, the goal is not memorizing external sorting; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: External sorting is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for External sorting before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 093: External sorting
EXAMPLE = {'page': 93, 'topic': 'External sorting', 'chapter': 'Sorting Algorithms', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for External sorting.', 'sample_input': {'values': [12, 23, 34, 5, 16, 27, 38], 'records': [{'name': 'A', 'score': 12}, {'name': 'B', 'score': 23}, {'name': 'C', 'score': 34}]}, 'expected_output': 'Inspectable result for External sorting', 'watch_for': 'The invariant that makes External sorting safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='093-external_sorting-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def external_sorting_p093(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return external_sorting_p093(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "External sorting" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by External sorting.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 093.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 094 / 561Chapter 7: Sorting Algorithms
Sorting linked lists
Page-local deep read
Mental model for Sorting linked lists: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 094, the goal is not memorizing sorting linked lists; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sorting linked lists is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sorting linked lists before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: A comparator that is not transitive can make even a correct sorting implementation produce surprising results.
# Page 094: Sorting linked lists
EXAMPLE = {'page': 94, 'topic': 'Sorting linked lists', 'chapter': 'Sorting Algorithms', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for Sorting linked lists.', 'sample_input': {'values': [19, 30, 1, 12, 23, 34, 5], 'records': [{'name': 'A', 'score': 19}, {'name': 'B', 'score': 30}, {'name': 'C', 'score': 1}]}, 'expected_output': 'Inspectable result for Sorting linked lists', 'watch_for': 'The invariant that makes Sorting linked lists safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='094-sorting_linked_lis-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def sorting_linked_lists_p094(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return sorting_linked_lists_p094(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Sorting linked lists" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Sorting linked lists.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 094.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 095 / 561Chapter 7: Sorting Algorithms
Partial sorting and top-k
Page-local deep read
Mental model for Partial sorting and top-k: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 095, the goal is not memorizing partial sorting and top-k; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Partial sorting and top-k is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Partial sorting and top-k before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: A comparator that is not transitive can make even a correct sorting implementation produce surprising results.
# Page 095: Partial sorting and top-k
EXAMPLE = {'page': 95, 'topic': 'Partial sorting and top-k', 'chapter': 'Sorting Algorithms', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for Partial sorting and top-k.', 'sample_input': {'values': [26, 37, 8, 19, 30, 1, 12], 'records': [{'name': 'A', 'score': 26}, {'name': 'B', 'score': 37}, {'name': 'C', 'score': 8}]}, 'expected_output': 'Inspectable result for Partial sorting and top-k', 'watch_for': 'The invariant that makes Partial sorting and top-k safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='095-partial_sorting_an-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def partial_sorting_and_top_k_p095(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return partial_sorting_and_top_k_p095(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Partial sorting and top-k" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 095 curation harness: Partial sorting and top-k
EXAMPLE_KIND = "sort_pattern"
EXAMPLE_TITLE = "Partial sorting and top-k"
SAMPLE = {
"values": [
26,
37,
8,
19,
30,
1,
12
],
"records": [
{
"name": "A",
"score": 26
},
{
"name": "B",
"score": 37
},
{
"name": "C",
"score": 8
}
],
"page_marker": "095-partial_sorting_and_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "095-partial_sorting_and_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "095-partial_sorting_and_"))
Browser JavaScript companion
// Page 095 browser-side experiment: Partial sorting and top-k
const pageExample95 = {"values":[26,37,8,19,30,1,12],"records":[{"name":"A","score":26},{"name":"B","score":37},{"name":"C","score":8}],"page_marker":"095-partial_sorting_and_"};
function summarizePage95(sample = pageExample95) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Partial sorting and top-k",
kind: "sort_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage95());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Partial sorting and top-k.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 095.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement partial sorting and top-k twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 096 / 561Chapter 7: Sorting Algorithms
Comparator contracts
Page-local deep read
Mental model for Comparator contracts: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 096, the goal is not memorizing comparator contracts; it is recognizing the representation, the safe transition, and the stopping condition inside the Sorting Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Comparator contracts is one small tool in the larger Sorting Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Comparator contracts before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: A comparator that is not transitive can make even a correct sorting implementation produce surprising results.
Do not memorize the label "Comparator contracts" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Comparator contracts.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 096.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for comparator contracts and explain what each one stresses.
Page 097 / 561Chapter 8: Recursion and Divide and Conquer
Recursion stack anatomy
Page-local deep read
Mental model for Recursion stack anatomy: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 097, the goal is not memorizing recursion stack anatomy; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Recursion stack anatomy is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Recursion stack anatomy before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 8: Recursion and Divide and Conquer
function maxSubarray(values) {
let best = -Infinity, current = -Infinity;
for (const x of values) { current = Math.max(x, current + x); best = Math.max(best, current); }
return best;
}
console.log(maxSubarray([2, -1, 3, -5, 4, 6, -2]));
Chapter anchor: This page is the Chapter 08 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Recursion and Divide and Conquer.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: missing base cases. Make this risk visible in tests and in code comments.
Common pitfall: A recursive solution without a shrinking argument may look elegant while never terminating.
# Page 097: Recursion stack anatomy
EXAMPLE = {'page': 97, 'topic': 'Recursion stack anatomy', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'recursion_pattern', 'scenario': 'Run a concrete recursion pattern miniature for Recursion stack anatomy.', 'sample_input': {'values': [40, 11, 22, 33, 4, 15, 26], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Recursion stack anatomy', 'watch_for': 'The invariant that makes Recursion stack anatomy safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the recursion pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='097-recursion_stack_an-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def recursion_stack_anatomy_p097(base, exponent):
if exponent == 0: return 1
half = recursion_stack_anatomy_p097(base, exponent // 2)
return half * half if exponent % 2 == 0 else half * half * base
def trace_power(base, exponent):
return {'base': base, 'exponent': exponent, 'value': recursion_stack_anatomy_p097(base, exponent)}
def run_example(example=EXAMPLE):
return trace_power(3, 7)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Recursion stack anatomy, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Recursion stack anatomy.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the recursion pattern invariant described in the code comments and return a stable, inspectable result for page 097.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for recursion stack anatomy, then point to the line of code that preserves it.
Page 098 / 561Chapter 8: Recursion and Divide and Conquer
Tail recursion and iteration
Page-local deep read
Mental model for Tail recursion and iteration: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 098, the goal is not memorizing tail recursion and iteration; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Tail recursion and iteration is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Tail recursion and iteration before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Tail recursion and iteration whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: missing base cases. Make this risk visible in tests and in code comments.
Common pitfall: A recursive solution without a shrinking argument may look elegant while never terminating.
# Page 098: Tail recursion and iteration
EXAMPLE = {'page': 98, 'topic': 'Tail recursion and iteration', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'recursion_pattern', 'scenario': 'Run a concrete recursion pattern miniature for Tail recursion and iteration.', 'sample_input': {'values': [7, 18, 29, 40, 11, 22, 33], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Tail recursion and iteration', 'watch_for': 'The invariant that makes Tail recursion and iteration safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the recursion pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='098-tail_recursion_and-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def tail_recursion_and_iteration_p098(base, exponent):
if exponent == 0: return 1
half = tail_recursion_and_iteration_p098(base, exponent // 2)
return half * half if exponent % 2 == 0 else half * half * base
def trace_power(base, exponent):
return {'base': base, 'exponent': exponent, 'value': tail_recursion_and_iteration_p098(base, exponent)}
def run_example(example=EXAMPLE):
return trace_power(3, 7)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Tail recursion and iteration, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 098 curation harness: Tail recursion and iteration
EXAMPLE_KIND = "recursion_pattern"
EXAMPLE_TITLE = "Tail recursion and iteration"
SAMPLE = {
"values": [
7,
18,
29,
40,
11,
22,
33
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "098-tail_recursion_and_i"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "098-tail_recursion_and_i"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "098-tail_recursion_and_i"))
Browser JavaScript companion
// Page 098 browser-side experiment: Tail recursion and iteration
const pageExample98 = {"values":[7,18,29,40,11,22,33],"steps":["read","update","verify"],"page_marker":"098-tail_recursion_and_i"};
function summarizePage98(sample = pageExample98) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Tail recursion and iteration",
kind: "recursion_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage98());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Tail recursion and iteration.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the recursion pattern invariant described in the code comments and return a stable, inspectable result for page 098.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 099 / 561Chapter 8: Recursion and Divide and Conquer
Divide, conquer, and combine
Page-local deep read
Mental model for Divide, conquer, and combine: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 099, the goal is not memorizing divide, conquer, and combine; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Divide, conquer, and combine is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Divide, conquer, and combine before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 099: Divide, conquer, and combine
EXAMPLE = {'page': 99, 'topic': 'Divide, conquer, and combine', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for Divide, conquer, and combine.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [14, 25, 36, 7, 18, 29, 40], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Divide, conquer, and combine', 'watch_for': 'The invariant that makes Divide, conquer, and combine safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='099-divide_conquer_and-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def divide_conquer_and_combine_p099(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return divide_conquer_and_combine_p099(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Divide, conquer, and combine, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 099 curation harness: Divide, conquer, and combine
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "Divide, conquer, and combine"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"perform transition",
"check output"
],
"values": [
14,
25,
36,
7,
18,
29,
40
],
"sizes": [
4,
8,
16,
32
],
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "099-divide_conquer_and_c"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "099-divide_conquer_and_c"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "099-divide_conquer_and_c"))
Browser JavaScript companion
// Page 099 browser-side experiment: Divide, conquer, and combine
const pageExample99 = {"steps":["read input","state invariant","perform transition","check output"],"values":[14,25,36,7,18,29,40],"sizes":[4,8,16,32],"requests":["A","B","A","C","D","A"],"page_marker":"099-divide_conquer_and_c"};
function summarizePage99(sample = pageExample99) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Divide, conquer, and combine",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage99());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Divide, conquer, and combine.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 099.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 100 / 561Chapter 8: Recursion and Divide and Conquer
Binary exponentiation
Page-local deep read
Mental model for Binary exponentiation: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 100, the goal is not memorizing binary exponentiation; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Binary exponentiation is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Binary exponentiation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 100: Binary exponentiation
EXAMPLE = {'page': 100, 'topic': 'Binary exponentiation', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'binary_power', 'scenario': 'Run a concrete binary power miniature for Binary exponentiation.', 'sample_input': {'values': [21, 32, 3, 14, 25, 36, 7], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Binary exponentiation', 'watch_for': 'The invariant that makes Binary exponentiation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the binary power example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='100-binary_exponentiat-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def binary_exponentiation_p100(base, exponent):
if exponent == 0: return 1
half = binary_exponentiation_p100(base, exponent // 2)
return half * half if exponent % 2 == 0 else half * half * base
def trace_power(base, exponent):
return {'base': base, 'exponent': exponent, 'value': binary_exponentiation_p100(base, exponent)}
def run_example(example=EXAMPLE):
return trace_power(3, 7)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Binary exponentiation, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Binary exponentiation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the binary power invariant described in the code comments and return a stable, inspectable result for page 100.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement binary exponentiation twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 101 / 561Chapter 8: Recursion and Divide and Conquer
Closest pair divide-and-conquer
Page-local deep read
Mental model for Closest pair divide-and-conquer: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 101, the goal is not memorizing closest pair divide-and-conquer; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Closest pair divide-and-conquer is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Closest pair divide-and-conquer before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: missing base cases. Make this risk visible in tests and in code comments.
Common pitfall: A recursive solution without a shrinking argument may look elegant while never terminating.
# Page 101: Closest pair divide-and-conquer
EXAMPLE = {'page': 101, 'topic': 'Closest pair divide-and-conquer', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'closest_pair', 'scenario': 'Run a concrete closest pair miniature for Closest pair divide-and-conquer.', 'sample_input': {'values': [28, 39, 10, 21, 32, 3, 14], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Closest pair divide-and-conquer', 'watch_for': 'The invariant that makes Closest pair divide-and-conquer safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the closest pair example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='101-closest_pair_divid-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from math import hypot
def closest_pair_divide_and_conquer_p101(points):
best = (float('inf'), None)
for i, a in enumerate(points):
for b in points[i+1:]:
d = hypot(a[0]-b[0], a[1]-b[1])
if d < best[0]: best = (d, (a, b))
return best
def run_example(example=EXAMPLE):
return closest_pair_divide_and_conquer_p101(example['sample_input'].get('points', [(0,0),(2,1),(1,1)]))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Closest pair divide-and-conquer, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Closest pair divide-and-conquer.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the closest pair invariant described in the code comments and return a stable, inspectable result for page 101.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for closest pair divide-and-conquer and explain what each one stresses.
Page 102 / 561Chapter 8: Recursion and Divide and Conquer
Karatsuba multiplication
Page-local deep read
Mental model for Karatsuba multiplication: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 102, the goal is not memorizing karatsuba multiplication; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Karatsuba multiplication is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Karatsuba multiplication before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 102: Karatsuba multiplication
EXAMPLE = {'page': 102, 'topic': 'Karatsuba multiplication', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'karatsuba', 'scenario': 'Run a concrete karatsuba miniature for Karatsuba multiplication.', 'sample_input': {'values': [35, 6, 17, 28, 39, 10, 21], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Karatsuba multiplication', 'watch_for': 'The invariant that makes Karatsuba multiplication safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the karatsuba example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='102-karatsuba_multipli-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def karatsuba_multiplication_p102(x, y):
if x < 10 or y < 10: return x * y
m = max(len(str(x)), len(str(y))) // 2
high1, low1 = divmod(x, 10**m); high2, low2 = divmod(y, 10**m)
z0 = karatsuba_multiplication_p102(low1, low2); z2 = karatsuba_multiplication_p102(high1, high2)
z1 = karatsuba_multiplication_p102(low1 + high1, low2 + high2) - z2 - z0
return z2 * 10**(2*m) + z1 * 10**m + z0
def run_example(example=EXAMPLE):
return karatsuba_multiplication_p102(1234, 5678)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Karatsuba multiplication, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Karatsuba multiplication.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the karatsuba invariant described in the code comments and return a stable, inspectable result for page 102.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for karatsuba multiplication, then point to the line of code that preserves it.
Page 103 / 561Chapter 8: Recursion and Divide and Conquer
Quickselect
Page-local deep read
Mental model for Quickselect: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 103, the goal is not memorizing quickselect; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Quickselect is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Quickselect before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as often recurrence-based time and recursion depth space in the common model, then revisit the bound when the input representation changes.
Key risk: missing base cases. Make this risk visible in tests and in code comments.
Common pitfall: A recursive solution without a shrinking argument may look elegant while never terminating.
# Page 103: Quickselect
EXAMPLE = {'page': 103, 'topic': 'Quickselect', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'quickselect', 'scenario': 'Run a concrete quickselect miniature for Quickselect.', 'sample_input': {'values': [2, 13, 24, 35, 6, 17, 28], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Quickselect', 'watch_for': 'The invariant that makes Quickselect safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the quickselect example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='103-quickselect-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def quickselect_p103(values, k):
pivot = values[len(values)//2]
lows = [v for v in values if v < pivot]
highs = [v for v in values if v > pivot]
pivots = [v for v in values if v == pivot]
if k < len(lows): return quickselect_p103(lows, k)
if k < len(lows) + len(pivots): return pivot
return quickselect_p103(highs, k - len(lows) - len(pivots))
def run_example(example=EXAMPLE):
return quickselect_p103(example['sample_input']['values'], 2)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Quickselect, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Quickselect.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the quickselect invariant described in the code comments and return a stable, inspectable result for page 103.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 104 / 561Chapter 8: Recursion and Divide and Conquer
Merge-based inversion counting
Page-local deep read
Mental model for Merge-based inversion counting: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 104, the goal is not memorizing merge-based inversion counting; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Merge-based inversion counting is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Merge-based inversion counting before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: missing base cases. Make this risk visible in tests and in code comments.
Common pitfall: A recursive solution without a shrinking argument may look elegant while never terminating.
# Page 104: Merge-based inversion counting
EXAMPLE = {'page': 104, 'topic': 'Merge-based inversion counting', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'inversions', 'scenario': 'Run a concrete inversions miniature for Merge-based inversion counting.', 'sample_input': {'values': [9, 20, 31, 2, 13, 24, 35], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Merge-based inversion counting', 'watch_for': 'The invariant that makes Merge-based inversion counting safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the inversions example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='104-merge_based_invers-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def merge_based_inversion_counting_p104(values):
if len(values) <= 1: return list(values), 0
mid = len(values)//2
left, inv_left = merge_based_inversion_counting_p104(values[:mid]); right, inv_right = merge_based_inversion_counting_p104(values[mid:])
merged, inv_split = [], 0
while left and right:
if left[0] <= right[0]: merged.append(left.pop(0))
else: merged.append(right.pop(0)); inv_split += len(left)
return merged + left + right, inv_left + inv_right + inv_split
def run_example(example=EXAMPLE):
return merge_based_inversion_counting_p104(example['sample_input']['values'])[1]
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Merge-based inversion counting, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Merge-based inversion counting.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the inversions invariant described in the code comments and return a stable, inspectable result for page 104.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 105 / 561Chapter 8: Recursion and Divide and Conquer
Recursive backtracking templates
Page-local deep read
Mental model for Recursive backtracking templates: Treat the algorithm as a decision tree. The important beginner move is to separate choose, check, recurse, and undo so failed branches do not contaminate later branches.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 105, the goal is not memorizing recursive backtracking templates; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Recursive backtracking templates is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Recursive backtracking templates before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: A recursive solution without a shrinking argument may look elegant while never terminating.
# Page 105: Recursive backtracking templates
EXAMPLE = {'page': 105, 'topic': 'Recursive backtracking templates', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for Recursive backtracking templates.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [16, 27, 38, 9, 20, 31, 2], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Recursive backtracking templates', 'watch_for': 'The invariant that makes Recursive backtracking templates safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='105-recursive_backtrac-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def recursive_backtracking_templates_p105(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return recursive_backtracking_templates_p105(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Recursive backtracking templates, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Recursive backtracking templates.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 105.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement recursive backtracking templates twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 106 / 561Chapter 8: Recursion and Divide and Conquer
Memoization versus raw recursion
Page-local deep read
Mental model for Memoization versus raw recursion: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 106, the goal is not memorizing memoization versus raw recursion; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Memoization versus raw recursion is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Memoization versus raw recursion before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: missing base cases. Make this risk visible in tests and in code comments.
Common pitfall: A recursive solution without a shrinking argument may look elegant while never terminating.
# Page 106: Memoization versus raw recursion
EXAMPLE = {'page': 106, 'topic': 'Memoization versus raw recursion', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'recursion_pattern', 'scenario': 'Run a concrete recursion pattern miniature for Memoization versus raw recursion.', 'sample_input': {'values': [23, 34, 5, 16, 27, 38, 9], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Memoization versus raw recursion', 'watch_for': 'The invariant that makes Memoization versus raw recursion safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the recursion pattern example changes first.', 'docs': [('Python functools.cache/lru_cache', 'https://docs.python.org/3/library/functools.html')]}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='106-memoization_versus-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def memoization_versus_raw_recursion_p106(base, exponent):
if exponent == 0: return 1
half = memoization_versus_raw_recursion_p106(base, exponent // 2)
return half * half if exponent % 2 == 0 else half * half * base
def trace_power(base, exponent):
return {'base': base, 'exponent': exponent, 'value': memoization_versus_raw_recursion_p106(base, exponent)}
def run_example(example=EXAMPLE):
return trace_power(3, 7)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Memoization versus raw recursion, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 106 curation harness: Memoization versus raw recursion
EXAMPLE_KIND = "recursion_pattern"
EXAMPLE_TITLE = "Memoization versus raw recursion"
SAMPLE = {
"values": [
23,
34,
5,
16,
27,
38,
9
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "106-memoization_versus_r"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "106-memoization_versus_r"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "106-memoization_versus_r"))
Browser JavaScript companion
// Page 106 browser-side experiment: Memoization versus raw recursion
const pageExample106 = {"values":[23,34,5,16,27,38,9],"steps":["read","update","verify"],"page_marker":"106-memoization_versus_r"};
function summarizePage106(sample = pageExample106) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Memoization versus raw recursion",
kind: "recursion_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage106());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Memoization versus raw recursion.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the recursion pattern invariant described in the code comments and return a stable, inspectable result for page 106.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for memoization versus raw recursion and explain what each one stresses.
Page 107 / 561Chapter 8: Recursion and Divide and Conquer
Recursion limits and stack safety
Page-local deep read
Mental model for Recursion limits and stack safety: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 107, the goal is not memorizing recursion limits and stack safety; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Recursion limits and stack safety is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Recursion limits and stack safety before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: missing base cases. Make this risk visible in tests and in code comments.
Common pitfall: A recursive solution without a shrinking argument may look elegant while never terminating.
# Page 107: Recursion limits and stack safety
EXAMPLE = {'page': 107, 'topic': 'Recursion limits and stack safety', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'recursion_pattern', 'scenario': 'Run a concrete recursion pattern miniature for Recursion limits and stack safety.', 'sample_input': {'values': [30, 1, 12, 23, 34, 5, 16], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Recursion limits and stack safety', 'watch_for': 'The invariant that makes Recursion limits and stack safety safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the recursion pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='107-recursion_limits_a-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def recursion_limits_and_stack_safety_p107(base, exponent):
if exponent == 0: return 1
half = recursion_limits_and_stack_safety_p107(base, exponent // 2)
return half * half if exponent % 2 == 0 else half * half * base
def trace_power(base, exponent):
return {'base': base, 'exponent': exponent, 'value': recursion_limits_and_stack_safety_p107(base, exponent)}
def run_example(example=EXAMPLE):
return trace_power(3, 7)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Recursion limits and stack safety, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 107 curation harness: Recursion limits and stack safety
EXAMPLE_KIND = "recursion_pattern"
EXAMPLE_TITLE = "Recursion limits and stack safety"
SAMPLE = {
"values": [
30,
1,
12,
23,
34,
5,
16
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "107-recursion_limits_and"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "107-recursion_limits_and"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "107-recursion_limits_and"))
Browser JavaScript companion
// Page 107 browser-side experiment: Recursion limits and stack safety
const pageExample107 = {"values":[30,1,12,23,34,5,16],"steps":["read","update","verify"],"page_marker":"107-recursion_limits_and"};
function summarizePage107(sample = pageExample107) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Recursion limits and stack safety",
kind: "recursion_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage107());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Recursion limits and stack safety.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the recursion pattern invariant described in the code comments and return a stable, inspectable result for page 107.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for recursion limits and stack safety, then point to the line of code that preserves it.
Page 108 / 561Chapter 8: Recursion and Divide and Conquer
Divide-and-conquer DP preview
Page-local deep read
Mental model for Divide-and-conquer DP preview: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 108, the goal is not memorizing divide-and-conquer dp preview; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Divide-and-conquer DP preview is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Divide-and-conquer DP preview before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Divide-and-conquer DP preview whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A recursive solution without a shrinking argument may look elegant while never terminating.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Divide-and-conquer DP preview" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Divide-and-conquer DP preview.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dp invariant described in the code comments and return a stable, inspectable result for page 108.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 109 / 561Chapter 8: Recursion and Divide and Conquer
Parallel divide-and-conquer
Page-local deep read
Mental model for Parallel divide-and-conquer: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 109, the goal is not memorizing parallel divide-and-conquer; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Parallel divide-and-conquer is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Parallel divide-and-conquer before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 109: Parallel divide-and-conquer
EXAMPLE = {'page': 109, 'topic': 'Parallel divide-and-conquer', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for Parallel divide-and-conquer.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [4, 15, 26, 37, 8, 19, 30], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Parallel divide-and-conquer', 'watch_for': 'The invariant that makes Parallel divide-and-conquer safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='109-parallel_divide_an-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def parallel_divide_and_conquer_p109(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return parallel_divide_and_conquer_p109(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Parallel divide-and-conquer, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Parallel divide-and-conquer.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 109.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 110 / 561Chapter 8: Recursion and Divide and Conquer
Designing base cases
Page-local deep read
Mental model for Designing base cases: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 110, the goal is not memorizing designing base cases; it is recognizing the representation, the safe transition, and the stopping condition inside the Recursion and Divide and Conquer chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Designing base cases is one small tool in the larger Recursion and Divide and Conquer toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Designing base cases before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 110: Designing base cases
EXAMPLE = {'page': 110, 'topic': 'Designing base cases', 'chapter': 'Recursion and Divide and Conquer', 'kind': 'recursion_pattern', 'scenario': 'Run a concrete recursion pattern miniature for Designing base cases.', 'sample_input': {'values': [11, 22, 33, 4, 15, 26, 37], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Designing base cases', 'watch_for': 'The invariant that makes Designing base cases safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the recursion pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='110-designing_base_cas-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def designing_base_cases_p110(base, exponent):
if exponent == 0: return 1
half = designing_base_cases_p110(base, exponent // 2)
return half * half if exponent % 2 == 0 else half * half * base
def trace_power(base, exponent):
return {'base': base, 'exponent': exponent, 'value': designing_base_cases_p110(base, exponent)}
def run_example(example=EXAMPLE):
return trace_power(3, 7)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Designing base cases, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 110 curation harness: Designing base cases
EXAMPLE_KIND = "recursion_pattern"
EXAMPLE_TITLE = "Designing base cases"
SAMPLE = {
"values": [
11,
22,
33,
4,
15,
26,
37
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "110-designing_base_cases"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "110-designing_base_cases"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "110-designing_base_cases"))
Browser JavaScript companion
// Page 110 browser-side experiment: Designing base cases
const pageExample110 = {"values":[11,22,33,4,15,26,37],"steps":["read","update","verify"],"page_marker":"110-designing_base_cases"};
function summarizePage110(sample = pageExample110) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Designing base cases",
kind: "recursion_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage110());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Designing base cases.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the recursion pattern invariant described in the code comments and return a stable, inspectable result for page 110.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement designing base cases twice: a direct version and an optimized version. Generate random small inputs and compare them.
Mental model for Stack ADT: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 111, the goal is not memorizing stack adt; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Stack ADT is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Stack ADT before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 9: Stacks, Queues, Deques, and Linked Lists
class SimpleDeque {
constructor() { this.data = []; }
pushRight(x) { this.data.push(x); }
pushLeft(x) { this.data.unshift(x); }
popLeft() { if (!this.data.length) throw new Error('empty'); return this.data.shift(); }
}
const dq = new SimpleDeque(); dq.pushRight(2); dq.pushLeft(1); console.log(dq.popLeft());
Chapter anchor: This page is the Chapter 09 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Stacks, Queues, Deques, and Linked Lists.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: wrong end operations. Make this risk visible in tests and in code comments.
Common pitfall: Using a structure that supports the right operation at the wrong end can change a linear traversal into a quadratic one.
# Page 111: Stack ADT
EXAMPLE = {'page': 111, 'topic': 'Stack ADT', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'stack', 'scenario': 'Run a concrete stack miniature for Stack ADT.', 'sample_input': {'values': [18, 29, 40, 11, 22, 33, 4], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Stack ADT', 'watch_for': 'The invariant that makes Stack ADT safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the stack example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='111-stack_adt-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def stack_adt_p111(tokens):
stack = []
for token in tokens:
if token.isdigit(): stack.append(int(token)); continue
b, a = stack.pop(), stack.pop()
stack.append(a + b if token == '+' else a * b)
return stack[-1]
def run_example(example=EXAMPLE):
return stack_adt_p111(['2','3','+','4','*'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Stack ADT, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Queue ADT: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 112, the goal is not memorizing queue adt; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Queue ADT is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Queue ADT before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Queue ADT, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Deque patterns: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 113, the goal is not memorizing deque patterns; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Deque patterns is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Deque patterns before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Deque patterns, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Monotonic stacks: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 114, the goal is not memorizing monotonic stacks; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Monotonic stacks is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Monotonic stacks before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: wrong end operations. Make this risk visible in tests and in code comments.
Common pitfall: Using a structure that supports the right operation at the wrong end can change a linear traversal into a quadratic one.
# Page 114: Monotonic stacks
EXAMPLE = {'page': 114, 'topic': 'Monotonic stacks', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'monotonic_stack', 'scenario': 'Run a concrete monotonic stack miniature for Monotonic stacks.', 'sample_input': {'values': [39, 10, 21, 32, 3, 14, 25], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Monotonic stacks', 'watch_for': 'The invariant that makes Monotonic stacks safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the monotonic stack example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='114-monotonic_stacks-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def monotonic_stacks_p114(values):
ans = [-1] * len(values); stack = []
for i, value in enumerate(values):
while stack and values[stack[-1]] < value:
ans[stack.pop()] = value
stack.append(i)
return ans
def run_example(example=EXAMPLE):
return monotonic_stacks_p114(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Monotonic stacks, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Monotonic queues: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 115, the goal is not memorizing monotonic queues; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Monotonic queues is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Monotonic queues before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: wrong end operations. Make this risk visible in tests and in code comments.
Common pitfall: Using a structure that supports the right operation at the wrong end can change a linear traversal into a quadratic one.
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Monotonic queues, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Parentheses and expression parsing: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 116, the goal is not memorizing parentheses and expression parsing; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Parentheses and expression parsing is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Parentheses and expression parsing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: wrong end operations. Make this risk visible in tests and in code comments.
Common pitfall: Using a structure that supports the right operation at the wrong end can change a linear traversal into a quadratic one.
# Page 116: Parentheses and expression parsing
EXAMPLE = {'page': 116, 'topic': 'Parentheses and expression parsing', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'expression_stack', 'scenario': 'Run a concrete expression stack miniature for Parentheses and expression parsing.', 'sample_input': {'values': [13, 24, 35, 6, 17, 28, 39], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Parentheses and expression parsing', 'watch_for': 'The invariant that makes Parentheses and expression parsing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the expression stack example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='116-parentheses_and_ex-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def parentheses_and_expression_parsing_p116(tokens):
stack = []
for token in tokens:
if token.isdigit(): stack.append(int(token)); continue
b, a = stack.pop(), stack.pop()
stack.append(a + b if token == '+' else a * b)
return stack[-1]
def run_example(example=EXAMPLE):
return parentheses_and_expression_parsing_p116(['2','3','+','4','*'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Parentheses and expression parsing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 116 curation harness: Parentheses and expression parsing
EXAMPLE_KIND = "expression_stack"
EXAMPLE_TITLE = "Parentheses and expression parsing"
SAMPLE = {
"values": [
13,
24,
35,
6,
17,
28,
39
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "116-parentheses_and_expr"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "116-parentheses_and_expr"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "116-parentheses_and_expr"))
Browser JavaScript companion
// Page 116 browser-side experiment: Parentheses and expression parsing
const pageExample116 = {"values":[13,24,35,6,17,28,39],"steps":["read","update","verify"],"page_marker":"116-parentheses_and_expr"};
function summarizePage116(sample = pageExample116) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Parentheses and expression parsing",
kind: "expression_stack",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage116());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Parentheses and expression parsing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the expression stack invariant described in the code comments and return a stable, inspectable result for page 116.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for parentheses and expression parsing and explain what each one stresses.
Mental model for Next greater element: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 117, the goal is not memorizing next greater element; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Next greater element is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Next greater element before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: wrong end operations. Make this risk visible in tests and in code comments.
Common pitfall: Using a structure that supports the right operation at the wrong end can change a linear traversal into a quadratic one.
# Page 117: Next greater element
EXAMPLE = {'page': 117, 'topic': 'Next greater element', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'next_greater', 'scenario': 'Run a concrete next greater miniature for Next greater element.', 'sample_input': {'values': [20, 31, 2, 13, 24, 35, 6], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Next greater element', 'watch_for': 'The invariant that makes Next greater element safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the next greater example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='117-next_greater_eleme-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def next_greater_element_p117(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return next_greater_element_p117(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Next greater element, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 117 curation harness: Next greater element
EXAMPLE_KIND = "next_greater"
EXAMPLE_TITLE = "Next greater element"
SAMPLE = {
"values": [
20,
31,
2,
13,
24,
35,
6
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "117-next_greater_element"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "117-next_greater_element"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "117-next_greater_element"))
Browser JavaScript companion
// Page 117 browser-side experiment: Next greater element
const pageExample117 = {"values":[20,31,2,13,24,35,6],"steps":["read","update","verify"],"page_marker":"117-next_greater_element"};
function summarizePage117(sample = pageExample117) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Next greater element",
kind: "next_greater",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage117());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Next greater element.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the next greater invariant described in the code comments and return a stable, inspectable result for page 117.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for next greater element, then point to the line of code that preserves it.
Mental model for Sliding-window maximum: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 118, the goal is not memorizing sliding-window maximum; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sliding-window maximum is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sliding-window maximum before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
Look for Sliding-window maximum whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: wrong end operations. Make this risk visible in tests and in code comments.
Common pitfall: Using a structure that supports the right operation at the wrong end can change a linear traversal into a quadratic one.
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Sliding-window maximum, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Singly linked lists: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 119, the goal is not memorizing singly linked lists; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Singly linked lists is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Singly linked lists before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
# Page 119: Singly linked lists
EXAMPLE = {'page': 119, 'topic': 'Singly linked lists', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'linked_list', 'scenario': 'Run a concrete linked list miniature for Singly linked lists.', 'sample_input': {'values': [34, 5, 16, 27, 38, 9, 20], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Singly linked lists', 'watch_for': 'The invariant that makes Singly linked lists safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linked list example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='119-singly_linked_list-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class Node:
def __init__(self, value, next=None): self.value, self.next = value, next
def singly_linked_lists_p119(head):
prev, node = None, head
while node:
nxt = node.next; node.next = prev; prev = node; node = nxt
return prev
def to_list(head):
out=[]
while head: out.append(head.value); head=head.next
return out
def run_example(example=EXAMPLE):
head = Node(1, Node(2, Node(3)))
return to_list(singly_linked_lists_p119(head))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Singly linked lists, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Doubly linked lists: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 120, the goal is not memorizing doubly linked lists; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Doubly linked lists is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Doubly linked lists before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
# Page 120: Doubly linked lists
EXAMPLE = {'page': 120, 'topic': 'Doubly linked lists', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'linked_list', 'scenario': 'Run a concrete linked list miniature for Doubly linked lists.', 'sample_input': {'values': [1, 12, 23, 34, 5, 16, 27], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Doubly linked lists', 'watch_for': 'The invariant that makes Doubly linked lists safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linked list example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='120-doubly_linked_list-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class Node:
def __init__(self, value, next=None): self.value, self.next = value, next
def doubly_linked_lists_p120(head):
prev, node = None, head
while node:
nxt = node.next; node.next = prev; prev = node; node = nxt
return prev
def to_list(head):
out=[]
while head: out.append(head.value); head=head.next
return out
def run_example(example=EXAMPLE):
head = Node(1, Node(2, Node(3)))
return to_list(doubly_linked_lists_p120(head))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Doubly linked lists, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Fast and slow pointers: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 121, the goal is not memorizing fast and slow pointers; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Fast and slow pointers is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Fast and slow pointers before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: wrong end operations. Make this risk visible in tests and in code comments.
Common pitfall: Using a structure that supports the right operation at the wrong end can change a linear traversal into a quadratic one.
# Page 121: Fast and slow pointers
EXAMPLE = {'page': 121, 'topic': 'Fast and slow pointers', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'linked_list', 'scenario': 'Run a concrete linked list miniature for Fast and slow pointers.', 'sample_input': {'values': [8, 19, 30, 1, 12, 23, 34], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Fast and slow pointers', 'watch_for': 'The invariant that makes Fast and slow pointers safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linked list example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='121-fast_and_slow_poin-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class Node:
def __init__(self, value, next=None): self.value, self.next = value, next
def fast_and_slow_pointers_p121(head):
prev, node = None, head
while node:
nxt = node.next; node.next = prev; prev = node; node = nxt
return prev
def to_list(head):
out=[]
while head: out.append(head.value); head=head.next
return out
def run_example(example=EXAMPLE):
head = Node(1, Node(2, Node(3)))
return to_list(fast_and_slow_pointers_p121(head))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Fast and slow pointers, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Cycle detection: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 122, the goal is not memorizing cycle detection; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Cycle detection is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Cycle detection before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
# Page 122: Cycle detection
EXAMPLE = {'page': 122, 'topic': 'Cycle detection', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'linked_list', 'scenario': 'Run a concrete linked list miniature for Cycle detection.', 'sample_input': {'values': [15, 26, 37, 8, 19, 30, 1], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Cycle detection', 'watch_for': 'The invariant that makes Cycle detection safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linked list example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='122-cycle_detection-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class Node:
def __init__(self, value, next=None): self.value, self.next = value, next
def cycle_detection_p122(head):
prev, node = None, head
while node:
nxt = node.next; node.next = prev; prev = node; node = nxt
return prev
def to_list(head):
out=[]
while head: out.append(head.value); head=head.next
return out
def run_example(example=EXAMPLE):
head = Node(1, Node(2, Node(3)))
return to_list(cycle_detection_p122(head))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Cycle detection, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Reversing linked lists: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 123, the goal is not memorizing reversing linked lists; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Reversing linked lists is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Reversing linked lists before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
# Page 123: Reversing linked lists
EXAMPLE = {'page': 123, 'topic': 'Reversing linked lists', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'linked_list', 'scenario': 'Run a concrete linked list miniature for Reversing linked lists.', 'sample_input': {'values': [22, 33, 4, 15, 26, 37, 8], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Reversing linked lists', 'watch_for': 'The invariant that makes Reversing linked lists safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linked list example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='123-reversing_linked_l-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class Node:
def __init__(self, value, next=None): self.value, self.next = value, next
def reversing_linked_lists_p123(head):
prev, node = None, head
while node:
nxt = node.next; node.next = prev; prev = node; node = nxt
return prev
def to_list(head):
out=[]
while head: out.append(head.value); head=head.next
return out
def run_example(example=EXAMPLE):
head = Node(1, Node(2, Node(3)))
return to_list(reversing_linked_lists_p123(head))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Reversing linked lists, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Merging linked lists: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 124, the goal is not memorizing merging linked lists; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Merging linked lists is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Merging linked lists before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: wrong end operations. Make this risk visible in tests and in code comments.
Common pitfall: Using a structure that supports the right operation at the wrong end can change a linear traversal into a quadratic one.
# Page 124: Merging linked lists
EXAMPLE = {'page': 124, 'topic': 'Merging linked lists', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'linked_list', 'scenario': 'Run a concrete linked list miniature for Merging linked lists.', 'sample_input': {'values': [29, 40, 11, 22, 33, 4, 15], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Merging linked lists', 'watch_for': 'The invariant that makes Merging linked lists safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linked list example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='124-merging_linked_lis-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class Node:
def __init__(self, value, next=None): self.value, self.next = value, next
def merging_linked_lists_p124(head):
prev, node = None, head
while node:
nxt = node.next; node.next = prev; prev = node; node = nxt
return prev
def to_list(head):
out=[]
while head: out.append(head.value); head=head.next
return out
def run_example(example=EXAMPLE):
head = Node(1, Node(2, Node(3)))
return to_list(merging_linked_lists_p124(head))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Merging linked lists, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for LRU cache with linked lists: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 125, the goal is not memorizing lru cache with linked lists; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: LRU cache with linked lists is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for LRU cache with linked lists before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: wrong end operations. Make this risk visible in tests and in code comments.
Common pitfall: Using a structure that supports the right operation at the wrong end can change a linear traversal into a quadratic one.
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of LRU cache with linked lists, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for When linked lists lose to arrays: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 126, the goal is not memorizing when linked lists lose to arrays; it is recognizing the representation, the safe transition, and the stopping condition inside the Stacks, Queues, Deques, and Linked Lists chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: When linked lists lose to arrays is one small tool in the larger Stacks, Queues, Deques, and Linked Lists toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for When linked lists lose to arrays before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Linear ADTs control the order in which work is processed. Stacks give last-in-first-out behavior, queues give first-in-first-out behavior, and deques support both ends.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: wrong end operations. Make this risk visible in tests and in code comments.
Common pitfall: Using a structure that supports the right operation at the wrong end can change a linear traversal into a quadratic one.
# Page 126: When linked lists lose to arrays
EXAMPLE = {'page': 126, 'topic': 'When linked lists lose to arrays', 'chapter': 'Stacks, Queues, Deques, and Linked Lists', 'kind': 'linked_list', 'scenario': 'Run a concrete linked list miniature for When linked lists lose to arrays.', 'sample_input': {'values': [3, 14, 25, 36, 7, 18, 29], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for When linked lists lose to arrays', 'watch_for': 'The invariant that makes When linked lists lose to arrays safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linked list example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='126-when_linked_lists_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class Node:
def __init__(self, value, next=None): self.value, self.next = value, next
def when_linked_lists_lose_to_arrays_p126(head):
prev, node = None, head
while node:
nxt = node.next; node.next = prev; prev = node; node = nxt
return prev
def to_list(head):
out=[]
while head: out.append(head.value); head=head.next
return out
def run_example(example=EXAMPLE):
head = Node(1, Node(2, Node(3)))
return to_list(when_linked_lists_lose_to_arrays_p126(head))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of When linked lists lose to arrays, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 126 curation harness: When linked lists lose to arrays
EXAMPLE_KIND = "linked_list"
EXAMPLE_TITLE = "When linked lists lose to arrays"
SAMPLE = {
"values": [
3,
14,
25,
36,
7,
18,
29
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "126-when_linked_lists_lo"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "126-when_linked_lists_lo"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "126-when_linked_lists_lo"))
Browser JavaScript companion
// Page 126 browser-side experiment: When linked lists lose to arrays
const pageExample126 = {"values":[3,14,25,36,7,18,29],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"126-when_linked_lists_lo"};
function summarizePage126(sample = pageExample126) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "When linked lists lose to arrays",
kind: "linked_list",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage126());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by When linked lists lose to arrays.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the linked list invariant described in the code comments and return a stable, inspectable result for page 126.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for when linked lists lose to arrays and explain what each one stresses.
Page 127 / 561Chapter 10: Hashing and Hash Tables
Hash function design
Page-local deep read
Mental model for Hash function design: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 127, the goal is not memorizing hash function design; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Hash function design is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Hash function design before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Chapter anchor: This page is the Chapter 10 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Hashing and Hash Tables.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: Hash-table performance depends on the hash distribution and resizing policy, not only on the code that calls it.
The toy hash uses a character-code sum modulo the bucket count. Collisions are chained.
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Hash function design" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Hash function design, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 127 curation harness: Hash function design
EXAMPLE_KIND = "hashing"
EXAMPLE_TITLE = "Hash function design"
SAMPLE = {
"values": [
10,
21,
32,
3,
14,
25,
36
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "127-hash_function_design"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "127-hash_function_design"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "127-hash_function_design"))
Browser JavaScript companion
// Page 127 browser-side experiment: Hash function design
const pageExample127 = {"values":[10,21,32,3,14,25,36],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"127-hash_function_design"};
function summarizePage127(sample = pageExample127) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Hash function design",
kind: "hashing",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage127());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Hash function design.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 127.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for hash function design, then point to the line of code that preserves it.
Page 128 / 561Chapter 10: Hashing and Hash Tables
Chaining
Page-local deep read
Mental model for Chaining: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 128, the goal is not memorizing chaining; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Chaining is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Chaining before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Chaining whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: Hash-table performance depends on the hash distribution and resizing policy, not only on the code that calls it.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Chaining" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Chaining, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Chaining.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 128.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 129 / 561Chapter 10: Hashing and Hash Tables
Open addressing
Page-local deep read
Mental model for Open addressing: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 129, the goal is not memorizing open addressing; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Open addressing is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Open addressing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Open addressing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Open addressing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Open addressing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 129.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 130 / 561Chapter 10: Hashing and Hash Tables
Linear and quadratic probing
Page-local deep read
Mental model for Linear and quadratic probing: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 130, the goal is not memorizing linear and quadratic probing; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Linear and quadratic probing is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Linear and quadratic probing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 130: Linear and quadratic probing
EXAMPLE = {'page': 130, 'topic': 'Linear and quadratic probing', 'chapter': 'Hashing and Hash Tables', 'kind': 'hashing', 'scenario': 'Run a concrete hashing miniature for Linear and quadratic probing.', 'sample_input': {'values': [31, 2, 13, 24, 35, 6, 17], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Linear and quadratic probing', 'watch_for': 'The invariant that makes Linear and quadratic probing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the hashing example changes first.', 'docs': [('Python collections deque/Counter', 'https://docs.python.org/3/library/collections.html')]}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='130-linear_and_quadrat-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def polynomial_hash(text, base=257, mod=1_000_000_007):
h = 0
for ch in text:
h = (h * base + ord(ch)) % mod
return h
def linear_and_quadratic_probing_p130(words):
buckets = {}
for word in words:
buckets.setdefault(polynomial_hash(word) % 7, []).append(word)
return buckets
def run_example(example=EXAMPLE):
return linear_and_quadratic_probing_p130(['ape','pea','algorithm','hash'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Linear and quadratic probing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Linear and quadratic probing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 130 curation harness: Linear and quadratic probing
EXAMPLE_KIND = "hashing"
EXAMPLE_TITLE = "Linear and quadratic probing"
SAMPLE = {
"values": [
31,
2,
13,
24,
35,
6,
17
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "130-linear_and_quadratic"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "130-linear_and_quadratic"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "130-linear_and_quadratic"))
Browser JavaScript companion
// Page 130 browser-side experiment: Linear and quadratic probing
const pageExample130 = {"values":[31,2,13,24,35,6,17],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"130-linear_and_quadratic"};
function summarizePage130(sample = pageExample130) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Linear and quadratic probing",
kind: "hashing",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage130());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Linear and quadratic probing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 130.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement linear and quadratic probing twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 131 / 561Chapter 10: Hashing and Hash Tables
Double hashing
Page-local deep read
Mental model for Double hashing: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 131, the goal is not memorizing double hashing; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Double hashing is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Double hashing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: Hash-table performance depends on the hash distribution and resizing policy, not only on the code that calls it.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Double hashing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Double hashing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Double hashing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 131.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for double hashing and explain what each one stresses.
Page 132 / 561Chapter 10: Hashing and Hash Tables
Load factor and resizing
Page-local deep read
Mental model for Load factor and resizing: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 132, the goal is not memorizing load factor and resizing; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Load factor and resizing is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Load factor and resizing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Load factor and resizing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Load factor and resizing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 132 curation harness: Load factor and resizing
EXAMPLE_KIND = "hashing"
EXAMPLE_TITLE = "Load factor and resizing"
SAMPLE = {
"values": [
5,
16,
27,
38,
9,
20,
31
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "132-load_factor_and_resi"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "132-load_factor_and_resi"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "132-load_factor_and_resi"))
Browser JavaScript companion
// Page 132 browser-side experiment: Load factor and resizing
const pageExample132 = {"values":[5,16,27,38,9,20,31],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"132-load_factor_and_resi"};
function summarizePage132(sample = pageExample132) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Load factor and resizing",
kind: "hashing",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage132());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Load factor and resizing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 132.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for load factor and resizing, then point to the line of code that preserves it.
Page 133 / 561Chapter 10: Hashing and Hash Tables
Universal hashing
Page-local deep read
Mental model for Universal hashing: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 133, the goal is not memorizing universal hashing; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Universal hashing is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Universal hashing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Universal hashing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Universal hashing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Universal hashing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 133.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 134 / 561Chapter 10: Hashing and Hash Tables
String hashing
Page-local deep read
Mental model for String hashing: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 134, the goal is not memorizing string hashing; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: String hashing is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for String hashing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: Hash-table performance depends on the hash distribution and resizing policy, not only on the code that calls it.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "String hashing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of String hashing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by String hashing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 134.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 135 / 561Chapter 10: Hashing and Hash Tables
Rolling hashes
Page-local deep read
Mental model for Rolling hashes: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 135, the goal is not memorizing rolling hashes; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rolling hashes is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rolling hashes before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: Hash-table performance depends on the hash distribution and resizing policy, not only on the code that calls it.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Rolling hashes" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Rolling hashes, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Rolling hashes.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 135.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement rolling hashes twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 136 / 561Chapter 10: Hashing and Hash Tables
Hash sets for membership
Page-local deep read
Mental model for Hash sets for membership: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 136, the goal is not memorizing hash sets for membership; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Hash sets for membership is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Hash sets for membership before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: Hash-table performance depends on the hash distribution and resizing policy, not only on the code that calls it.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Hash sets for membership" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Hash sets for membership, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 136 curation harness: Hash sets for membership
EXAMPLE_KIND = "hashing"
EXAMPLE_TITLE = "Hash sets for membership"
SAMPLE = {
"values": [
33,
4,
15,
26,
37,
8,
19
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "136-hash_sets_for_member"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "136-hash_sets_for_member"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "136-hash_sets_for_member"))
Browser JavaScript companion
// Page 136 browser-side experiment: Hash sets for membership
const pageExample136 = {"values":[33,4,15,26,37,8,19],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"136-hash_sets_for_member"};
function summarizePage136(sample = pageExample136) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Hash sets for membership",
kind: "hashing",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage136());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Hash sets for membership.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 136.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for hash sets for membership and explain what each one stresses.
Page 137 / 561Chapter 10: Hashing and Hash Tables
Hash maps for counting
Page-local deep read
Mental model for Hash maps for counting: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 137, the goal is not memorizing hash maps for counting; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Hash maps for counting is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Hash maps for counting before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: Hash-table performance depends on the hash distribution and resizing policy, not only on the code that calls it.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Hash maps for counting" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Hash maps for counting, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 137 curation harness: Hash maps for counting
EXAMPLE_KIND = "hashing"
EXAMPLE_TITLE = "Hash maps for counting"
SAMPLE = {
"values": [
40,
11,
22,
33,
4,
15,
26
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "137-hash_maps_for_counti"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "137-hash_maps_for_counti"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "137-hash_maps_for_counti"))
Browser JavaScript companion
// Page 137 browser-side experiment: Hash maps for counting
const pageExample137 = {"values":[40,11,22,33,4,15,26],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"137-hash_maps_for_counti"};
function summarizePage137(sample = pageExample137) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Hash maps for counting",
kind: "hashing",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage137());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Hash maps for counting.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 137.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for hash maps for counting, then point to the line of code that preserves it.
Page 138 / 561Chapter 10: Hashing and Hash Tables
Bloom filters
Page-local deep read
Mental model for Bloom filters: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 138, the goal is not memorizing bloom filters; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bloom filters is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bloom filters before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Bloom filters whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: Hash-table performance depends on the hash distribution and resizing policy, not only on the code that calls it.
# Page 138: Bloom filters
EXAMPLE = {'page': 138, 'topic': 'Bloom filters', 'chapter': 'Hashing and Hash Tables', 'kind': 'bloom_filter', 'scenario': 'Run a concrete bloom filter miniature for Bloom filters.', 'sample_input': {'values': [7, 18, 29, 40, 11, 22, 33], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Bloom filters', 'watch_for': 'The invariant that makes Bloom filters safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the bloom filter example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='138-bloom_filters-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def hashes(item, size):
return [hash((item, salt)) % size for salt in (17, 31, 47)]
def bloom_filters_p138(items, queries, size=32):
bits = [0] * size
for item in items:
for h in hashes(item, size): bits[h] = 1
return {q: all(bits[h] for h in hashes(q, size)) for q in queries}
def run_example(example=EXAMPLE):
return bloom_filters_p138(['red','blue','green'], ['red','cyan'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Bloom filters, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Bloom filters.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the bloom filter invariant described in the code comments and return a stable, inspectable result for page 138.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 139 / 561Chapter 10: Hashing and Hash Tables
Collision attacks and robustness
Page-local deep read
Mental model for Collision attacks and robustness: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 139, the goal is not memorizing collision attacks and robustness; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Collision attacks and robustness is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Collision attacks and robustness before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Collision attacks and robustness" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Collision attacks and robustness, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 139 curation harness: Collision attacks and robustness
EXAMPLE_KIND = "hashing"
EXAMPLE_TITLE = "Collision attacks and robustness"
SAMPLE = {
"values": [
14,
25,
36,
7,
18,
29,
40
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "139-collision_attacks_an"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "139-collision_attacks_an"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "139-collision_attacks_an"))
Browser JavaScript companion
// Page 139 browser-side experiment: Collision attacks and robustness
const pageExample139 = {"values":[14,25,36,7,18,29,40],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"139-collision_attacks_an"};
function summarizePage139(sample = pageExample139) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Collision attacks and robustness",
kind: "hashing",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage139());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Collision attacks and robustness.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 139.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 140 / 561Chapter 10: Hashing and Hash Tables
Hash-table debugging
Page-local deep read
Mental model for Hash-table debugging: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 140, the goal is not memorizing hash-table debugging; it is recognizing the representation, the safe transition, and the stopping condition inside the Hashing and Hash Tables chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Hash-table debugging is one small tool in the larger Hashing and Hash Tables toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Hash-table debugging before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Hash-table debugging" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Hash-table debugging, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Hash-table debugging.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 140.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement hash-table debugging twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 141 / 561Chapter 11: Trees and Traversals
Tree vocabulary
Page-local deep read
Mental model for Tree vocabulary: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 141, the goal is not memorizing tree vocabulary; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Tree vocabulary is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Tree vocabulary before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
This is a chapter-level anchor example. Read it alongside the page-specific labs lower down.
class Node:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def preorder(root):
if not root:
return []
out, stack = [], [root]
while stack:
node = stack.pop()
out.append(node.value)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return out
tree = Node(2, Node(1), Node(4, Node(3), Node(5)))
print(preorder(tree))
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 11: Trees and Traversals
function preorder(root) {
if (!root) return [];
const out = [], stack = [root];
while (stack.length) { const n = stack.pop(); out.push(n.v); if (n.r) stack.push(n.r); if (n.l) stack.push(n.l); }
return out;
}
console.log(preorder({v:2,l:{v:1},r:{v:3}}));
Chapter anchor: This page is the Chapter 11 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Trees and Traversals.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 141: Tree vocabulary
EXAMPLE = {'page': 141, 'topic': 'Tree vocabulary', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Tree vocabulary.', 'sample_input': {'values': [28, 39, 10, 21, 32, 3, 14], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Tree vocabulary', 'watch_for': 'The invariant that makes Tree vocabulary safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='141-tree_vocabulary-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def tree_vocabulary_p141(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return tree_vocabulary_p141(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Tree vocabulary" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Tree vocabulary.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 141.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for tree vocabulary and explain what each one stresses.
Page 142 / 561Chapter 11: Trees and Traversals
Rooted trees
Page-local deep read
Mental model for Rooted trees: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 142, the goal is not memorizing rooted trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rooted trees is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rooted trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 142: Rooted trees
EXAMPLE = {'page': 142, 'topic': 'Rooted trees', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Rooted trees.', 'sample_input': {'values': [35, 6, 17, 28, 39, 10, 21], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Rooted trees', 'watch_for': 'The invariant that makes Rooted trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='142-rooted_trees-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def rooted_trees_p142(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return rooted_trees_p142(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Rooted trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Rooted trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 142.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for rooted trees, then point to the line of code that preserves it.
Page 143 / 561Chapter 11: Trees and Traversals
DFS preorder/inorder/postorder
Page-local deep read
Mental model for DFS preorder/inorder/postorder: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 143, the goal is not memorizing dfs preorder/inorder/postorder; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DFS preorder/inorder/postorder is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DFS preorder/inorder/postorder before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 143: DFS preorder/inorder/postorder
EXAMPLE = {'page': 143, 'topic': 'DFS preorder/inorder/postorder', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for DFS preorder/inorder/postorder.', 'sample_input': {'values': [2, 13, 24, 35, 6, 17, 28], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for DFS preorder/inorder/postorder', 'watch_for': 'The invariant that makes DFS preorder/inorder/postorder safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='143-dfs_preorder_inord-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def dfs_preorder_inorder_postorder_p143(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return dfs_preorder_inorder_postorder_p143(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "DFS preorder/inorder/postorder" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by DFS preorder/inorder/postorder.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 143.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 144 / 561Chapter 11: Trees and Traversals
Level-order traversal
Page-local deep read
Mental model for Level-order traversal: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 144, the goal is not memorizing level-order traversal; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Level-order traversal is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Level-order traversal before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 144: Level-order traversal
EXAMPLE = {'page': 144, 'topic': 'Level-order traversal', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Level-order traversal.', 'sample_input': {'values': [9, 20, 31, 2, 13, 24, 35], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Level-order traversal', 'watch_for': 'The invariant that makes Level-order traversal safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='144-level_order_traver-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def level_order_traversal_p144(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return level_order_traversal_p144(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Level-order traversal" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Level-order traversal.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 144.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 145 / 561Chapter 11: Trees and Traversals
Euler tours
Page-local deep read
Mental model for Euler tours: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 145, the goal is not memorizing euler tours; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Euler tours is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Euler tours before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 145: Euler tours
EXAMPLE = {'page': 145, 'topic': 'Euler tours', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Euler tours.', 'sample_input': {'values': [16, 27, 38, 9, 20, 31, 2], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Euler tours', 'watch_for': 'The invariant that makes Euler tours safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='145-euler_tours-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def euler_tours_p145(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return euler_tours_p145(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Euler tours" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Euler tours.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 145.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement euler tours twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 146 / 561Chapter 11: Trees and Traversals
Subtree aggregation
Page-local deep read
Mental model for Subtree aggregation: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 146, the goal is not memorizing subtree aggregation; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Subtree aggregation is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Subtree aggregation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 146: Subtree aggregation
EXAMPLE = {'page': 146, 'topic': 'Subtree aggregation', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Subtree aggregation.', 'sample_input': {'values': [23, 34, 5, 16, 27, 38, 9], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Subtree aggregation', 'watch_for': 'The invariant that makes Subtree aggregation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='146-subtree_aggregatio-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def subtree_aggregation_p146(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return subtree_aggregation_p146(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Subtree aggregation" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Subtree aggregation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 146.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for subtree aggregation and explain what each one stresses.
Page 147 / 561Chapter 11: Trees and Traversals
Tree height and diameter
Page-local deep read
Mental model for Tree height and diameter: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 147, the goal is not memorizing tree height and diameter; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Tree height and diameter is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Tree height and diameter before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 147: Tree height and diameter
EXAMPLE = {'page': 147, 'topic': 'Tree height and diameter', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Tree height and diameter.', 'sample_input': {'values': [30, 1, 12, 23, 34, 5, 16], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Tree height and diameter', 'watch_for': 'The invariant that makes Tree height and diameter safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='147-tree_height_and_di-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def tree_height_and_diameter_p147(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return tree_height_and_diameter_p147(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Tree height and diameter" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 147 curation harness: Tree height and diameter
EXAMPLE_KIND = "tree_alg"
EXAMPLE_TITLE = "Tree height and diameter"
SAMPLE = {
"values": [
30,
1,
12,
23,
34,
5,
16
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "147-tree_height_and_diam"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "147-tree_height_and_diam"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "147-tree_height_and_diam"))
Browser JavaScript companion
// Page 147 browser-side experiment: Tree height and diameter
const pageExample147 = {"values":[30,1,12,23,34,5,16],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"147-tree_height_and_diam"};
function summarizePage147(sample = pageExample147) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Tree height and diameter",
kind: "tree_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage147());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Tree height and diameter.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 147.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for tree height and diameter, then point to the line of code that preserves it.
Page 148 / 561Chapter 11: Trees and Traversals
Lowest common ancestor basics
Page-local deep read
Mental model for Lowest common ancestor basics: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 148, the goal is not memorizing lowest common ancestor basics; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Lowest common ancestor basics is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Lowest common ancestor basics before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Lowest common ancestor basics whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 148: Lowest common ancestor basics
EXAMPLE = {'page': 148, 'topic': 'Lowest common ancestor basics', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Lowest common ancestor basics.', 'sample_input': {'values': [37, 8, 19, 30, 1, 12, 23], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Lowest common ancestor basics', 'watch_for': 'The invariant that makes Lowest common ancestor basics safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='148-lowest_common_ance-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def lowest_common_ancestor_basics_p148(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return lowest_common_ancestor_basics_p148(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Lowest common ancestor basics" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 148 curation harness: Lowest common ancestor basics
EXAMPLE_KIND = "tree_alg"
EXAMPLE_TITLE = "Lowest common ancestor basics"
SAMPLE = {
"values": [
37,
8,
19,
30,
1,
12,
23
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "148-lowest_common_ancest"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "148-lowest_common_ancest"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "148-lowest_common_ancest"))
Browser JavaScript companion
// Page 148 browser-side experiment: Lowest common ancestor basics
const pageExample148 = {"values":[37,8,19,30,1,12,23],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"148-lowest_common_ancest"};
function summarizePage148(sample = pageExample148) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Lowest common ancestor basics",
kind: "tree_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage148());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Lowest common ancestor basics.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 148.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 149 / 561Chapter 11: Trees and Traversals
Binary lifting
Page-local deep read
Mental model for Binary lifting: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 149, the goal is not memorizing binary lifting; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Binary lifting is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Binary lifting before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 149: Binary lifting
EXAMPLE = {'page': 149, 'topic': 'Binary lifting', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Binary lifting.', 'sample_input': {'values': [4, 15, 26, 37, 8, 19, 30], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Binary lifting', 'watch_for': 'The invariant that makes Binary lifting safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='149-binary_lifting-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def binary_lifting_p149(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return binary_lifting_p149(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Binary lifting" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Binary lifting.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 149.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 150 / 561Chapter 11: Trees and Traversals
Heavy-light intuition
Page-local deep read
Mental model for Heavy-light intuition: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 150, the goal is not memorizing heavy-light intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Heavy-light intuition is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Heavy-light intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 150: Heavy-light intuition
EXAMPLE = {'page': 150, 'topic': 'Heavy-light intuition', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Heavy-light intuition.', 'sample_input': {'values': [11, 22, 33, 4, 15, 26, 37], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Heavy-light intuition', 'watch_for': 'The invariant that makes Heavy-light intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='150-heavy_light_intuit-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def heavy_light_intuition_p150(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return heavy_light_intuition_p150(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Heavy-light intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Heavy-light intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 150.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement heavy-light intuition twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 151 / 561Chapter 11: Trees and Traversals
Segment trees
Page-local deep read
Mental model for Segment trees: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 151, the goal is not memorizing segment trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Segment trees is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Segment trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 151: Segment trees
EXAMPLE = {'page': 151, 'topic': 'Segment trees', 'chapter': 'Trees and Traversals', 'kind': 'segment_tree', 'scenario': 'Run a concrete segment tree miniature for Segment trees.', 'sample_input': {'values': [18, 29, 40, 11, 22, 33, 4], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Segment trees', 'watch_for': 'The invariant that makes Segment trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the segment tree example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='151-segment_trees-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def build_segment_tree(values):
n = 1
while n < len(values): n *= 2
tree = [0] * (2*n)
tree[n:n+len(values)] = values
for i in range(n-1, 0, -1): tree[i] = tree[2*i] + tree[2*i+1]
return tree, n
def segment_trees_p151(values, left, right):
tree, n = build_segment_tree(values); left += n; right += n; total = 0
while left < right:
if left % 2: total += tree[left]; left += 1
if right % 2: right -= 1; total += tree[right]
left //= 2; right //= 2
return total
def run_example(example=EXAMPLE):
values = example['sample_input']['values']
return segment_trees_p151(values, 1, min(5, len(values)))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Segment trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Segment trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the segment tree invariant described in the code comments and return a stable, inspectable result for page 151.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for segment trees and explain what each one stresses.
Page 152 / 561Chapter 11: Trees and Traversals
Fenwick trees
Page-local deep read
Mental model for Fenwick trees: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 152, the goal is not memorizing fenwick trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Fenwick trees is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Fenwick trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 152: Fenwick trees
EXAMPLE = {'page': 152, 'topic': 'Fenwick trees', 'chapter': 'Trees and Traversals', 'kind': 'fenwick_tree', 'scenario': 'Run a concrete fenwick tree miniature for Fenwick trees.', 'sample_input': {'values': [25, 36, 7, 18, 29, 40, 11], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Fenwick trees', 'watch_for': 'The invariant that makes Fenwick trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the fenwick tree example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='152-fenwick_trees-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def add(bit, index, delta):
while index < len(bit):
bit[index] += delta; index += index & -index
def prefix(bit, index):
total = 0
while index > 0:
total += bit[index]; index -= index & -index
return total
def fenwick_trees_p152(values):
bit = [0] * (len(values) + 1)
for i, value in enumerate(values, 1): add(bit, i, value)
return [prefix(bit, i) for i in range(1, len(values)+1)]
def run_example(example=EXAMPLE):
return fenwick_trees_p152(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Fenwick trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Fenwick trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the fenwick tree invariant described in the code comments and return a stable, inspectable result for page 152.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for fenwick trees, then point to the line of code that preserves it.
Page 153 / 561Chapter 11: Trees and Traversals
Lazy propagation
Page-local deep read
Mental model for Lazy propagation: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 153, the goal is not memorizing lazy propagation; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Lazy propagation is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Lazy propagation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 153: Lazy propagation
EXAMPLE = {'page': 153, 'topic': 'Lazy propagation', 'chapter': 'Trees and Traversals', 'kind': 'segment_tree', 'scenario': 'Run a concrete segment tree miniature for Lazy propagation.', 'sample_input': {'values': [32, 3, 14, 25, 36, 7, 18], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Lazy propagation', 'watch_for': 'The invariant that makes Lazy propagation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the segment tree example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='153-lazy_propagation-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def build_segment_tree(values):
n = 1
while n < len(values): n *= 2
tree = [0] * (2*n)
tree[n:n+len(values)] = values
for i in range(n-1, 0, -1): tree[i] = tree[2*i] + tree[2*i+1]
return tree, n
def lazy_propagation_p153(values, left, right):
tree, n = build_segment_tree(values); left += n; right += n; total = 0
while left < right:
if left % 2: total += tree[left]; left += 1
if right % 2: right -= 1; total += tree[right]
left //= 2; right //= 2
return total
def run_example(example=EXAMPLE):
values = example['sample_input']['values']
return lazy_propagation_p153(values, 1, min(5, len(values)))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Lazy propagation" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Lazy propagation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the segment tree invariant described in the code comments and return a stable, inspectable result for page 153.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 154 / 561Chapter 11: Trees and Traversals
Persistent segment trees
Page-local deep read
Mental model for Persistent segment trees: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 154, the goal is not memorizing persistent segment trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Persistent segment trees is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Persistent segment trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 154: Persistent segment trees
EXAMPLE = {'page': 154, 'topic': 'Persistent segment trees', 'chapter': 'Trees and Traversals', 'kind': 'persistent_segment_tree', 'scenario': 'Run a concrete persistent segment tree miniature for Persistent segment trees.', 'sample_input': {'values': [39, 10, 21, 32, 3, 14, 25], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Persistent segment trees', 'watch_for': 'The invariant that makes Persistent segment trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the persistent segment tree example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='154-persistent_segment-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def persistent_segment_trees_p154(values, index, new_value):
new_values = list(values)
old_value = new_values[index]
new_values[index] = new_value
return {'old_version': list(values), 'new_version': new_values, 'delta': new_value - old_value}
def run_example(example=EXAMPLE):
values = example['sample_input']['values']
return persistent_segment_trees_p154(values, 2, values[2] + 10)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Persistent segment trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Persistent segment trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the persistent segment tree invariant described in the code comments and return a stable, inspectable result for page 154.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 155 / 561Chapter 11: Trees and Traversals
Tries as trees
Page-local deep read
Mental model for Tries as trees: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 155, the goal is not memorizing tries as trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Tries as trees is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Tries as trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 155: Tries as trees
EXAMPLE = {'page': 155, 'topic': 'Tries as trees', 'chapter': 'Trees and Traversals', 'kind': 'trie', 'scenario': 'Run a concrete trie miniature for Tries as trees.', 'sample_input': {'values': [6, 17, 28, 39, 10, 21, 32], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Tries as trees', 'watch_for': 'The invariant that makes Tries as trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trie example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='155-tries_as_trees-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def tries_as_trees_p155(words):
root = {}
END = '_end'
for word in words:
node = root
for ch in word: node = node.setdefault(ch, {})
node[END] = True
return root
def contains(root, word):
node = root
for ch in word:
if ch not in node: return False
node = node[ch]
return bool(node.get('_end'))
def run_example(example=EXAMPLE):
trie = tries_as_trees_p155(['algo','all','also','tree'])
return contains(trie, 'also'), contains(trie, 'ask')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Tries as trees, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 155 curation harness: Tries as trees
EXAMPLE_KIND = "trie"
EXAMPLE_TITLE = "Tries as trees"
SAMPLE = {
"values": [
6,
17,
28,
39,
10,
21,
32
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "155-tries_as_trees"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "155-tries_as_trees"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "155-tries_as_trees"))
Browser JavaScript companion
// Page 155 browser-side experiment: Tries as trees
const pageExample155 = {"values":[6,17,28,39,10,21,32],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"155-tries_as_trees"};
function summarizePage155(sample = pageExample155) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Tries as trees",
kind: "trie",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage155());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Tries as trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trie invariant described in the code comments and return a stable, inspectable result for page 155.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement tries as trees twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 156 / 561Chapter 11: Trees and Traversals
Expression trees
Page-local deep read
Mental model for Expression trees: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 156, the goal is not memorizing expression trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Expression trees is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Expression trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 156: Expression trees
EXAMPLE = {'page': 156, 'topic': 'Expression trees', 'chapter': 'Trees and Traversals', 'kind': 'expression_stack', 'scenario': 'Run a concrete expression stack miniature for Expression trees.', 'sample_input': {'values': [13, 24, 35, 6, 17, 28, 39], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Expression trees', 'watch_for': 'The invariant that makes Expression trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the expression stack example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='156-expression_trees-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def expression_trees_p156(tokens):
stack = []
for token in tokens:
if token.isdigit(): stack.append(int(token)); continue
b, a = stack.pop(), stack.pop()
stack.append(a + b if token == '+' else a * b)
return stack[-1]
def run_example(example=EXAMPLE):
return expression_trees_p156(['2','3','+','4','*'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Expression trees, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Expression trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the expression stack invariant described in the code comments and return a stable, inspectable result for page 156.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for expression trees and explain what each one stresses.
Page 157 / 561Chapter 11: Trees and Traversals
Tree serialization
Page-local deep read
Mental model for Tree serialization: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 157, the goal is not memorizing tree serialization; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Tree serialization is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Tree serialization before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 157: Tree serialization
EXAMPLE = {'page': 157, 'topic': 'Tree serialization', 'chapter': 'Trees and Traversals', 'kind': 'tree_serialization', 'scenario': 'Run a concrete tree serialization miniature for Tree serialization.', 'sample_input': {'values': [20, 31, 2, 13, 24, 35, 6], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Tree serialization', 'watch_for': 'The invariant that makes Tree serialization safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree serialization example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='157-tree_serialization-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def tree_serialization_p157(tree, root):
out = []
def dfs(node):
out.append(node)
children = tree.get(node, [])
out.append(len(children))
for child in children: dfs(child)
dfs(root); return out
def run_example(example=EXAMPLE):
return tree_serialization_p157(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Tree serialization" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Tree serialization.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree serialization invariant described in the code comments and return a stable, inspectable result for page 157.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for tree serialization, then point to the line of code that preserves it.
Page 158 / 561Chapter 11: Trees and Traversals
Rerooting patterns
Page-local deep read
Mental model for Rerooting patterns: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 158, the goal is not memorizing rerooting patterns; it is recognizing the representation, the safe transition, and the stopping condition inside the Trees and Traversals chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rerooting patterns is one small tool in the larger Trees and Traversals toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rerooting patterns before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Rerooting patterns whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: unbalanced height. Make this risk visible in tests and in code comments.
Common pitfall: Confusing node count n with height h leads to wrong bounds for recursive tree operations.
# Page 158: Rerooting patterns
EXAMPLE = {'page': 158, 'topic': 'Rerooting patterns', 'chapter': 'Trees and Traversals', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Rerooting patterns.', 'sample_input': {'values': [27, 38, 9, 20, 31, 2, 13], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Rerooting patterns', 'watch_for': 'The invariant that makes Rerooting patterns safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='158-rerooting_patterns-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def rerooting_patterns_p158(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return rerooting_patterns_p158(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Rerooting patterns" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Rerooting patterns.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 158.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 159 / 561Chapter 12: Binary Search Trees and Balanced Trees
BST invariant
Page-local deep read
Mental model for BST invariant: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 159, the goal is not memorizing bst invariant; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: BST invariant is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for BST invariant before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
This is a chapter-level anchor example. Read it alongside the page-specific labs lower down.
class MinHeap:
def __init__(self):
self.data = []
def push(self, value: int) -> None:
self.data.append(value)
i = len(self.data) - 1
while i > 0:
p = (i - 1) // 2
if self.data[p] <= self.data[i]:
break
self.data[p], self.data[i] = self.data[i], self.data[p]
i = p
def pop(self) -> int:
if not self.data:
raise IndexError('empty heap')
self.data[0], self.data[-1] = self.data[-1], self.data[0]
value = self.data.pop()
i = 0
while True:
left = 2 * i + 1
right = left + 1
smallest = i
if left < len(self.data) and self.data[left] < self.data[smallest]:
smallest = left
if right < len(self.data) and self.data[right] < self.data[smallest]:
smallest = right
if smallest == i:
break
self.data[i], self.data[smallest] = self.data[smallest], self.data[i]
i = smallest
return value
heap = MinHeap()
for x in [7, 3, 9, 1, 4]:
heap.push(x)
print([heap.pop() for _ in range(5)])
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 12: Binary Search Trees and Balanced Trees
class BST {
constructor(key) { this.key = key; this.left = null; this.right = null; }
insert(key) { if (key < this.key) this.left ? this.left.insert(key) : this.left = new BST(key); else if (key > this.key) this.right ? this.right.insert(key) : this.right = new BST(key); }
has(key) { return key === this.key || (key < this.key ? !!this.left?.has(key) : !!this.right?.has(key)); }
}
const t = new BST(8); [3,10,1,6].forEach(x => t.insert(x)); console.log(t.has(6));
Chapter anchor: This page is the Chapter 12 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Binary Search Trees and Balanced Trees.
# Page 159: BST invariant
EXAMPLE = {'page': 159, 'topic': 'BST invariant', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for BST invariant.', 'sample_input': {'values': [34, 5, 16, 27, 38, 9, 20], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for BST invariant', 'watch_for': 'The invariant that makes BST invariant safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='159-bst_invariant-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def bst_invariant_p159(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return bst_invariant_p159(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "BST invariant" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by BST invariant.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 159.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 160 / 561Chapter 12: Binary Search Trees and Balanced Trees
BST search, insert, delete
Page-local deep read
Mental model for BST search, insert, delete: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 160, the goal is not memorizing bst search, insert, delete; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: BST search, insert, delete is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for BST search, insert, delete before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 160: BST search, insert, delete
EXAMPLE = {'page': 160, 'topic': 'BST search, insert, delete', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for BST search, insert, delete.', 'sample_input': {'values': [1, 12, 23, 34, 5, 16, 27], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for BST search, insert, delete', 'watch_for': 'The invariant that makes BST search, insert, delete safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='160-bst_search_insert_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def bst_search_insert_delete_p160(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return bst_search_insert_delete_p160(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "BST search, insert, delete" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by BST search, insert, delete.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 160.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement bst search, insert, delete twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 161 / 561Chapter 12: Binary Search Trees and Balanced Trees
Successor and predecessor
Page-local deep read
Mental model for Successor and predecessor: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 161, the goal is not memorizing successor and predecessor; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Successor and predecessor is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Successor and predecessor before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: A plain BST can become a linked list if keys arrive in sorted order.
# Page 161: Successor and predecessor
EXAMPLE = {'page': 161, 'topic': 'Successor and predecessor', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Successor and predecessor.', 'sample_input': {'values': [8, 19, 30, 1, 12, 23, 34], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Successor and predecessor', 'watch_for': 'The invariant that makes Successor and predecessor safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='161-successor_and_pred-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def successor_and_predecessor_p161(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return successor_and_predecessor_p161(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Successor and predecessor" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 161 curation harness: Successor and predecessor
EXAMPLE_KIND = "tree_alg"
EXAMPLE_TITLE = "Successor and predecessor"
SAMPLE = {
"values": [
8,
19,
30,
1,
12,
23,
34
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "161-successor_and_predec"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "161-successor_and_predec"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "161-successor_and_predec"))
Browser JavaScript companion
// Page 161 browser-side experiment: Successor and predecessor
const pageExample161 = {"values":[8,19,30,1,12,23,34],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"161-successor_and_predec"};
function summarizePage161(sample = pageExample161) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Successor and predecessor",
kind: "tree_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage161());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Successor and predecessor.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 161.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for successor and predecessor and explain what each one stresses.
Page 162 / 561Chapter 12: Binary Search Trees and Balanced Trees
AVL rotations
Page-local deep read
Mental model for AVL rotations: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 162, the goal is not memorizing avl rotations; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: AVL rotations is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for AVL rotations before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 162: AVL rotations
EXAMPLE = {'page': 162, 'topic': 'AVL rotations', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'rotate_array', 'scenario': 'Run a concrete rotate array miniature for AVL rotations.', 'sample_input': {'values': [15, 26, 37, 8, 19, 30, 1], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for AVL rotations', 'watch_for': 'The invariant that makes AVL rotations safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the rotate array example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='162-avl_rotations-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def reverse(values, left, right):
while left < right:
values[left], values[right] = values[right], values[left]
left += 1; right -= 1
def avl_rotations_p162(values, k):
values = list(values); n = len(values); k %= n or 1
reverse(values, 0, n-1); reverse(values, 0, k-1); reverse(values, k, n-1)
return values
def run_example(example=EXAMPLE):
return avl_rotations_p162(example['sample_input']['values'], 3)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by AVL rotations.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the rotate array invariant described in the code comments and return a stable, inspectable result for page 162.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for avl rotations, then point to the line of code that preserves it.
Page 163 / 561Chapter 12: Binary Search Trees and Balanced Trees
Red-black tree intuition
Page-local deep read
Mental model for Red-black tree intuition: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 163, the goal is not memorizing red-black tree intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Red-black tree intuition is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Red-black tree intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 163: Red-black tree intuition
EXAMPLE = {'page': 163, 'topic': 'Red-black tree intuition', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Red-black tree intuition.', 'sample_input': {'values': [22, 33, 4, 15, 26, 37, 8], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Red-black tree intuition', 'watch_for': 'The invariant that makes Red-black tree intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='163-red_black_tree_int-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def red_black_tree_intuition_p163(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return red_black_tree_intuition_p163(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Red-black tree intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 163 curation harness: Red-black tree intuition
EXAMPLE_KIND = "tree_alg"
EXAMPLE_TITLE = "Red-black tree intuition"
SAMPLE = {
"values": [
22,
33,
4,
15,
26,
37,
8
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "163-red_black_tree_intui"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "163-red_black_tree_intui"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "163-red_black_tree_intui"))
Browser JavaScript companion
// Page 163 browser-side experiment: Red-black tree intuition
const pageExample163 = {"values":[22,33,4,15,26,37,8],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"163-red_black_tree_intui"};
function summarizePage163(sample = pageExample163) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Red-black tree intuition",
kind: "tree_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage163());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Red-black tree intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 163.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 164 / 561Chapter 12: Binary Search Trees and Balanced Trees
Treaps
Page-local deep read
Mental model for Treaps: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 164, the goal is not memorizing treaps; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Treaps is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Treaps before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: A plain BST can become a linked list if keys arrive in sorted order.
# Page 164: Treaps
EXAMPLE = {'page': 164, 'topic': 'Treaps', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Treaps.', 'sample_input': {'values': [29, 40, 11, 22, 33, 4, 15], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Treaps', 'watch_for': 'The invariant that makes Treaps safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='164-treaps-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def treaps_p164(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return treaps_p164(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Treaps" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Treaps.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 164.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 165 / 561Chapter 12: Binary Search Trees and Balanced Trees
Splay trees
Page-local deep read
Mental model for Splay trees: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 165, the goal is not memorizing splay trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Splay trees is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Splay trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: A plain BST can become a linked list if keys arrive in sorted order.
# Page 165: Splay trees
EXAMPLE = {'page': 165, 'topic': 'Splay trees', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Splay trees.', 'sample_input': {'values': [36, 7, 18, 29, 40, 11, 22], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Splay trees', 'watch_for': 'The invariant that makes Splay trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='165-splay_trees-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def splay_trees_p165(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return splay_trees_p165(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Splay trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Splay trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 165.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement splay trees twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 166 / 561Chapter 12: Binary Search Trees and Balanced Trees
B-trees and cache blocks
Page-local deep read
Mental model for B-trees and cache blocks: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 166, the goal is not memorizing b-trees and cache blocks; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: B-trees and cache blocks is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for B-trees and cache blocks before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: A plain BST can become a linked list if keys arrive in sorted order.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "B-trees and cache blocks" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 166 curation harness: B-trees and cache blocks
EXAMPLE_KIND = "tree_alg"
EXAMPLE_TITLE = "B-trees and cache blocks"
SAMPLE = {
"values": [
3,
14,
25,
36,
7,
18,
29
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "166-b_trees_and_cache_bl"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "166-b_trees_and_cache_bl"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "166-b_trees_and_cache_bl"))
Browser JavaScript companion
// Page 166 browser-side experiment: B-trees and cache blocks
const pageExample166 = {"values":[3,14,25,36,7,18,29],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"166-b_trees_and_cache_bl"};
function summarizePage166(sample = pageExample166) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "B-trees and cache blocks",
kind: "tree_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage166());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by B-trees and cache blocks.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 166.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for b-trees and cache blocks and explain what each one stresses.
Page 167 / 561Chapter 12: Binary Search Trees and Balanced Trees
Order-statistics trees
Page-local deep read
Mental model for Order-statistics trees: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 167, the goal is not memorizing order-statistics trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Order-statistics trees is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Order-statistics trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: A plain BST can become a linked list if keys arrive in sorted order.
# Page 167: Order-statistics trees
EXAMPLE = {'page': 167, 'topic': 'Order-statistics trees', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Order-statistics trees.', 'sample_input': {'values': [10, 21, 32, 3, 14, 25, 36], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Order-statistics trees', 'watch_for': 'The invariant that makes Order-statistics trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='167-order_statistics_t-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def order_statistics_trees_p167(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return order_statistics_trees_p167(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Order-statistics trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Order-statistics trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 167.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for order-statistics trees, then point to the line of code that preserves it.
Page 168 / 561Chapter 12: Binary Search Trees and Balanced Trees
Interval trees
Page-local deep read
Mental model for Interval trees: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 168, the goal is not memorizing interval trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Interval trees is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Interval trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Interval trees whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: A plain BST can become a linked list if keys arrive in sorted order.
# Page 168: Interval trees
EXAMPLE = {'page': 168, 'topic': 'Interval trees', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Interval trees.', 'sample_input': {'values': [17, 28, 39, 10, 21, 32, 3], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Interval trees', 'watch_for': 'The invariant that makes Interval trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='168-interval_trees-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def interval_trees_p168(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return interval_trees_p168(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Interval trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Interval trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 168.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 169 / 561Chapter 12: Binary Search Trees and Balanced Trees
Range queries with trees
Page-local deep read
Mental model for Range queries with trees: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 169, the goal is not memorizing range queries with trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Range queries with trees is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Range queries with trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 169: Range queries with trees
EXAMPLE = {'page': 169, 'topic': 'Range queries with trees', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Range queries with trees.', 'sample_input': {'values': [24, 35, 6, 17, 28, 39, 10], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Range queries with trees', 'watch_for': 'The invariant that makes Range queries with trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='169-range_queries_with-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def range_queries_with_trees_p169(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return range_queries_with_trees_p169(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Range queries with trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 169 curation harness: Range queries with trees
EXAMPLE_KIND = "tree_alg"
EXAMPLE_TITLE = "Range queries with trees"
SAMPLE = {
"values": [
24,
35,
6,
17,
28,
39,
10
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "169-range_queries_with_t"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "169-range_queries_with_t"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "169-range_queries_with_t"))
Browser JavaScript companion
// Page 169 browser-side experiment: Range queries with trees
const pageExample169 = {"values":[24,35,6,17,28,39,10],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"169-range_queries_with_t"};
function summarizePage169(sample = pageExample169) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Range queries with trees",
kind: "tree_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage169());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Range queries with trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 169.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 170 / 561Chapter 12: Binary Search Trees and Balanced Trees
Immutable balanced trees
Page-local deep read
Mental model for Immutable balanced trees: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 170, the goal is not memorizing immutable balanced trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Immutable balanced trees is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Immutable balanced trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 170: Immutable balanced trees
EXAMPLE = {'page': 170, 'topic': 'Immutable balanced trees', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Immutable balanced trees.', 'sample_input': {'values': [31, 2, 13, 24, 35, 6, 17], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Immutable balanced trees', 'watch_for': 'The invariant that makes Immutable balanced trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='170-immutable_balanced-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def immutable_balanced_trees_p170(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return immutable_balanced_trees_p170(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Immutable balanced trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Immutable balanced trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 170.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement immutable balanced trees twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 171 / 561Chapter 12: Binary Search Trees and Balanced Trees
Skip lists
Page-local deep read
Mental model for Skip lists: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 171, the goal is not memorizing skip lists; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Skip lists is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Skip lists before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: A plain BST can become a linked list if keys arrive in sorted order.
# Page 171: Skip lists
EXAMPLE = {'page': 171, 'topic': 'Skip lists', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Skip lists.', 'sample_input': {'values': [38, 9, 20, 31, 2, 13, 24], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Skip lists', 'watch_for': 'The invariant that makes Skip lists safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='171-skip_lists-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def skip_lists_p171(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return skip_lists_p171(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Skip lists" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Skip lists.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 171.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for skip lists and explain what each one stresses.
Page 172 / 561Chapter 12: Binary Search Trees and Balanced Trees
Maps and sets in standard libraries
Page-local deep read
Mental model for Maps and sets in standard libraries: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 172, the goal is not memorizing maps and sets in standard libraries; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Maps and sets in standard libraries is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Maps and sets in standard libraries before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 172: Maps and sets in standard libraries
EXAMPLE = {'page': 172, 'topic': 'Maps and sets in standard libraries', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Maps and sets in standard libraries.', 'sample_input': {'values': [5, 16, 27, 38, 9, 20, 31], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Maps and sets in standard libraries', 'watch_for': 'The invariant that makes Maps and sets in standard libraries safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='172-maps_and_sets_in_s-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def maps_and_sets_in_standard_libraries_p172(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return maps_and_sets_in_standard_libraries_p172(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Maps and sets in standard libraries" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 172 curation harness: Maps and sets in standard libraries
EXAMPLE_KIND = "tree_alg"
EXAMPLE_TITLE = "Maps and sets in standard libraries"
SAMPLE = {
"values": [
5,
16,
27,
38,
9,
20,
31
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "172-maps_and_sets_in_sta"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "172-maps_and_sets_in_sta"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "172-maps_and_sets_in_sta"))
Browser JavaScript companion
// Page 172 browser-side experiment: Maps and sets in standard libraries
const pageExample172 = {"values":[5,16,27,38,9,20,31],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"172-maps_and_sets_in_sta"};
function summarizePage172(sample = pageExample172) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Maps and sets in standard libraries",
kind: "tree_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage172());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Maps and sets in standard libraries.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 172.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for maps and sets in standard libraries, then point to the line of code that preserves it.
Page 173 / 561Chapter 12: Binary Search Trees and Balanced Trees
Pathological insertion orders
Page-local deep read
Mental model for Pathological insertion orders: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 173, the goal is not memorizing pathological insertion orders; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Pathological insertion orders is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Pathological insertion orders before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 173: Pathological insertion orders
EXAMPLE = {'page': 173, 'topic': 'Pathological insertion orders', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Pathological insertion orders.', 'sample_input': {'values': [12, 23, 34, 5, 16, 27, 38], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Pathological insertion orders', 'watch_for': 'The invariant that makes Pathological insertion orders safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='173-pathological_inser-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def pathological_insertion_orders_p173(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return pathological_insertion_orders_p173(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Pathological insertion orders" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Pathological insertion orders.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 173.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 174 / 561Chapter 12: Binary Search Trees and Balanced Trees
Choosing a tree structure
Page-local deep read
Mental model for Choosing a tree structure: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 174, the goal is not memorizing choosing a tree structure; it is recognizing the representation, the safe transition, and the stopping condition inside the Binary Search Trees and Balanced Trees chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Choosing a tree structure is one small tool in the larger Binary Search Trees and Balanced Trees toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Choosing a tree structure before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: requires monotone predicate. Make this risk visible in tests and in code comments.
Common pitfall: A plain BST can become a linked list if keys arrive in sorted order.
# Page 174: Choosing a tree structure
EXAMPLE = {'page': 174, 'topic': 'Choosing a tree structure', 'chapter': 'Binary Search Trees and Balanced Trees', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Choosing a tree structure.', 'sample_input': {'values': [19, 30, 1, 12, 23, 34, 5], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Choosing a tree structure', 'watch_for': 'The invariant that makes Choosing a tree structure safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='174-choosing_a_tree_st-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def choosing_a_tree_structure_p174(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return choosing_a_tree_structure_p174(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Choosing a tree structure" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 174 curation harness: Choosing a tree structure
EXAMPLE_KIND = "tree_alg"
EXAMPLE_TITLE = "Choosing a tree structure"
SAMPLE = {
"values": [
19,
30,
1,
12,
23,
34,
5
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "174-choosing_a_tree_stru"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "174-choosing_a_tree_stru"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "174-choosing_a_tree_stru"))
Browser JavaScript companion
// Page 174 browser-side experiment: Choosing a tree structure
const pageExample174 = {"values":[19,30,1,12,23,34,5],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"174-choosing_a_tree_stru"};
function summarizePage174(sample = pageExample174) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Choosing a tree structure",
kind: "tree_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage174());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Choosing a tree structure.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 174.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 175 / 561Chapter 13: Heaps and Priority Queues
Heap invariant
Page-local deep read
Mental model for Heap invariant: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 175, the goal is not memorizing heap invariant; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Heap invariant is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Heap invariant before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 13: Heaps and Priority Queues
class MinHeap {
constructor() { this.a = []; }
push(x) { this.a.push(x); for (let i = this.a.length - 1; i > 0;) { const p = Math.floor((i - 1) / 2); if (this.a[p] <= this.a[i]) break; [this.a[p], this.a[i]] = [this.a[i], this.a[p]]; i = p; } }
pop() { this.a.sort((x,y)=>x-y); return this.a.shift(); }
}
const h = new MinHeap(); [7,3,1].forEach(x => h.push(x)); console.log(h.pop());
Chapter anchor: This page is the Chapter 13 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Heaps and Priority Queues.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: stale priorities. Make this risk visible in tests and in code comments.
Common pitfall: Priority queues usually do not support efficient arbitrary priority decrease unless you add an index or use lazy deletion.
Insert values and extract the minimum while preserving the heap invariant.
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Heap invariant" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Heap invariant, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Heap invariant.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 175.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement heap invariant twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 176 / 561Chapter 13: Heaps and Priority Queues
Array representation of heaps
Page-local deep read
Mental model for Array representation of heaps: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 176, the goal is not memorizing array representation of heaps; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Array representation of heaps is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Array representation of heaps before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: stale priorities. Make this risk visible in tests and in code comments.
Common pitfall: Priority queues usually do not support efficient arbitrary priority decrease unless you add an index or use lazy deletion.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Array representation of heaps" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Array representation of heaps, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 176 curation harness: Array representation of heaps
EXAMPLE_KIND = "heap"
EXAMPLE_TITLE = "Array representation of heaps"
SAMPLE = {
"values": [
33,
4,
15,
26,
37,
8,
19
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "176-array_representation"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "176-array_representation"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "176-array_representation"))
Browser JavaScript companion
// Page 176 browser-side experiment: Array representation of heaps
const pageExample176 = {"values":[33,4,15,26,37,8,19],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"176-array_representation"};
function summarizePage176(sample = pageExample176) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Array representation of heaps",
kind: "heap",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage176());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Array representation of heaps.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 176.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for array representation of heaps and explain what each one stresses.
Page 177 / 561Chapter 13: Heaps and Priority Queues
Sift up and sift down
Page-local deep read
Mental model for Sift up and sift down: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 177, the goal is not memorizing sift up and sift down; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sift up and sift down is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sift up and sift down before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: stale priorities. Make this risk visible in tests and in code comments.
Common pitfall: Priority queues usually do not support efficient arbitrary priority decrease unless you add an index or use lazy deletion.
# Page 177: Sift up and sift down
EXAMPLE = {'page': 177, 'topic': 'Sift up and sift down', 'chapter': 'Heaps and Priority Queues', 'kind': 'heap', 'scenario': 'Run a concrete heap miniature for Sift up and sift down.', 'sample_input': {'values': [40, 11, 22, 33, 4, 15, 26], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Sift up and sift down', 'watch_for': 'The invariant that makes Sift up and sift down safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the heap example changes first.', 'docs': [('Python heapq priority queues', 'https://docs.python.org/3/library/heapq.html')]}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='177-sift_up_and_sift_d-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def sift_up_and_sift_down_p177(values):
heap = list(values)
heapq.heapify(heap)
return [heapq.heappop(heap) for _ in range(len(heap))]
def run_example(example=EXAMPLE):
return sift_up_and_sift_down_p177(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Sift up and sift down" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Sift up and sift down, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 177 curation harness: Sift up and sift down
EXAMPLE_KIND = "heap"
EXAMPLE_TITLE = "Sift up and sift down"
SAMPLE = {
"values": [
40,
11,
22,
33,
4,
15,
26
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "177-sift_up_and_sift_dow"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "177-sift_up_and_sift_dow"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "177-sift_up_and_sift_dow"))
Browser JavaScript companion
// Page 177 browser-side experiment: Sift up and sift down
const pageExample177 = {"values":[40,11,22,33,4,15,26],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"177-sift_up_and_sift_dow"};
function summarizePage177(sample = pageExample177) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Sift up and sift down",
kind: "heap",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage177());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Sift up and sift down.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 177.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for sift up and sift down, then point to the line of code that preserves it.
Page 178 / 561Chapter 13: Heaps and Priority Queues
Heapify bottom-up
Page-local deep read
Mental model for Heapify bottom-up: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 178, the goal is not memorizing heapify bottom-up; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Heapify bottom-up is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Heapify bottom-up before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Heapify bottom-up whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: stale priorities. Make this risk visible in tests and in code comments.
Common pitfall: Priority queues usually do not support efficient arbitrary priority decrease unless you add an index or use lazy deletion.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Heapify bottom-up" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Heapify bottom-up, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Heapify bottom-up.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 178.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 179 / 561Chapter 13: Heaps and Priority Queues
Priority queue API
Page-local deep read
Mental model for Priority queue API: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 179, the goal is not memorizing priority queue api; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Priority queue API is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Priority queue API before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Priority queue API" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Priority queue API, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Priority queue API.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 179.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 180 / 561Chapter 13: Heaps and Priority Queues
Lazy deletion
Page-local deep read
Mental model for Lazy deletion: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 180, the goal is not memorizing lazy deletion; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Lazy deletion is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Lazy deletion before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Lazy deletion" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Lazy deletion, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Lazy deletion.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 180.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement lazy deletion twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 181 / 561Chapter 13: Heaps and Priority Queues
Two heaps for medians
Page-local deep read
Mental model for Two heaps for medians: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 181, the goal is not memorizing two heaps for medians; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Two heaps for medians is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Two heaps for medians before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: stale priorities. Make this risk visible in tests and in code comments.
Common pitfall: Priority queues usually do not support efficient arbitrary priority decrease unless you add an index or use lazy deletion.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Two heaps for medians" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Two heaps for medians, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 181 curation harness: Two heaps for medians
EXAMPLE_KIND = "heap"
EXAMPLE_TITLE = "Two heaps for medians"
SAMPLE = {
"values": [
28,
39,
10,
21,
32,
3,
14
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "181-two_heaps_for_median"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "181-two_heaps_for_median"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "181-two_heaps_for_median"))
Browser JavaScript companion
// Page 181 browser-side experiment: Two heaps for medians
const pageExample181 = {"values":[28,39,10,21,32,3,14],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"181-two_heaps_for_median"};
function summarizePage181(sample = pageExample181) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Two heaps for medians",
kind: "heap",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage181());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Two heaps for medians.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 181.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for two heaps for medians and explain what each one stresses.
Page 182 / 561Chapter 13: Heaps and Priority Queues
K-way merge
Page-local deep read
Mental model for K-way merge: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 182, the goal is not memorizing k-way merge; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: K-way merge is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for K-way merge before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "K-way merge" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of K-way merge, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by K-way merge.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 182.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for k-way merge, then point to the line of code that preserves it.
Page 183 / 561Chapter 13: Heaps and Priority Queues
Top-k with bounded heaps
Page-local deep read
Mental model for Top-k with bounded heaps: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 183, the goal is not memorizing top-k with bounded heaps; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Top-k with bounded heaps is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Top-k with bounded heaps before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 183: Top-k with bounded heaps
EXAMPLE = {'page': 183, 'topic': 'Top-k with bounded heaps', 'chapter': 'Heaps and Priority Queues', 'kind': 'quickselect', 'scenario': 'Run a concrete quickselect miniature for Top-k with bounded heaps.', 'sample_input': {'values': [2, 13, 24, 35, 6, 17, 28], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Top-k with bounded heaps', 'watch_for': 'The invariant that makes Top-k with bounded heaps safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the quickselect example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='183-top_k_with_bounded-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def top_k_with_bounded_heaps_p183(values, k):
pivot = values[len(values)//2]
lows = [v for v in values if v < pivot]
highs = [v for v in values if v > pivot]
pivots = [v for v in values if v == pivot]
if k < len(lows): return top_k_with_bounded_heaps_p183(lows, k)
if k < len(lows) + len(pivots): return pivot
return top_k_with_bounded_heaps_p183(highs, k - len(lows) - len(pivots))
def run_example(example=EXAMPLE):
return top_k_with_bounded_heaps_p183(example['sample_input']['values'], 2)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Top-k with bounded heaps, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 183 curation harness: Top-k with bounded heaps
EXAMPLE_KIND = "quickselect"
EXAMPLE_TITLE = "Top-k with bounded heaps"
SAMPLE = {
"values": [
2,
13,
24,
35,
6,
17,
28
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "183-top_k_with_bounded_h"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "183-top_k_with_bounded_h"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "183-top_k_with_bounded_h"))
Browser JavaScript companion
// Page 183 browser-side experiment: Top-k with bounded heaps
const pageExample183 = {"values":[2,13,24,35,6,17,28],"steps":["read","update","verify"],"page_marker":"183-top_k_with_bounded_h"};
function summarizePage183(sample = pageExample183) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Top-k with bounded heaps",
kind: "quickselect",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage183());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Top-k with bounded heaps.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the quickselect invariant described in the code comments and return a stable, inspectable result for page 183.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 184 / 561Chapter 13: Heaps and Priority Queues
D-ary heaps
Page-local deep read
Mental model for D-ary heaps: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 184, the goal is not memorizing d-ary heaps; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: D-ary heaps is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for D-ary heaps before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: stale priorities. Make this risk visible in tests and in code comments.
Common pitfall: Priority queues usually do not support efficient arbitrary priority decrease unless you add an index or use lazy deletion.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "D-ary heaps" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of D-ary heaps, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by D-ary heaps.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 184.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 185 / 561Chapter 13: Heaps and Priority Queues
Pairing heap intuition
Page-local deep read
Mental model for Pairing heap intuition: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 185, the goal is not memorizing pairing heap intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Pairing heap intuition is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Pairing heap intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: stale priorities. Make this risk visible in tests and in code comments.
Common pitfall: Priority queues usually do not support efficient arbitrary priority decrease unless you add an index or use lazy deletion.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Pairing heap intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Pairing heap intuition, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Pairing heap intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 185.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement pairing heap intuition twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 186 / 561Chapter 13: Heaps and Priority Queues
Indexed priority queues
Page-local deep read
Mental model for Indexed priority queues: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 186, the goal is not memorizing indexed priority queues; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Indexed priority queues is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Indexed priority queues before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: stale priorities. Make this risk visible in tests and in code comments.
Common pitfall: Priority queues usually do not support efficient arbitrary priority decrease unless you add an index or use lazy deletion.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Indexed priority queues" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Indexed priority queues, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Indexed priority queues.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 186.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for indexed priority queues and explain what each one stresses.
Page 187 / 561Chapter 13: Heaps and Priority Queues
Heap sort revisited
Page-local deep read
Mental model for Heap sort revisited: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 187, the goal is not memorizing heap sort revisited; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Heap sort revisited is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Heap sort revisited before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: Priority queues usually do not support efficient arbitrary priority decrease unless you add an index or use lazy deletion.
# Page 187: Heap sort revisited
EXAMPLE = {'page': 187, 'topic': 'Heap sort revisited', 'chapter': 'Heaps and Priority Queues', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for Heap sort revisited.', 'sample_input': {'values': [30, 1, 12, 23, 34, 5, 16], 'records': [{'name': 'A', 'score': 30}, {'name': 'B', 'score': 1}, {'name': 'C', 'score': 12}]}, 'expected_output': 'Inspectable result for Heap sort revisited', 'watch_for': 'The invariant that makes Heap sort revisited safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='187-heap_sort_revisite-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def heap_sort_revisited_p187(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return heap_sort_revisited_p187(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Heap sort revisited" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Heap sort revisited.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 187.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for heap sort revisited, then point to the line of code that preserves it.
Page 188 / 561Chapter 13: Heaps and Priority Queues
Priority queues in graph algorithms
Page-local deep read
Mental model for Priority queues in graph algorithms: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 188, the goal is not memorizing priority queues in graph algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Heaps and Priority Queues chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Priority queues in graph algorithms is one small tool in the larger Heaps and Priority Queues toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Priority queues in graph algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Priority queues in graph algorithms whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: stale priorities. Make this risk visible in tests and in code comments.
Common pitfall: Priority queues usually do not support efficient arbitrary priority decrease unless you add an index or use lazy deletion.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Priority queues in graph algorithms" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Priority queues in graph algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 188 curation harness: Priority queues in graph algorithms
EXAMPLE_KIND = "heap"
EXAMPLE_TITLE = "Priority queues in graph algorithms"
SAMPLE = {
"values": [
37,
8,
19,
30,
1,
12,
23
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "188-priority_queues_in_g"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "188-priority_queues_in_g"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "188-priority_queues_in_g"))
Browser JavaScript companion
// Page 188 browser-side experiment: Priority queues in graph algorithms
const pageExample188 = {"values":[37,8,19,30,1,12,23],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"188-priority_queues_in_g"};
function summarizePage188(sample = pageExample188) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Priority queues in graph algorithms",
kind: "heap",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage188());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Priority queues in graph algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the heap invariant described in the code comments and return a stable, inspectable result for page 188.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 189 / 561Chapter 14: Disjoint Set Union
DSU parent forest
Page-local deep read
Mental model for DSU parent forest: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 189, the goal is not memorizing dsu parent forest; it is recognizing the representation, the safe transition, and the stopping condition inside the Disjoint Set Union chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DSU parent forest is one small tool in the larger Disjoint Set Union toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DSU parent forest before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 14: Disjoint Set Union
class DSU {
constructor(n) { this.parent = Array.from({length:n}, (_, i) => i); this.size = Array(n).fill(1); }
find(x) { return this.parent[x] === x ? x : this.parent[x] = this.find(this.parent[x]); }
union(a, b) { let ra = this.find(a), rb = this.find(b); if (ra === rb) return false; if (this.size[ra] < this.size[rb]) [ra, rb] = [rb, ra]; this.parent[rb] = ra; this.size[ra] += this.size[rb]; return true; }
}
const d = new DSU(4); d.union(0,1); d.union(2,3); console.log(d.find(1) === d.find(0));
Chapter anchor: This page is the Chapter 14 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Disjoint Set Union.
# Page 189: DSU parent forest
EXAMPLE = {'page': 189, 'topic': 'DSU parent forest', 'chapter': 'Disjoint Set Union', 'kind': 'dsu', 'scenario': 'Run a concrete dsu miniature for DSU parent forest.', 'sample_input': {'values': [4, 15, 26, 37, 8, 19, 30], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for DSU parent forest', 'watch_for': 'The invariant that makes DSU parent forest safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='189-dsu_parent_forest-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def dsu_parent_forest_p189(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return dsu_parent_forest_p189(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Union-Find Playground
Union sets and run find. Toggle path compression to see parent forests flatten.
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "DSU parent forest" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of DSU parent forest, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by DSU parent forest.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 189.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 190 / 561Chapter 14: Disjoint Set Union
Find operation
Page-local deep read
Mental model for Find operation: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 190, the goal is not memorizing find operation; it is recognizing the representation, the safe transition, and the stopping condition inside the Disjoint Set Union chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Find operation is one small tool in the larger Disjoint Set Union toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Find operation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 190: Find operation
EXAMPLE = {'page': 190, 'topic': 'Find operation', 'chapter': 'Disjoint Set Union', 'kind': 'dsu', 'scenario': 'Run a concrete dsu miniature for Find operation.', 'sample_input': {'values': [11, 22, 33, 4, 15, 26, 37], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Find operation', 'watch_for': 'The invariant that makes Find operation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='190-find_operation-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def find_operation_p190(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return find_operation_p190(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Find operation" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Find operation, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Find operation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 190.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement find operation twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 191 / 561Chapter 14: Disjoint Set Union
Union operation
Page-local deep read
Mental model for Union operation: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 191, the goal is not memorizing union operation; it is recognizing the representation, the safe transition, and the stopping condition inside the Disjoint Set Union chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Union operation is one small tool in the larger Disjoint Set Union toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Union operation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: path compression / union size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting path compression or union by size can turn practical near-constant operations into tall-tree traversals.
# Page 191: Union operation
EXAMPLE = {'page': 191, 'topic': 'Union operation', 'chapter': 'Disjoint Set Union', 'kind': 'dsu', 'scenario': 'Run a concrete dsu miniature for Union operation.', 'sample_input': {'values': [18, 29, 40, 11, 22, 33, 4], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Union operation', 'watch_for': 'The invariant that makes Union operation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='191-union_operation-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def union_operation_p191(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return union_operation_p191(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Union operation" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Union operation, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Union operation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 191.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for union operation and explain what each one stresses.
Page 192 / 561Chapter 14: Disjoint Set Union
Path compression
Page-local deep read
Mental model for Path compression: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 192, the goal is not memorizing path compression; it is recognizing the representation, the safe transition, and the stopping condition inside the Disjoint Set Union chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Path compression is one small tool in the larger Disjoint Set Union toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Path compression before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 192: Path compression
EXAMPLE = {'page': 192, 'topic': 'Path compression', 'chapter': 'Disjoint Set Union', 'kind': 'dsu', 'scenario': 'Run a concrete dsu miniature for Path compression.', 'sample_input': {'values': [25, 36, 7, 18, 29, 40, 11], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Path compression', 'watch_for': 'The invariant that makes Path compression safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='192-path_compression-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def path_compression_p192(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return path_compression_p192(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Path compression" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Path compression, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Path compression.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 192.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for path compression, then point to the line of code that preserves it.
Page 193 / 561Chapter 14: Disjoint Set Union
Union by rank and size
Page-local deep read
Mental model for Union by rank and size: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 193, the goal is not memorizing union by rank and size; it is recognizing the representation, the safe transition, and the stopping condition inside the Disjoint Set Union chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Union by rank and size is one small tool in the larger Disjoint Set Union toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Union by rank and size before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 193: Union by rank and size
EXAMPLE = {'page': 193, 'topic': 'Union by rank and size', 'chapter': 'Disjoint Set Union', 'kind': 'dsu', 'scenario': 'Run a concrete dsu miniature for Union by rank and size.', 'sample_input': {'values': [32, 3, 14, 25, 36, 7, 18], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Union by rank and size', 'watch_for': 'The invariant that makes Union by rank and size safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='193-union_by_rank_and_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def union_by_rank_and_size_p193(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return union_by_rank_and_size_p193(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Union by rank and size" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Union by rank and size, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 193 curation harness: Union by rank and size
EXAMPLE_KIND = "dsu"
EXAMPLE_TITLE = "Union by rank and size"
SAMPLE = {
"values": [
32,
3,
14,
25,
36,
7,
18
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "193-union_by_rank_and_si"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "193-union_by_rank_and_si"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "193-union_by_rank_and_si"))
Browser JavaScript companion
// Page 193 browser-side experiment: Union by rank and size
const pageExample193 = {"values":[32,3,14,25,36,7,18],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"193-union_by_rank_and_si"};
function summarizePage193(sample = pageExample193) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Union by rank and size",
kind: "dsu",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage193());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Union by rank and size.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 193.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 194 / 561Chapter 14: Disjoint Set Union
Amortized inverse Ackermann intuition
Page-local deep read
Mental model for Amortized inverse Ackermann intuition: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 194, the goal is not memorizing amortized inverse ackermann intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Disjoint Set Union chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Amortized inverse Ackermann intuition is one small tool in the larger Disjoint Set Union toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Amortized inverse Ackermann intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: path compression / union size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting path compression or union by size can turn practical near-constant operations into tall-tree traversals.
# Page 194: Amortized inverse Ackermann intuition
EXAMPLE = {'page': 194, 'topic': 'Amortized inverse Ackermann intuition', 'chapter': 'Disjoint Set Union', 'kind': 'dsu', 'scenario': 'Run a concrete dsu miniature for Amortized inverse Ackermann intuition.', 'sample_input': {'values': [39, 10, 21, 32, 3, 14, 25], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Amortized inverse Ackermann intuition', 'watch_for': 'The invariant that makes Amortized inverse Ackermann intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='194-amortized_inverse_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def amortized_inverse_ackermann_intuition_p194(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return amortized_inverse_ackermann_intuition_p194(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Amortized inverse Ackermann intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Amortized inverse Ackermann intuition, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Amortized inverse Ackermann intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 194.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 195 / 561Chapter 14: Disjoint Set Union
Kruskal's algorithm with DSU
Page-local deep read
Mental model for Kruskal's algorithm with DSU: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 195, the goal is not memorizing kruskal's algorithm with dsu; it is recognizing the representation, the safe transition, and the stopping condition inside the Disjoint Set Union chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Kruskal's algorithm with DSU is one small tool in the larger Disjoint Set Union toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Kruskal's algorithm with DSU before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: path compression / union size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting path compression or union by size can turn practical near-constant operations into tall-tree traversals.
# Page 195: Kruskal's algorithm with DSU
EXAMPLE = {'page': 195, 'topic': "Kruskal's algorithm with DSU", 'chapter': 'Disjoint Set Union', 'kind': 'dsu', 'scenario': "Run a concrete dsu miniature for Kruskal's algorithm with DSU.", 'sample_input': {'values': [6, 17, 28, 39, 10, 21, 32], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': "Inspectable result for Kruskal's algorithm with DSU", 'watch_for': "The invariant that makes Kruskal's algorithm with DSU safe is checked before the next transition.", 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='195-kruskal_s_algorith-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def kruskal_s_algorithm_with_dsu_p195(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return kruskal_s_algorithm_with_dsu_p195(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Kruskal's algorithm with DSU" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Kruskal's algorithm with DSU, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 195 curation harness: Kruskal's algorithm with DSU
EXAMPLE_KIND = "dsu"
EXAMPLE_TITLE = "Kruskal's algorithm with DSU"
SAMPLE = {
"values": [
6,
17,
28,
39,
10,
21,
32
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "195-kruskal_s_algorithm_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "195-kruskal_s_algorithm_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "195-kruskal_s_algorithm_"))
Browser JavaScript companion
// Page 195 browser-side experiment: Kruskal's algorithm with DSU
const pageExample195 = {"values":[6,17,28,39,10,21,32],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"195-kruskal_s_algorithm_"};
function summarizePage195(sample = pageExample195) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Kruskal's algorithm with DSU",
kind: "dsu",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage195());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Kruskal's algorithm with DSU.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 195.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement kruskal's algorithm with dsu twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 196 / 561Chapter 14: Disjoint Set Union
Connected components online
Page-local deep read
Mental model for Connected components online: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 196, the goal is not memorizing connected components online; it is recognizing the representation, the safe transition, and the stopping condition inside the Disjoint Set Union chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Connected components online is one small tool in the larger Disjoint Set Union toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Connected components online before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting path compression or union by size can turn practical near-constant operations into tall-tree traversals.
# Page 196: Connected components online
EXAMPLE = {'page': 196, 'topic': 'Connected components online', 'chapter': 'Disjoint Set Union', 'kind': 'dsu', 'scenario': 'Run a concrete dsu miniature for Connected components online.', 'sample_input': {'values': [13, 24, 35, 6, 17, 28, 39], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Connected components online', 'watch_for': 'The invariant that makes Connected components online safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='196-connected_componen-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def connected_components_online_p196(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return connected_components_online_p196(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Connected components online" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Connected components online, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Connected components online.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 196.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for connected components online and explain what each one stresses.
Page 197 / 561Chapter 14: Disjoint Set Union
Rollback DSU
Page-local deep read
Mental model for Rollback DSU: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 197, the goal is not memorizing rollback dsu; it is recognizing the representation, the safe transition, and the stopping condition inside the Disjoint Set Union chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rollback DSU is one small tool in the larger Disjoint Set Union toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rollback DSU before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: path compression / union size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting path compression or union by size can turn practical near-constant operations into tall-tree traversals.
# Page 197: Rollback DSU
EXAMPLE = {'page': 197, 'topic': 'Rollback DSU', 'chapter': 'Disjoint Set Union', 'kind': 'dsu', 'scenario': 'Run a concrete dsu miniature for Rollback DSU.', 'sample_input': {'values': [20, 31, 2, 13, 24, 35, 6], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Rollback DSU', 'watch_for': 'The invariant that makes Rollback DSU safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='197-rollback_dsu-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def rollback_dsu_p197(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return rollback_dsu_p197(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Rollback DSU" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Rollback DSU, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Rollback DSU.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 197.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for rollback dsu, then point to the line of code that preserves it.
Page 198 / 561Chapter 14: Disjoint Set Union
DSU pitfalls
Page-local deep read
Mental model for DSU pitfalls: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 198, the goal is not memorizing dsu pitfalls; it is recognizing the representation, the safe transition, and the stopping condition inside the Disjoint Set Union chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DSU pitfalls is one small tool in the larger Disjoint Set Union toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DSU pitfalls before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for DSU pitfalls whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: path compression / union size. Make this risk visible in tests and in code comments.
Common pitfall: Forgetting path compression or union by size can turn practical near-constant operations into tall-tree traversals.
# Page 198: DSU pitfalls
EXAMPLE = {'page': 198, 'topic': 'DSU pitfalls', 'chapter': 'Disjoint Set Union', 'kind': 'dsu', 'scenario': 'Run a concrete dsu miniature for DSU pitfalls.', 'sample_input': {'values': [27, 38, 9, 20, 31, 2, 13], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for DSU pitfalls', 'watch_for': 'The invariant that makes DSU pitfalls safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='198-dsu_pitfalls-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def dsu_pitfalls_p198(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return dsu_pitfalls_p198(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "DSU pitfalls" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of DSU pitfalls, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by DSU pitfalls.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 198.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 199 / 561Chapter 15: Graph Basics and Traversal
Graph representations
Page-local deep read
Mental model for Graph representations: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 199, the goal is not memorizing graph representations; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Graph representations is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Graph representations before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 15: Graph Basics and Traversal
function bfs(graph, start) {
const q = [start], dist = new Map([[start, 0]]);
for (let head = 0; head < q.length; head++) for (const v of graph[q[head]] ?? []) if (!dist.has(v)) { dist.set(v, dist.get(q[head]) + 1); q.push(v); }
return Object.fromEntries(dist);
}
console.log(bfs({A:['B','C'],B:['D'],C:['D'],D:[]}, 'A'));
Chapter anchor: This page is the Chapter 15 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Graph Basics and Traversal.
# Page 199: Graph representations
EXAMPLE = {'page': 199, 'topic': 'Graph representations', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Graph representations.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Graph representations', 'watch_for': 'The invariant that makes Graph representations safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='199-graph_representati-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def graph_representations_p199(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return graph_representations_p199(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Graph representations" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Graph representations.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 199.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 200 / 561Chapter 15: Graph Basics and Traversal
Adjacency lists versus matrices
Page-local deep read
Mental model for Adjacency lists versus matrices: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 200, the goal is not memorizing adjacency lists versus matrices; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Adjacency lists versus matrices is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Adjacency lists versus matrices before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 200: Adjacency lists versus matrices
EXAMPLE = {'page': 200, 'topic': 'Adjacency lists versus matrices', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Adjacency lists versus matrices.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Adjacency lists versus matrices', 'watch_for': 'The invariant that makes Adjacency lists versus matrices safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='200-adjacency_lists_ve-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def adjacency_lists_versus_matrices_p200(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return adjacency_lists_versus_matrices_p200(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Adjacency lists versus matrices" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 200 curation harness: Adjacency lists versus matrices
EXAMPLE_KIND = "graph"
EXAMPLE_TITLE = "Adjacency lists versus matrices"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "200-adjacency_lists_vers"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "200-adjacency_lists_vers"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "200-adjacency_lists_vers"))
Browser JavaScript companion
// Page 200 browser-side experiment: Adjacency lists versus matrices
const pageExample200 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"200-adjacency_lists_vers"};
function summarizePage200(sample = pageExample200) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Adjacency lists versus matrices",
kind: "graph",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage200());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Adjacency lists versus matrices.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 200.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement adjacency lists versus matrices twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 201 / 561Chapter 15: Graph Basics and Traversal
BFS
Page-local deep read
Mental model for BFS: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 201, the goal is not memorizing bfs; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: BFS is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for BFS before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: Marking nodes visited too late can enqueue or recurse into the same state many times.
# Page 201: BFS
EXAMPLE = {'page': 201, 'topic': 'BFS', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph_bfs', 'scenario': 'Run a concrete graph bfs miniature for BFS.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for BFS', 'watch_for': 'The invariant that makes BFS safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph bfs example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='201-bfs-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def bfs_p201(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return bfs_p201(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Graph Traversal Visualizer
Run BFS or DFS from node A. The frontier determines the order.
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "BFS" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by BFS.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph bfs invariant described in the code comments and return a stable, inspectable result for page 201.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for bfs and explain what each one stresses.
Page 202 / 561Chapter 15: Graph Basics and Traversal
DFS
Page-local deep read
Mental model for DFS: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 202, the goal is not memorizing dfs; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DFS is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DFS before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 202: DFS
EXAMPLE = {'page': 202, 'topic': 'DFS', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph_dfs', 'scenario': 'Run a concrete graph dfs miniature for DFS.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for DFS', 'watch_for': 'The invariant that makes DFS safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph dfs example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='202-dfs-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def dfs_p202(graph, start):
seen, order = set(), []
def dfs(node):
seen.add(node); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen: dfs(nxt)
dfs(start); return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return dfs_p202(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "DFS" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by DFS.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph dfs invariant described in the code comments and return a stable, inspectable result for page 202.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for dfs, then point to the line of code that preserves it.
Page 203 / 561Chapter 15: Graph Basics and Traversal
Connected components
Page-local deep read
Mental model for Connected components: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 203, the goal is not memorizing connected components; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Connected components is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Connected components before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 203: Connected components
EXAMPLE = {'page': 203, 'topic': 'Connected components', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Connected components.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Connected components', 'watch_for': 'The invariant that makes Connected components safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='203-connected_componen-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def connected_components_p203(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return connected_components_p203(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Connected components" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Connected components.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 203.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 204 / 561Chapter 15: Graph Basics and Traversal
Cycle detection
Page-local deep read
Mental model for Cycle detection: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 204, the goal is not memorizing cycle detection; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Cycle detection is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Cycle detection before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: Marking nodes visited too late can enqueue or recurse into the same state many times.
# Page 204: Cycle detection
EXAMPLE = {'page': 204, 'topic': 'Cycle detection', 'chapter': 'Graph Basics and Traversal', 'kind': 'linked_list', 'scenario': 'Run a concrete linked list miniature for Cycle detection.', 'sample_input': {'values': [29, 40, 11, 22, 33, 4, 15], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Cycle detection', 'watch_for': 'The invariant that makes Cycle detection safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linked list example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='204-cycle_detection-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class Node:
def __init__(self, value, next=None): self.value, self.next = value, next
def cycle_detection_p204(head):
prev, node = None, head
while node:
nxt = node.next; node.next = prev; prev = node; node = nxt
return prev
def to_list(head):
out=[]
while head: out.append(head.value); head=head.next
return out
def run_example(example=EXAMPLE):
head = Node(1, Node(2, Node(3)))
return to_list(cycle_detection_p204(head))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Cycle detection, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Cycle detection.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the linked list invariant described in the code comments and return a stable, inspectable result for page 204.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 205 / 561Chapter 15: Graph Basics and Traversal
Bipartite checking
Page-local deep read
Mental model for Bipartite checking: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 205, the goal is not memorizing bipartite checking; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bipartite checking is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bipartite checking before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: Marking nodes visited too late can enqueue or recurse into the same state many times.
# Page 205: Bipartite checking
EXAMPLE = {'page': 205, 'topic': 'Bipartite checking', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Bipartite checking.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Bipartite checking', 'watch_for': 'The invariant that makes Bipartite checking safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='205-bipartite_checking-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def bipartite_checking_p205(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return bipartite_checking_p205(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Bipartite checking" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Bipartite checking.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 205.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement bipartite checking twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 206 / 561Chapter 15: Graph Basics and Traversal
Flood fill
Page-local deep read
Mental model for Flood fill: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 206, the goal is not memorizing flood fill; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Flood fill is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Flood fill before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: visited-state mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Marking nodes visited too late can enqueue or recurse into the same state many times.
# Page 206: Flood fill
EXAMPLE = {'page': 206, 'topic': 'Flood fill', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Flood fill.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Flood fill', 'watch_for': 'The invariant that makes Flood fill safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='206-flood_fill-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def flood_fill_p206(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return flood_fill_p206(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Flood fill" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Flood fill.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 206.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for flood fill and explain what each one stresses.
Page 207 / 561Chapter 15: Graph Basics and Traversal
Maze shortest paths
Page-local deep read
Mental model for Maze shortest paths: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 207, the goal is not memorizing maze shortest paths; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Maze shortest paths is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Maze shortest paths before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: visited-state mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Marking nodes visited too late can enqueue or recurse into the same state many times.
# Page 207: Maze shortest paths
EXAMPLE = {'page': 207, 'topic': 'Maze shortest paths', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Maze shortest paths.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Maze shortest paths', 'watch_for': 'The invariant that makes Maze shortest paths safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='207-maze_shortest_path-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def maze_shortest_paths_p207(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return maze_shortest_paths_p207(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Maze shortest paths" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Maze shortest paths.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 207.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for maze shortest paths, then point to the line of code that preserves it.
Page 208 / 561Chapter 15: Graph Basics and Traversal
Implicit graphs
Page-local deep read
Mental model for Implicit graphs: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 208, the goal is not memorizing implicit graphs; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Implicit graphs is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Implicit graphs before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Implicit graphs whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: visited-state mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Marking nodes visited too late can enqueue or recurse into the same state many times.
# Page 208: Implicit graphs
EXAMPLE = {'page': 208, 'topic': 'Implicit graphs', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Implicit graphs.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Implicit graphs', 'watch_for': 'The invariant that makes Implicit graphs safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='208-implicit_graphs-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def implicit_graphs_p208(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return implicit_graphs_p208(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Implicit graphs" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Implicit graphs.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 208.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 209 / 561Chapter 15: Graph Basics and Traversal
Multi-source BFS
Page-local deep read
Mental model for Multi-source BFS: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 209, the goal is not memorizing multi-source bfs; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Multi-source BFS is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Multi-source BFS before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 209: Multi-source BFS
EXAMPLE = {'page': 209, 'topic': 'Multi-source BFS', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph_bfs', 'scenario': 'Run a concrete graph bfs miniature for Multi-source BFS.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Multi-source BFS', 'watch_for': 'The invariant that makes Multi-source BFS safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph bfs example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='209-multi_source_bfs-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def multi_source_bfs_p209(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return multi_source_bfs_p209(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Multi-source BFS" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Multi-source BFS.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph bfs invariant described in the code comments and return a stable, inspectable result for page 209.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 210 / 561Chapter 15: Graph Basics and Traversal
0-1 BFS preview
Page-local deep read
Mental model for 0-1 BFS preview: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 210, the goal is not memorizing 0-1 bfs preview; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: 0-1 BFS preview is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for 0-1 BFS preview before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 210: 0-1 BFS preview
EXAMPLE = {'page': 210, 'topic': '0-1 BFS preview', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for 0-1 BFS preview.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for 0-1 BFS preview', 'watch_for': 'The invariant that makes 0-1 BFS preview safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='210-topic_0_1_bfs_prev-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def topic_0_1_bfs_preview_p210(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return topic_0_1_bfs_preview_p210(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "0-1 BFS preview" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by 0-1 BFS preview.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 210.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement 0-1 bfs preview twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 211 / 561Chapter 15: Graph Basics and Traversal
Graph traversal state
Page-local deep read
Mental model for Graph traversal state: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 211, the goal is not memorizing graph traversal state; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Graph traversal state is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Graph traversal state before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: visited-state mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Marking nodes visited too late can enqueue or recurse into the same state many times.
# Page 211: Graph traversal state
EXAMPLE = {'page': 211, 'topic': 'Graph traversal state', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Graph traversal state.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Graph traversal state', 'watch_for': 'The invariant that makes Graph traversal state safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='211-graph_traversal_st-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def graph_traversal_state_p211(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return graph_traversal_state_p211(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Graph traversal state" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Graph traversal state.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 211.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for graph traversal state and explain what each one stresses.
Page 212 / 561Chapter 15: Graph Basics and Traversal
Parent arrays and path reconstruction
Page-local deep read
Mental model for Parent arrays and path reconstruction: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 212, the goal is not memorizing parent arrays and path reconstruction; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Parent arrays and path reconstruction is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Parent arrays and path reconstruction before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 212: Parent arrays and path reconstruction
EXAMPLE = {'page': 212, 'topic': 'Parent arrays and path reconstruction', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Parent arrays and path reconstruction.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Parent arrays and path reconstruction', 'watch_for': 'The invariant that makes Parent arrays and path reconstruction safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='212-parent_arrays_and_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def parent_arrays_and_path_reconstruction_p212(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return parent_arrays_and_path_reconstruction_p212(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Parent arrays and path reconstruction" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 212 curation harness: Parent arrays and path reconstruction
EXAMPLE_KIND = "graph"
EXAMPLE_TITLE = "Parent arrays and path reconstruction"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "212-parent_arrays_and_pa"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "212-parent_arrays_and_pa"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "212-parent_arrays_and_pa"))
Browser JavaScript companion
// Page 212 browser-side experiment: Parent arrays and path reconstruction
const pageExample212 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"212-parent_arrays_and_pa"};
function summarizePage212(sample = pageExample212) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Parent arrays and path reconstruction",
kind: "graph",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage212());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Parent arrays and path reconstruction.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 212.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for parent arrays and path reconstruction, then point to the line of code that preserves it.
Page 213 / 561Chapter 15: Graph Basics and Traversal
Bridges
Page-local deep read
Mental model for Bridges: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 213, the goal is not memorizing bridges; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bridges is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bridges before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 213: Bridges
EXAMPLE = {'page': 213, 'topic': 'Bridges', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Bridges.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Bridges', 'watch_for': 'The invariant that makes Bridges safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='213-bridges-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def bridges_p213(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return bridges_p213(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Bridges" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Bridges.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 213.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 214 / 561Chapter 15: Graph Basics and Traversal
Articulation points
Page-local deep read
Mental model for Articulation points: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 214, the goal is not memorizing articulation points; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Articulation points is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Articulation points before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: visited-state mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Marking nodes visited too late can enqueue or recurse into the same state many times.
# Page 214: Articulation points
EXAMPLE = {'page': 214, 'topic': 'Articulation points', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Articulation points.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Articulation points', 'watch_for': 'The invariant that makes Articulation points safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='214-articulation_point-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def articulation_points_p214(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return articulation_points_p214(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Articulation points" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Articulation points.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 214.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 215 / 561Chapter 15: Graph Basics and Traversal
Strongly connected components
Page-local deep read
Mental model for Strongly connected components: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 215, the goal is not memorizing strongly connected components; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Strongly connected components is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Strongly connected components before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: Marking nodes visited too late can enqueue or recurse into the same state many times.
# Page 215: Strongly connected components
EXAMPLE = {'page': 215, 'topic': 'Strongly connected components', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Strongly connected components.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Strongly connected components', 'watch_for': 'The invariant that makes Strongly connected components safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='215-strongly_connected-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def strongly_connected_components_p215(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return strongly_connected_components_p215(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Strongly connected components" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Strongly connected components.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 215.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement strongly connected components twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 216 / 561Chapter 15: Graph Basics and Traversal
Graph traversal bugs
Page-local deep read
Mental model for Graph traversal bugs: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 216, the goal is not memorizing graph traversal bugs; it is recognizing the representation, the safe transition, and the stopping condition inside the Graph Basics and Traversal chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Graph traversal bugs is one small tool in the larger Graph Basics and Traversal toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Graph traversal bugs before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: visited-state mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Marking nodes visited too late can enqueue or recurse into the same state many times.
# Page 216: Graph traversal bugs
EXAMPLE = {'page': 216, 'topic': 'Graph traversal bugs', 'chapter': 'Graph Basics and Traversal', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Graph traversal bugs.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Graph traversal bugs', 'watch_for': 'The invariant that makes Graph traversal bugs safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='216-graph_traversal_bu-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def graph_traversal_bugs_p216(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return graph_traversal_bugs_p216(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Graph traversal bugs" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Graph traversal bugs.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 216.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for graph traversal bugs and explain what each one stresses.
Page 217 / 561Chapter 16: DAGs and Topological Algorithms
DAG model
Page-local deep read
Mental model for DAG model: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 217, the goal is not memorizing dag model; it is recognizing the representation, the safe transition, and the stopping condition inside the DAGs and Topological Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DAG model is one small tool in the larger DAGs and Topological Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DAG model before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
This is a chapter-level anchor example. Read it alongside the page-specific labs lower down.
from collections import deque
def topological_sort(graph: dict[str, list[str]]) -> list[str]:
indeg = {u: 0 for u in graph}
for u in graph:
for v in graph[u]:
indeg[v] = indeg.get(v, 0) + 1
q = deque([u for u, d in indeg.items() if d == 0])
order = []
while q:
u = q.popleft()
order.append(u)
for v in graph.get(u, []):
indeg[v] -= 1
if indeg[v] == 0:
q.append(v)
if len(order) != len(indeg):
raise ValueError('graph contains a cycle')
return order
dag = {'shirt': ['belt', 'tie'], 'tie': ['jacket'], 'belt': ['jacket'], 'jacket': [], 'watch': []}
print(topological_sort(dag))
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 16: DAGs and Topological Algorithms
function topo(graph) {
const indeg = new Map(); Object.keys(graph).forEach(u => indeg.set(u, indeg.get(u) ?? 0));
for (const u in graph) for (const v of graph[u]) indeg.set(v, (indeg.get(v) ?? 0) + 1);
const q = [...indeg].filter(([,d]) => d === 0).map(([u]) => u), order = [];
for (let i = 0; i < q.length; i++) { const u = q[i]; order.push(u); for (const v of graph[u] ?? []) if (indeg.set(v, indeg.get(v)-1).get(v) === 0) q.push(v); }
return order;
}
console.log(topo({shirt:['belt','tie'], belt:['jacket'], tie:['jacket'], jacket:[]}));
Chapter anchor: This page is the Chapter 16 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of DAGs and Topological Algorithms.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: If a cycle exists, no topological order exists; silently producing a partial order is a bug.
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 217 curation harness: DAG model
EXAMPLE_KIND = "dag"
EXAMPLE_TITLE = "DAG model"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "217-dag_model"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "217-dag_model"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "217-dag_model"))
Browser JavaScript companion
// Page 217 browser-side experiment: DAG model
const pageExample217 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"217-dag_model"};
function summarizePage217(sample = pageExample217) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "DAG model",
kind: "dag",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage217());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by DAG model.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dag invariant described in the code comments and return a stable, inspectable result for page 217.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for dag model, then point to the line of code that preserves it.
Page 218 / 561Chapter 16: DAGs and Topological Algorithms
Topological sort with Kahn's algorithm
Page-local deep read
Mental model for Topological sort with Kahn's algorithm: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 218, the goal is not memorizing topological sort with kahn's algorithm; it is recognizing the representation, the safe transition, and the stopping condition inside the DAGs and Topological Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Topological sort with Kahn's algorithm is one small tool in the larger DAGs and Topological Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Topological sort with Kahn's algorithm before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Topological sort with Kahn's algorithm whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: If a cycle exists, no topological order exists; silently producing a partial order is a bug.
Kahn's algorithm repeatedly takes tasks with no remaining prerequisites.
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Topological sort with Kahn's algorithm" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 218 curation harness: Topological sort with Kahn's algorithm
EXAMPLE_KIND = "toposort"
EXAMPLE_TITLE = "Topological sort with Kahn's algorithm"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "218-topological_sort_wit"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "218-topological_sort_wit"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "218-topological_sort_wit"))
Browser JavaScript companion
// Page 218 browser-side experiment: Topological sort with Kahn's algorithm
const pageExample218 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"218-topological_sort_wit"};
function summarizePage218(sample = pageExample218) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Topological sort with Kahn's algorithm",
kind: "toposort",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage218());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Topological sort with Kahn's algorithm.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the toposort invariant described in the code comments and return a stable, inspectable result for page 218.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 219 / 561Chapter 16: DAGs and Topological Algorithms
Topological sort with DFS
Page-local deep read
Mental model for Topological sort with DFS: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 219, the goal is not memorizing topological sort with dfs; it is recognizing the representation, the safe transition, and the stopping condition inside the DAGs and Topological Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Topological sort with DFS is one small tool in the larger DAGs and Topological Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Topological sort with DFS before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 219: Topological sort with DFS
EXAMPLE = {'page': 219, 'topic': 'Topological sort with DFS', 'chapter': 'DAGs and Topological Algorithms', 'kind': 'toposort_dfs', 'scenario': 'Run a concrete toposort dfs miniature for Topological sort with DFS.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Topological sort with DFS', 'watch_for': 'The invariant that makes Topological sort with DFS safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the toposort dfs example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='219-topological_sort_w-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def topological_sort_with_dfs_p219(graph):
seen, temp, order = set(), set(), []
def dfs(node):
if node in temp: raise ValueError('cycle')
if node in seen: return
temp.add(node)
for nxt in graph.get(node, []): dfs(nxt)
temp.remove(node); seen.add(node); order.append(node)
for node in graph: dfs(node)
return order[::-1]
def run_example(example=EXAMPLE):
return topological_sort_with_dfs_p219({'parse':['build'], 'build':['test'], 'test':['deploy'], 'deploy':[]})
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Topological sort with DFS" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 219 curation harness: Topological sort with DFS
EXAMPLE_KIND = "toposort_dfs"
EXAMPLE_TITLE = "Topological sort with DFS"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "219-topological_sort_wit"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "219-topological_sort_wit"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "219-topological_sort_wit"))
Browser JavaScript companion
// Page 219 browser-side experiment: Topological sort with DFS
const pageExample219 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"219-topological_sort_wit"};
function summarizePage219(sample = pageExample219) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Topological sort with DFS",
kind: "toposort_dfs",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage219());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Topological sort with DFS.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the toposort dfs invariant described in the code comments and return a stable, inspectable result for page 219.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 220 / 561Chapter 16: DAGs and Topological Algorithms
Cycle detection in prerequisites
Page-local deep read
Mental model for Cycle detection in prerequisites: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 220, the goal is not memorizing cycle detection in prerequisites; it is recognizing the representation, the safe transition, and the stopping condition inside the DAGs and Topological Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Cycle detection in prerequisites is one small tool in the larger DAGs and Topological Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Cycle detection in prerequisites before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 220: Cycle detection in prerequisites
EXAMPLE = {'page': 220, 'topic': 'Cycle detection in prerequisites', 'chapter': 'DAGs and Topological Algorithms', 'kind': 'linked_list', 'scenario': 'Run a concrete linked list miniature for Cycle detection in prerequisites.', 'sample_input': {'values': [21, 32, 3, 14, 25, 36, 7], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Cycle detection in prerequisites', 'watch_for': 'The invariant that makes Cycle detection in prerequisites safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linked list example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='220-cycle_detection_in-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class Node:
def __init__(self, value, next=None): self.value, self.next = value, next
def cycle_detection_in_prerequisites_p220(head):
prev, node = None, head
while node:
nxt = node.next; node.next = prev; prev = node; node = nxt
return prev
def to_list(head):
out=[]
while head: out.append(head.value); head=head.next
return out
def run_example(example=EXAMPLE):
head = Node(1, Node(2, Node(3)))
return to_list(cycle_detection_in_prerequisites_p220(head))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Cycle detection in prerequisites, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 220 curation harness: Cycle detection in prerequisites
EXAMPLE_KIND = "linked_list"
EXAMPLE_TITLE = "Cycle detection in prerequisites"
SAMPLE = {
"values": [
21,
32,
3,
14,
25,
36,
7
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "220-cycle_detection_in_p"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "220-cycle_detection_in_p"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "220-cycle_detection_in_p"))
Browser JavaScript companion
// Page 220 browser-side experiment: Cycle detection in prerequisites
const pageExample220 = {"values":[21,32,3,14,25,36,7],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"220-cycle_detection_in_p"};
function summarizePage220(sample = pageExample220) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Cycle detection in prerequisites",
kind: "linked_list",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage220());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Cycle detection in prerequisites.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the linked list invariant described in the code comments and return a stable, inspectable result for page 220.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement cycle detection in prerequisites twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 221 / 561Chapter 16: DAGs and Topological Algorithms
DAG shortest paths
Page-local deep read
Mental model for DAG shortest paths: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 221, the goal is not memorizing dag shortest paths; it is recognizing the representation, the safe transition, and the stopping condition inside the DAGs and Topological Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DAG shortest paths is one small tool in the larger DAGs and Topological Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DAG shortest paths before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: If a cycle exists, no topological order exists; silently producing a partial order is a bug.
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by DAG shortest paths.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dag invariant described in the code comments and return a stable, inspectable result for page 221.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for dag shortest paths and explain what each one stresses.
Page 222 / 561Chapter 16: DAGs and Topological Algorithms
DAG longest paths
Page-local deep read
Mental model for DAG longest paths: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 222, the goal is not memorizing dag longest paths; it is recognizing the representation, the safe transition, and the stopping condition inside the DAGs and Topological Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DAG longest paths is one small tool in the larger DAGs and Topological Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DAG longest paths before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by DAG longest paths.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dag invariant described in the code comments and return a stable, inspectable result for page 222.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for dag longest paths, then point to the line of code that preserves it.
Page 223 / 561Chapter 16: DAGs and Topological Algorithms
Dynamic programming on DAGs
Page-local deep read
Mental model for Dynamic programming on DAGs: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 223, the goal is not memorizing dynamic programming on dags; it is recognizing the representation, the safe transition, and the stopping condition inside the DAGs and Topological Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Dynamic programming on DAGs is one small tool in the larger DAGs and Topological Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Dynamic programming on DAGs before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 223 curation harness: Dynamic programming on DAGs
EXAMPLE_KIND = "dag"
EXAMPLE_TITLE = "Dynamic programming on DAGs"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "223-dynamic_programming_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "223-dynamic_programming_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "223-dynamic_programming_"))
Browser JavaScript companion
// Page 223 browser-side experiment: Dynamic programming on DAGs
const pageExample223 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"223-dynamic_programming_"};
function summarizePage223(sample = pageExample223) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Dynamic programming on DAGs",
kind: "dag",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage223());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Dynamic programming on DAGs.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dag invariant described in the code comments and return a stable, inspectable result for page 223.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 224 / 561Chapter 16: DAGs and Topological Algorithms
Critical path scheduling
Page-local deep read
Mental model for Critical path scheduling: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 224, the goal is not memorizing critical path scheduling; it is recognizing the representation, the safe transition, and the stopping condition inside the DAGs and Topological Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Critical path scheduling is one small tool in the larger DAGs and Topological Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Critical path scheduling before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: If a cycle exists, no topological order exists; silently producing a partial order is a bug.
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Critical path scheduling.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dag invariant described in the code comments and return a stable, inspectable result for page 224.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 225 / 561Chapter 16: DAGs and Topological Algorithms
Partial orders
Page-local deep read
Mental model for Partial orders: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 225, the goal is not memorizing partial orders; it is recognizing the representation, the safe transition, and the stopping condition inside the DAGs and Topological Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Partial orders is one small tool in the larger DAGs and Topological Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Partial orders before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: If a cycle exists, no topological order exists; silently producing a partial order is a bug.
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Partial orders.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dag invariant described in the code comments and return a stable, inspectable result for page 225.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement partial orders twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 226 / 561Chapter 16: DAGs and Topological Algorithms
Topological sort edge cases
Page-local deep read
Mental model for Topological sort edge cases: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 226, the goal is not memorizing topological sort edge cases; it is recognizing the representation, the safe transition, and the stopping condition inside the DAGs and Topological Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Topological sort edge cases is one small tool in the larger DAGs and Topological Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Topological sort edge cases before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: If a cycle exists, no topological order exists; silently producing a partial order is a bug.
# Page 226: Topological sort edge cases
EXAMPLE = {'page': 226, 'topic': 'Topological sort edge cases', 'chapter': 'DAGs and Topological Algorithms', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for Topological sort edge cases.', 'sample_input': {'values': [23, 34, 5, 16, 27, 38, 9], 'records': [{'name': 'A', 'score': 23}, {'name': 'B', 'score': 34}, {'name': 'C', 'score': 5}]}, 'expected_output': 'Inspectable result for Topological sort edge cases', 'watch_for': 'The invariant that makes Topological sort edge cases safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='226-topological_sort_e-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def topological_sort_edge_cases_p226(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return topological_sort_edge_cases_p226(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Topological sort edge cases" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Topological sort edge cases.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 226.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for topological sort edge cases and explain what each one stresses.
Page 227 / 561Chapter 17: Shortest Paths
Shortest path problem variants
Page-local deep read
Mental model for Shortest path problem variants: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 227, the goal is not memorizing shortest path problem variants; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Shortest path problem variants is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Shortest path problem variants before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 17: Shortest Paths
function dijkstra(graph, start) {
const dist = new Map([[start, 0]]), used = new Set();
while (true) { let u = null, best = Infinity; for (const [v,d] of dist) if (!used.has(v) && d < best) [u,best] = [v,d]; if (u === null) break; used.add(u); for (const [v,w] of graph[u] ?? []) if (best + w < (dist.get(v) ?? Infinity)) dist.set(v, best + w); }
return Object.fromEntries(dist);
}
console.log(dijkstra({A:[['B',4],['C',1]], C:[['B',2]], B:[['D',1]], D:[]}, 'A'));
Chapter anchor: This page is the Chapter 17 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Shortest Paths.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: invalid weight assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 227: Shortest path problem variants
EXAMPLE = {'page': 227, 'topic': 'Shortest path problem variants', 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': 'Run a concrete shortest path miniature for Shortest path problem variants.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Shortest path problem variants', 'watch_for': 'The invariant that makes Shortest path problem variants safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='227-shortest_path_prob-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def shortest_path_problem_variants_p227(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return shortest_path_problem_variants_p227(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 227 curation harness: Shortest path problem variants
EXAMPLE_KIND = "shortest_path"
EXAMPLE_TITLE = "Shortest path problem variants"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "227-shortest_path_proble"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "227-shortest_path_proble"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "227-shortest_path_proble"))
Browser JavaScript companion
// Page 227 browser-side experiment: Shortest path problem variants
const pageExample227 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"227-shortest_path_proble"};
function summarizePage227(sample = pageExample227) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Shortest path problem variants",
kind: "shortest_path",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage227());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Shortest path problem variants.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 227.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for shortest path problem variants, then point to the line of code that preserves it.
Page 228 / 561Chapter 17: Shortest Paths
Unweighted shortest paths
Page-local deep read
Mental model for Unweighted shortest paths: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 228, the goal is not memorizing unweighted shortest paths; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Unweighted shortest paths is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Unweighted shortest paths before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Unweighted shortest paths whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: invalid weight assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 228: Unweighted shortest paths
EXAMPLE = {'page': 228, 'topic': 'Unweighted shortest paths', 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': 'Run a concrete shortest path miniature for Unweighted shortest paths.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Unweighted shortest paths', 'watch_for': 'The invariant that makes Unweighted shortest paths safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='228-unweighted_shortes-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def unweighted_shortest_paths_p228(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return unweighted_shortest_paths_p228(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Unweighted shortest paths.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 228.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 229 / 561Chapter 17: Shortest Paths
Dijkstra's algorithm
Page-local deep read
Mental model for Dijkstra's algorithm: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 229, the goal is not memorizing dijkstra's algorithm; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Dijkstra's algorithm is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Dijkstra's algorithm before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Watch tentative distances settle on a weighted graph with nonnegative edges.
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Dijkstra's algorithm, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Dijkstra's algorithm.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dijkstra invariant described in the code comments and return a stable, inspectable result for page 229.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 230 / 561Chapter 17: Shortest Paths
Priority queue Dijkstra
Page-local deep read
Mental model for Priority queue Dijkstra: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 230, the goal is not memorizing priority queue dijkstra; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Priority queue Dijkstra is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Priority queue Dijkstra before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Priority queue Dijkstra, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Priority queue Dijkstra.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dijkstra invariant described in the code comments and return a stable, inspectable result for page 230.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement priority queue dijkstra twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 231 / 561Chapter 17: Shortest Paths
Path reconstruction
Page-local deep read
Mental model for Path reconstruction: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 231, the goal is not memorizing path reconstruction; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Path reconstruction is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Path reconstruction before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: invalid weight assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 231: Path reconstruction
EXAMPLE = {'page': 231, 'topic': 'Path reconstruction', 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': 'Run a concrete shortest path miniature for Path reconstruction.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Path reconstruction', 'watch_for': 'The invariant that makes Path reconstruction safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='231-path_reconstructio-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def path_reconstruction_p231(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return path_reconstruction_p231(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Path reconstruction.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 231.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for path reconstruction and explain what each one stresses.
Page 232 / 561Chapter 17: Shortest Paths
0-1 BFS
Page-local deep read
Mental model for 0-1 BFS: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 232, the goal is not memorizing 0-1 bfs; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: 0-1 BFS is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for 0-1 BFS before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 232: 0-1 BFS
EXAMPLE = {'page': 232, 'topic': '0-1 BFS', 'chapter': 'Shortest Paths', 'kind': 'zero_one_bfs', 'scenario': 'Run a concrete zero one bfs miniature for 0-1 BFS.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for 0-1 BFS', 'watch_for': 'The invariant that makes 0-1 BFS safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the zero one bfs example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='232-topic_0_1_bfs-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def topic_0_1_bfs_p232(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return topic_0_1_bfs_p232(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of 0-1 BFS, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by 0-1 BFS.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the zero one bfs invariant described in the code comments and return a stable, inspectable result for page 232.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for 0-1 bfs, then point to the line of code that preserves it.
Page 233 / 561Chapter 17: Shortest Paths
Bellman-Ford
Page-local deep read
Mental model for Bellman-Ford: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 233, the goal is not memorizing bellman-ford; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bellman-Ford is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bellman-Ford before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 233: Bellman-Ford
EXAMPLE = {'page': 233, 'topic': 'Bellman-Ford', 'chapter': 'Shortest Paths', 'kind': 'bellman_ford', 'scenario': 'Run a concrete bellman ford miniature for Bellman-Ford.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Bellman-Ford', 'watch_for': 'The invariant that makes Bellman-Ford safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the bellman ford example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='233-bellman_ford-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def bellman_ford_p233(nodes, edges, start):
dist = {node: float('inf') for node in nodes}; dist[start] = 0
for _ in range(len(nodes)-1):
changed = False
for u, v, w in edges:
if dist[u] + w < dist[v]: dist[v] = dist[u] + w; changed = True
if not changed: break
has_negative_cycle = any(dist[u] + w < dist[v] for u, v, w in edges)
return dist, has_negative_cycle
def run_example(example=EXAMPLE):
return bellman_ford_p233(['A','B','C','D','E','F'], example['sample_input']['weighted_edges'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Bellman-Ford, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Bellman-Ford.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the bellman ford invariant described in the code comments and return a stable, inspectable result for page 233.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 234 / 561Chapter 17: Shortest Paths
Negative cycle detection
Page-local deep read
Mental model for Negative cycle detection: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 234, the goal is not memorizing negative cycle detection; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Negative cycle detection is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Negative cycle detection before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 234: Negative cycle detection
EXAMPLE = {'page': 234, 'topic': 'Negative cycle detection', 'chapter': 'Shortest Paths', 'kind': 'linked_list', 'scenario': 'Run a concrete linked list miniature for Negative cycle detection.', 'sample_input': {'values': [39, 10, 21, 32, 3, 14, 25], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Negative cycle detection', 'watch_for': 'The invariant that makes Negative cycle detection safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the linked list example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='234-negative_cycle_det-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class Node:
def __init__(self, value, next=None): self.value, self.next = value, next
def negative_cycle_detection_p234(head):
prev, node = None, head
while node:
nxt = node.next; node.next = prev; prev = node; node = nxt
return prev
def to_list(head):
out=[]
while head: out.append(head.value); head=head.next
return out
def run_example(example=EXAMPLE):
head = Node(1, Node(2, Node(3)))
return to_list(negative_cycle_detection_p234(head))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Negative cycle detection, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Negative cycle detection.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the linked list invariant described in the code comments and return a stable, inspectable result for page 234.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 235 / 561Chapter 17: Shortest Paths
SPFA caution
Page-local deep read
Mental model for SPFA caution: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 235, the goal is not memorizing spfa caution; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: SPFA caution is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for SPFA caution before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: invalid weight assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 235: SPFA caution
EXAMPLE = {'page': 235, 'topic': 'SPFA caution', 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': 'Run a concrete shortest path miniature for SPFA caution.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for SPFA caution', 'watch_for': 'The invariant that makes SPFA caution safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='235-spfa_caution-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def spfa_caution_p235(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return spfa_caution_p235(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by SPFA caution.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 235.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement spfa caution twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 236 / 561Chapter 17: Shortest Paths
Floyd-Warshall
Page-local deep read
Mental model for Floyd-Warshall: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 236, the goal is not memorizing floyd-warshall; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Floyd-Warshall is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Floyd-Warshall before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: dense all-pairs. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 236: Floyd-Warshall
EXAMPLE = {'page': 236, 'topic': 'Floyd-Warshall', 'chapter': 'Shortest Paths', 'kind': 'floyd_warshall', 'scenario': 'Run a concrete floyd warshall miniature for Floyd-Warshall.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Floyd-Warshall', 'watch_for': 'The invariant that makes Floyd-Warshall safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the floyd warshall example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='236-floyd_warshall-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def floyd_warshall_p236(nodes, edges):
dist = {(i,j): (0 if i==j else float('inf')) for i in nodes for j in nodes}
for u, v, w in edges: dist[(u,v)] = min(dist[(u,v)], w)
for k in nodes:
for i in nodes:
for j in nodes:
dist[(i,j)] = min(dist[(i,j)], dist[(i,k)] + dist[(k,j)])
return dist
def run_example(example=EXAMPLE):
return floyd_warshall_p236(['A','B','C','D','E','F'], example['sample_input']['weighted_edges'])[('A','F')]
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Floyd-Warshall, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Floyd-Warshall.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the floyd warshall invariant described in the code comments and return a stable, inspectable result for page 236.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for floyd-warshall and explain what each one stresses.
Page 237 / 561Chapter 17: Shortest Paths
Johnson's algorithm
Page-local deep read
Mental model for Johnson's algorithm: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 237, the goal is not memorizing johnson's algorithm; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Johnson's algorithm is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Johnson's algorithm before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: invalid weight assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 237: Johnson's algorithm
EXAMPLE = {'page': 237, 'topic': "Johnson's algorithm", 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': "Run a concrete shortest path miniature for Johnson's algorithm.", 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': "Inspectable result for Johnson's algorithm", 'watch_for': "The invariant that makes Johnson's algorithm safe is checked before the next transition.", 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='237-johnson_s_algorith-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def johnson_s_algorithm_p237(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return johnson_s_algorithm_p237(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Johnson's algorithm.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 237.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for johnson's algorithm, then point to the line of code that preserves it.
Page 238 / 561Chapter 17: Shortest Paths
A* search
Page-local deep read
Mental model for A* search: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 238, the goal is not memorizing a* search; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: A* search is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for A* search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for A* search whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: invalid weight assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 238: A* search
EXAMPLE = {'page': 238, 'topic': 'A* search', 'chapter': 'Shortest Paths', 'kind': 'astar', 'scenario': 'Run a concrete astar miniature for A* search.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for A* search', 'watch_for': 'The invariant that makes A* search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the astar example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='238-a_search-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def a_search_p238(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return a_search_p238(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of A* search, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by A* search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the astar invariant described in the code comments and return a stable, inspectable result for page 238.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 239 / 561Chapter 17: Shortest Paths
Bidirectional search
Page-local deep read
Mental model for Bidirectional search: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 239, the goal is not memorizing bidirectional search; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bidirectional search is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bidirectional search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 239: Bidirectional search
EXAMPLE = {'page': 239, 'topic': 'Bidirectional search', 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': 'Run a concrete shortest path miniature for Bidirectional search.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Bidirectional search', 'watch_for': 'The invariant that makes Bidirectional search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='239-bidirectional_sear-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def bidirectional_search_p239(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return bidirectional_search_p239(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Bidirectional search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 239.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 240 / 561Chapter 17: Shortest Paths
Multi-source shortest paths
Page-local deep read
Mental model for Multi-source shortest paths: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 240, the goal is not memorizing multi-source shortest paths; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Multi-source shortest paths is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Multi-source shortest paths before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 240: Multi-source shortest paths
EXAMPLE = {'page': 240, 'topic': 'Multi-source shortest paths', 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': 'Run a concrete shortest path miniature for Multi-source shortest paths.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Multi-source shortest paths', 'watch_for': 'The invariant that makes Multi-source shortest paths safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='240-multi_source_short-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def multi_source_shortest_paths_p240(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return multi_source_shortest_paths_p240(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Multi-source shortest paths.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 240.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement multi-source shortest paths twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 241 / 561Chapter 17: Shortest Paths
Shortest paths on grids
Page-local deep read
Mental model for Shortest paths on grids: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 241, the goal is not memorizing shortest paths on grids; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Shortest paths on grids is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Shortest paths on grids before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: invalid weight assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 241: Shortest paths on grids
EXAMPLE = {'page': 241, 'topic': 'Shortest paths on grids', 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': 'Run a concrete shortest path miniature for Shortest paths on grids.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Shortest paths on grids', 'watch_for': 'The invariant that makes Shortest paths on grids safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='241-shortest_paths_on_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def shortest_paths_on_grids_p241(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return shortest_paths_on_grids_p241(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 241 curation harness: Shortest paths on grids
EXAMPLE_KIND = "shortest_path"
EXAMPLE_TITLE = "Shortest paths on grids"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "241-shortest_paths_on_gr"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "241-shortest_paths_on_gr"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "241-shortest_paths_on_gr"))
Browser JavaScript companion
// Page 241 browser-side experiment: Shortest paths on grids
const pageExample241 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"241-shortest_paths_on_gr"};
function summarizePage241(sample = pageExample241) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Shortest paths on grids",
kind: "shortest_path",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage241());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Shortest paths on grids.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 241.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for shortest paths on grids and explain what each one stresses.
Page 242 / 561Chapter 17: Shortest Paths
Resource-constrained shortest paths
Page-local deep read
Mental model for Resource-constrained shortest paths: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 242, the goal is not memorizing resource-constrained shortest paths; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Resource-constrained shortest paths is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Resource-constrained shortest paths before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 242: Resource-constrained shortest paths
EXAMPLE = {'page': 242, 'topic': 'Resource-constrained shortest paths', 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': 'Run a concrete shortest path miniature for Resource-constrained shortest paths.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Resource-constrained shortest paths', 'watch_for': 'The invariant that makes Resource-constrained shortest paths safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='242-resource_constrain-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def resource_constrained_shortest_paths_p242(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return resource_constrained_shortest_paths_p242(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Resource-constrained shortest paths.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 242.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for resource-constrained shortest paths, then point to the line of code that preserves it.
Page 243 / 561Chapter 17: Shortest Paths
Heuristics and admissibility
Page-local deep read
Mental model for Heuristics and admissibility: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 243, the goal is not memorizing heuristics and admissibility; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Heuristics and admissibility is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Heuristics and admissibility before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as varies by algorithm time and O(V+E) or more space in the common model, then revisit the bound when the input representation changes.
Key risk: invalid weight assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 243: Heuristics and admissibility
EXAMPLE = {'page': 243, 'topic': 'Heuristics and admissibility', 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': 'Run a concrete shortest path miniature for Heuristics and admissibility.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Heuristics and admissibility', 'watch_for': 'The invariant that makes Heuristics and admissibility safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='243-heuristics_and_adm-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def heuristics_and_admissibility_p243(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return heuristics_and_admissibility_p243(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 243 curation harness: Heuristics and admissibility
EXAMPLE_KIND = "shortest_path"
EXAMPLE_TITLE = "Heuristics and admissibility"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "243-heuristics_and_admis"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "243-heuristics_and_admis"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "243-heuristics_and_admis"))
Browser JavaScript companion
// Page 243 browser-side experiment: Heuristics and admissibility
const pageExample243 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"243-heuristics_and_admis"};
function summarizePage243(sample = pageExample243) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Heuristics and admissibility",
kind: "shortest_path",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage243());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Heuristics and admissibility.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 243.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 244 / 561Chapter 17: Shortest Paths
Shortest path testing
Page-local deep read
Mental model for Shortest path testing: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 244, the goal is not memorizing shortest path testing; it is recognizing the representation, the safe transition, and the stopping condition inside the Shortest Paths chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Shortest path testing is one small tool in the larger Shortest Paths toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Shortest path testing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: invalid weight assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Dijkstra's greedy choice is not valid in the presence of negative edge weights.
# Page 244: Shortest path testing
EXAMPLE = {'page': 244, 'topic': 'Shortest path testing', 'chapter': 'Shortest Paths', 'kind': 'shortest_path', 'scenario': 'Run a concrete shortest path miniature for Shortest path testing.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Shortest path testing', 'watch_for': 'The invariant that makes Shortest path testing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the shortest path example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='244-shortest_path_test-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def shortest_path_testing_p244(edges, start):
graph = {}
for u, v, w in edges: graph.setdefault(u, []).append((v, w))
pq, dist = [(0, start)], {start: 0}
while pq:
d, node = heapq.heappop(pq)
if d != dist[node]: continue
for nxt, w in graph.get(node, []):
nd = d + w
if nd < dist.get(nxt, float('inf')):
dist[nxt] = nd; heapq.heappush(pq, (nd, nxt))
return dist
def run_example(example=EXAMPLE):
d=example['sample_input']; return shortest_path_testing_p244(d['weighted_edges'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Shortest path testing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the shortest path invariant described in the code comments and return a stable, inspectable result for page 244.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 245 / 561Chapter 18: Spanning Trees and Connectivity
Spanning tree basics
Page-local deep read
Mental model for Spanning tree basics: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 245, the goal is not memorizing spanning tree basics; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Spanning tree basics is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Spanning tree basics before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 18: Spanning Trees and Connectivity
function kruskal(n, edges) {
const parent = Array.from({length:n}, (_, i) => i); const find = x => parent[x] === x ? x : parent[x] = find(parent[x]);
const chosen = []; for (const [w,u,v] of edges.sort((a,b)=>a[0]-b[0])) { const a = find(u), b = find(v); if (a !== b) { parent[b] = a; chosen.push([u,v,w]); } }
return chosen;
}
console.log(kruskal(4, [[1,0,1],[4,0,2],[2,1,2],[3,2,3]]));
Chapter anchor: This page is the Chapter 18 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Spanning Trees and Connectivity.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: disconnected inputs. Make this risk visible in tests and in code comments.
Common pitfall: An MST only exists for a connected graph; disconnected graphs produce a minimum spanning forest.
# Page 245: Spanning tree basics
EXAMPLE = {'page': 245, 'topic': 'Spanning tree basics', 'chapter': 'Spanning Trees and Connectivity', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Spanning tree basics.', 'sample_input': {'values': [36, 7, 18, 29, 40, 11, 22], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Spanning tree basics', 'watch_for': 'The invariant that makes Spanning tree basics safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='245-spanning_tree_basi-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def spanning_tree_basics_p245(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return spanning_tree_basics_p245(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Spanning tree basics" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 245 curation harness: Spanning tree basics
EXAMPLE_KIND = "tree_alg"
EXAMPLE_TITLE = "Spanning tree basics"
SAMPLE = {
"values": [
36,
7,
18,
29,
40,
11,
22
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "245-spanning_tree_basics"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "245-spanning_tree_basics"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "245-spanning_tree_basics"))
Browser JavaScript companion
// Page 245 browser-side experiment: Spanning tree basics
const pageExample245 = {"values":[36,7,18,29,40,11,22],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"245-spanning_tree_basics"};
function summarizePage245(sample = pageExample245) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Spanning tree basics",
kind: "tree_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage245());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Spanning tree basics.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 245.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement spanning tree basics twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 246 / 561Chapter 18: Spanning Trees and Connectivity
Minimum spanning tree problem
Page-local deep read
Mental model for Minimum spanning tree problem: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 246, the goal is not memorizing minimum spanning tree problem; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Minimum spanning tree problem is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Minimum spanning tree problem before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: disconnected inputs. Make this risk visible in tests and in code comments.
Common pitfall: An MST only exists for a connected graph; disconnected graphs produce a minimum spanning forest.
# Page 246: Minimum spanning tree problem
EXAMPLE = {'page': 246, 'topic': 'Minimum spanning tree problem', 'chapter': 'Spanning Trees and Connectivity', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Minimum spanning tree problem.', 'sample_input': {'values': [3, 14, 25, 36, 7, 18, 29], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Minimum spanning tree problem', 'watch_for': 'The invariant that makes Minimum spanning tree problem safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='246-minimum_spanning_t-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def minimum_spanning_tree_problem_p246(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return minimum_spanning_tree_problem_p246(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Minimum spanning tree problem" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 246 curation harness: Minimum spanning tree problem
EXAMPLE_KIND = "tree_alg"
EXAMPLE_TITLE = "Minimum spanning tree problem"
SAMPLE = {
"values": [
3,
14,
25,
36,
7,
18,
29
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "246-minimum_spanning_tre"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "246-minimum_spanning_tre"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "246-minimum_spanning_tre"))
Browser JavaScript companion
// Page 246 browser-side experiment: Minimum spanning tree problem
const pageExample246 = {"values":[3,14,25,36,7,18,29],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"246-minimum_spanning_tre"};
function summarizePage246(sample = pageExample246) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Minimum spanning tree problem",
kind: "tree_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage246());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Minimum spanning tree problem.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 246.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for minimum spanning tree problem and explain what each one stresses.
Page 247 / 561Chapter 18: Spanning Trees and Connectivity
Kruskal's algorithm
Page-local deep read
Mental model for Kruskal's algorithm: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 247, the goal is not memorizing kruskal's algorithm; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Kruskal's algorithm is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Kruskal's algorithm before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: disconnected inputs. Make this risk visible in tests and in code comments.
Common pitfall: An MST only exists for a connected graph; disconnected graphs produce a minimum spanning forest.
# Page 247: Kruskal's algorithm
EXAMPLE = {'page': 247, 'topic': "Kruskal's algorithm", 'chapter': 'Spanning Trees and Connectivity', 'kind': 'kruskal', 'scenario': "Run a concrete kruskal miniature for Kruskal's algorithm.", 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': "Inspectable result for Kruskal's algorithm", 'watch_for': "The invariant that makes Kruskal's algorithm safe is checked before the next transition.", 'try_next': 'Change the sample input and predict which line in the kruskal example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='247-kruskal_s_algorith-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def kruskal_s_algorithm_p247(nodes, edges):
parent = {x:x for x in nodes}
def find(x):
while parent[x] != x:
parent[x] = parent[parent[x]]; x = parent[x]
return x
tree=[]
for u, v, w in sorted(edges, key=lambda e:e[2]):
ru, rv = find(u), find(v)
if ru != rv:
parent[rv] = ru; tree.append((u,v,w))
return tree
def run_example(example=EXAMPLE):
edges=example['sample_input']['weighted_edges']; return kruskal_s_algorithm_p247(['A','B','C','D','E','F'], edges)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Kruskal's algorithm, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Kruskal's algorithm.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the kruskal invariant described in the code comments and return a stable, inspectable result for page 247.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for kruskal's algorithm, then point to the line of code that preserves it.
Page 248 / 561Chapter 18: Spanning Trees and Connectivity
Prim's algorithm
Page-local deep read
Mental model for Prim's algorithm: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 248, the goal is not memorizing prim's algorithm; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Prim's algorithm is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Prim's algorithm before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Prim's algorithm whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: disconnected inputs. Make this risk visible in tests and in code comments.
Common pitfall: An MST only exists for a connected graph; disconnected graphs produce a minimum spanning forest.
# Page 248: Prim's algorithm
EXAMPLE = {'page': 248, 'topic': "Prim's algorithm", 'chapter': 'Spanning Trees and Connectivity', 'kind': 'prim', 'scenario': "Run a concrete prim miniature for Prim's algorithm.", 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': "Inspectable result for Prim's algorithm", 'watch_for': "The invariant that makes Prim's algorithm safe is checked before the next transition.", 'try_next': 'Change the sample input and predict which line in the prim example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='248-prim_s_algorithm-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def prim_s_algorithm_p248(edges, start):
g={}
for u,v,w in edges:
g.setdefault(u,[]).append((w,v)); g.setdefault(v,[]).append((w,u))
seen, pq, tree = {start}, g[start][:], []
heapq.heapify(pq)
while pq:
w, v = heapq.heappop(pq)
if v in seen: continue
seen.add(v); tree.append((v,w))
for item in g.get(v, []):
if item[1] not in seen: heapq.heappush(pq, item)
return tree
def run_example(example=EXAMPLE):
return prim_s_algorithm_p248(example['sample_input']['weighted_edges'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Prim's algorithm, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Prim's algorithm.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the prim invariant described in the code comments and return a stable, inspectable result for page 248.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 249 / 561Chapter 18: Spanning Trees and Connectivity
Cut property
Page-local deep read
Mental model for Cut property: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 249, the goal is not memorizing cut property; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Cut property is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Cut property before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 249: Cut property
EXAMPLE = {'page': 249, 'topic': 'Cut property', 'chapter': 'Spanning Trees and Connectivity', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Cut property.', 'sample_input': {'values': [24, 35, 6, 17, 28, 39, 10], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Cut property', 'watch_for': 'The invariant that makes Cut property safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='249-cut_property-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cut_property_p249(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return cut_property_p249(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Cut property" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Cut property.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 249.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 250 / 561Chapter 18: Spanning Trees and Connectivity
Cycle property
Page-local deep read
Mental model for Cycle property: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 250, the goal is not memorizing cycle property; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Cycle property is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Cycle property before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 250: Cycle property
EXAMPLE = {'page': 250, 'topic': 'Cycle property', 'chapter': 'Spanning Trees and Connectivity', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Cycle property.', 'sample_input': {'values': [31, 2, 13, 24, 35, 6, 17], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Cycle property', 'watch_for': 'The invariant that makes Cycle property safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='250-cycle_property-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cycle_property_p250(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return cycle_property_p250(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Cycle property" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Cycle property.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 250.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement cycle property twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 251 / 561Chapter 18: Spanning Trees and Connectivity
Boruvka's algorithm
Page-local deep read
Mental model for Boruvka's algorithm: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 251, the goal is not memorizing boruvka's algorithm; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Boruvka's algorithm is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Boruvka's algorithm before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: disconnected inputs. Make this risk visible in tests and in code comments.
Common pitfall: An MST only exists for a connected graph; disconnected graphs produce a minimum spanning forest.
# Page 251: Boruvka's algorithm
EXAMPLE = {'page': 251, 'topic': "Boruvka's algorithm", 'chapter': 'Spanning Trees and Connectivity', 'kind': 'tree_alg', 'scenario': "Run a concrete tree alg miniature for Boruvka's algorithm.", 'sample_input': {'values': [38, 9, 20, 31, 2, 13, 24], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': "Inspectable result for Boruvka's algorithm", 'watch_for': "The invariant that makes Boruvka's algorithm safe is checked before the next transition.", 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='251-boruvka_s_algorith-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def boruvka_s_algorithm_p251(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return boruvka_s_algorithm_p251(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Boruvka's algorithm" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Boruvka's algorithm.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 251.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for boruvka's algorithm and explain what each one stresses.
Page 252 / 561Chapter 18: Spanning Trees and Connectivity
Second-best MST
Page-local deep read
Mental model for Second-best MST: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 252, the goal is not memorizing second-best mst; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Second-best MST is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Second-best MST before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 252: Second-best MST
EXAMPLE = {'page': 252, 'topic': 'Second-best MST', 'chapter': 'Spanning Trees and Connectivity', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Second-best MST.', 'sample_input': {'values': [5, 16, 27, 38, 9, 20, 31], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Second-best MST', 'watch_for': 'The invariant that makes Second-best MST safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='252-second_best_mst-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def second_best_mst_p252(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return second_best_mst_p252(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Second-best MST" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Second-best MST.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 252.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for second-best mst, then point to the line of code that preserves it.
Page 253 / 561Chapter 18: Spanning Trees and Connectivity
Dynamic connectivity
Page-local deep read
Mental model for Dynamic connectivity: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 253, the goal is not memorizing dynamic connectivity; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Dynamic connectivity is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Dynamic connectivity before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 253: Dynamic connectivity
EXAMPLE = {'page': 253, 'topic': 'Dynamic connectivity', 'chapter': 'Spanning Trees and Connectivity', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Dynamic connectivity.', 'sample_input': {'values': [12, 23, 34, 5, 16, 27, 38], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Dynamic connectivity', 'watch_for': 'The invariant that makes Dynamic connectivity safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='253-dynamic_connectivi-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def dynamic_connectivity_p253(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return dynamic_connectivity_p253(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Dynamic connectivity" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Dynamic connectivity.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 253.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 254 / 561Chapter 18: Spanning Trees and Connectivity
Offline connectivity
Page-local deep read
Mental model for Offline connectivity: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 254, the goal is not memorizing offline connectivity; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Offline connectivity is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Offline connectivity before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: disconnected inputs. Make this risk visible in tests and in code comments.
Common pitfall: An MST only exists for a connected graph; disconnected graphs produce a minimum spanning forest.
# Page 254: Offline connectivity
EXAMPLE = {'page': 254, 'topic': 'Offline connectivity', 'chapter': 'Spanning Trees and Connectivity', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Offline connectivity.', 'sample_input': {'values': [19, 30, 1, 12, 23, 34, 5], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Offline connectivity', 'watch_for': 'The invariant that makes Offline connectivity safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='254-offline_connectivi-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def offline_connectivity_p254(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return offline_connectivity_p254(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Offline connectivity" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Offline connectivity.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 254.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 255 / 561Chapter 18: Spanning Trees and Connectivity
Bridge-connected components
Page-local deep read
Mental model for Bridge-connected components: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 255, the goal is not memorizing bridge-connected components; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bridge-connected components is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bridge-connected components before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: visited-state correctness. Make this risk visible in tests and in code comments.
Common pitfall: An MST only exists for a connected graph; disconnected graphs produce a minimum spanning forest.
# Page 255: Bridge-connected components
EXAMPLE = {'page': 255, 'topic': 'Bridge-connected components', 'chapter': 'Spanning Trees and Connectivity', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Bridge-connected components.', 'sample_input': {'values': [26, 37, 8, 19, 30, 1, 12], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Bridge-connected components', 'watch_for': 'The invariant that makes Bridge-connected components safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='255-bridge_connected_c-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def bridge_connected_components_p255(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return bridge_connected_components_p255(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Bridge-connected components" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Bridge-connected components.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 255.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement bridge-connected components twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 256 / 561Chapter 18: Spanning Trees and Connectivity
Connectivity project lab
Page-local deep read
Mental model for Connectivity project lab: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 256, the goal is not memorizing connectivity project lab; it is recognizing the representation, the safe transition, and the stopping condition inside the Spanning Trees and Connectivity chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Connectivity project lab is one small tool in the larger Spanning Trees and Connectivity toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Connectivity project lab before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: disconnected inputs. Make this risk visible in tests and in code comments.
Common pitfall: An MST only exists for a connected graph; disconnected graphs produce a minimum spanning forest.
# Page 256: Connectivity project lab
EXAMPLE = {'page': 256, 'topic': 'Connectivity project lab', 'chapter': 'Spanning Trees and Connectivity', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Connectivity project lab.', 'sample_input': {'values': [33, 4, 15, 26, 37, 8, 19], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Connectivity project lab', 'watch_for': 'The invariant that makes Connectivity project lab safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='256-connectivity_proje-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def connectivity_project_lab_p256(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return connectivity_project_lab_p256(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Connectivity project lab" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Connectivity project lab.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 256.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for connectivity project lab and explain what each one stresses.
Page 257 / 561Chapter 19: Network Flow and Matching
Flow networks
Page-local deep read
Mental model for Flow networks: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 257, the goal is not memorizing flow networks; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Flow networks is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Flow networks before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
This is a chapter-level anchor example. Read it alongside the page-specific labs lower down.
from collections import deque, defaultdict
def edmonds_karp(capacity: dict[str, dict[str, int]], source: str, sink: str) -> int:
residual = defaultdict(dict)
for u, nbrs in capacity.items():
for v, cap in nbrs.items():
residual[u][v] = cap
residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}
q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent:
parent[v] = u
q.append(v)
if sink not in parent:
return flow
aug = float('inf')
v = sink
while v != source:
u = parent[v]
aug = min(aug, residual[u][v])
v = u
v = sink
while v != source:
u = parent[v]
residual[u][v] -= aug
residual[v][u] += aug
v = u
flow += aug
capacity = {'s': {'a': 3, 'b': 2}, 'a': {'b': 1, 't': 2}, 'b': {'t': 3}, 't': {}}
print(edmonds_karp(capacity, 's', 't'))
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 19: Network Flow and Matching
function edmondsKarp(capacity, source, sink) {
const residual = JSON.parse(JSON.stringify(capacity)); for (const u in residual) for (const v in residual[u]) { residual[v] ??= {}; residual[v][u] ??= 0; }
let flow = 0;
while (true) { const parent = {[source]: null}, q = [source]; for (let i=0; i<q.length && !(sink in parent); i++) for (const [v,c] of Object.entries(residual[q[i]] ?? {})) if (c > 0 && !(v in parent)) { parent[v]=q[i]; q.push(v); }
if (!(sink in parent)) return flow; let aug = Infinity; for (let v=sink; v!==source; v=parent[v]) aug = Math.min(aug, residual[parent[v]][v]); for (let v=sink; v!==source; v=parent[v]) { residual[parent[v]][v]-=aug; residual[v][parent[v]]+=aug; } flow += aug; }
}
console.log(edmondsKarp({s:{a:3,b:2},a:{b:1,t:2},b:{t:3},t:{}}, 's', 't'));
Chapter anchor: This page is the Chapter 19 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Network Flow and Matching.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: wrong residual updates. Make this risk visible in tests and in code comments.
Common pitfall: Most flow bugs are caused by updating only the forward edge and forgetting the reverse residual capacity.
# Page 257: Flow networks
EXAMPLE = {'page': 257, 'topic': 'Flow networks', 'chapter': 'Network Flow and Matching', 'kind': 'flow', 'scenario': 'Run a concrete flow miniature for Flow networks.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Flow networks', 'watch_for': 'The invariant that makes Flow networks safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the flow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='257-flow_networks-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def flow_networks_p257(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return flow_networks_p257({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Flow networks.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the flow invariant described in the code comments and return a stable, inspectable result for page 257.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for flow networks, then point to the line of code that preserves it.
Page 258 / 561Chapter 19: Network Flow and Matching
Residual graphs
Page-local deep read
Mental model for Residual graphs: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 258, the goal is not memorizing residual graphs; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Residual graphs is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Residual graphs before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Residual graphs whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: wrong residual updates. Make this risk visible in tests and in code comments.
Common pitfall: Most flow bugs are caused by updating only the forward edge and forgetting the reverse residual capacity.
# Page 258: Residual graphs
EXAMPLE = {'page': 258, 'topic': 'Residual graphs', 'chapter': 'Network Flow and Matching', 'kind': 'flow', 'scenario': 'Run a concrete flow miniature for Residual graphs.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Residual graphs', 'watch_for': 'The invariant that makes Residual graphs safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the flow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='258-residual_graphs-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def residual_graphs_p258(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return residual_graphs_p258({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Residual graphs.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the flow invariant described in the code comments and return a stable, inspectable result for page 258.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 259 / 561Chapter 19: Network Flow and Matching
Ford-Fulkerson
Page-local deep read
Mental model for Ford-Fulkerson: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 259, the goal is not memorizing ford-fulkerson; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Ford-Fulkerson is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Ford-Fulkerson before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 259: Ford-Fulkerson
EXAMPLE = {'page': 259, 'topic': 'Ford-Fulkerson', 'chapter': 'Network Flow and Matching', 'kind': 'ford_fulkerson', 'scenario': 'Run a concrete ford fulkerson miniature for Ford-Fulkerson.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Ford-Fulkerson', 'watch_for': 'The invariant that makes Ford-Fulkerson safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the ford fulkerson example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='259-ford_fulkerson-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def ford_fulkerson_p259(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return ford_fulkerson_p259({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Ford-Fulkerson, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Ford-Fulkerson.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the ford fulkerson invariant described in the code comments and return a stable, inspectable result for page 259.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 260 / 561Chapter 19: Network Flow and Matching
Edmonds-Karp
Page-local deep read
Mental model for Edmonds-Karp: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 260, the goal is not memorizing edmonds-karp; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Edmonds-Karp is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Edmonds-Karp before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 260: Edmonds-Karp
EXAMPLE = {'page': 260, 'topic': 'Edmonds-Karp', 'chapter': 'Network Flow and Matching', 'kind': 'edmonds_karp', 'scenario': 'Run a concrete edmonds karp miniature for Edmonds-Karp.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Edmonds-Karp', 'watch_for': 'The invariant that makes Edmonds-Karp safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the edmonds karp example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='260-edmonds_karp-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def edmonds_karp_p260(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return edmonds_karp_p260({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Edmonds-Karp, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Edmonds-Karp.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the edmonds karp invariant described in the code comments and return a stable, inspectable result for page 260.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement edmonds-karp twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 261 / 561Chapter 19: Network Flow and Matching
Dinic's algorithm intuition
Page-local deep read
Mental model for Dinic's algorithm intuition: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 261, the goal is not memorizing dinic's algorithm intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Dinic's algorithm intuition is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Dinic's algorithm intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: wrong residual updates. Make this risk visible in tests and in code comments.
Common pitfall: Most flow bugs are caused by updating only the forward edge and forgetting the reverse residual capacity.
# Page 261: Dinic's algorithm intuition
EXAMPLE = {'page': 261, 'topic': "Dinic's algorithm intuition", 'chapter': 'Network Flow and Matching', 'kind': 'flow', 'scenario': "Run a concrete flow miniature for Dinic's algorithm intuition.", 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': "Inspectable result for Dinic's algorithm intuition", 'watch_for': "The invariant that makes Dinic's algorithm intuition safe is checked before the next transition.", 'try_next': 'Change the sample input and predict which line in the flow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='261-dinic_s_algorithm_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def dinic_s_algorithm_intuition_p261(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return dinic_s_algorithm_intuition_p261({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Dinic's algorithm intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the flow invariant described in the code comments and return a stable, inspectable result for page 261.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for dinic's algorithm intuition and explain what each one stresses.
Page 262 / 561Chapter 19: Network Flow and Matching
Min-cut max-flow theorem
Page-local deep read
Mental model for Min-cut max-flow theorem: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 262, the goal is not memorizing min-cut max-flow theorem; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Min-cut max-flow theorem is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Min-cut max-flow theorem before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 262: Min-cut max-flow theorem
EXAMPLE = {'page': 262, 'topic': 'Min-cut max-flow theorem', 'chapter': 'Network Flow and Matching', 'kind': 'flow', 'scenario': 'Run a concrete flow miniature for Min-cut max-flow theorem.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Min-cut max-flow theorem', 'watch_for': 'The invariant that makes Min-cut max-flow theorem safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the flow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='262-min_cut_max_flow_t-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def min_cut_max_flow_theorem_p262(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return min_cut_max_flow_theorem_p262({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Min-cut max-flow theorem.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the flow invariant described in the code comments and return a stable, inspectable result for page 262.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for min-cut max-flow theorem, then point to the line of code that preserves it.
Page 263 / 561Chapter 19: Network Flow and Matching
Bipartite matching as flow
Page-local deep read
Mental model for Bipartite matching as flow: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 263, the goal is not memorizing bipartite matching as flow; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bipartite matching as flow is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bipartite matching as flow before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 263: Bipartite matching as flow
EXAMPLE = {'page': 263, 'topic': 'Bipartite matching as flow', 'chapter': 'Network Flow and Matching', 'kind': 'graph', 'scenario': 'Run a concrete graph miniature for Bipartite matching as flow.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Bipartite matching as flow', 'watch_for': 'The invariant that makes Bipartite matching as flow safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the graph example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='263-bipartite_matching-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque
def bipartite_matching_as_flow_p263(graph, start):
q, seen, order = deque([start]), {start}, []
while q:
node = q.popleft(); order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt); q.append(nxt)
return order
def run_example(example=EXAMPLE):
d=example['sample_input']; return bipartite_matching_as_flow_p263(d['graph'], d['start'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Bipartite matching as flow" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 263 curation harness: Bipartite matching as flow
EXAMPLE_KIND = "graph"
EXAMPLE_TITLE = "Bipartite matching as flow"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "263-bipartite_matching_a"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "263-bipartite_matching_a"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "263-bipartite_matching_a"))
Browser JavaScript companion
// Page 263 browser-side experiment: Bipartite matching as flow
const pageExample263 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"263-bipartite_matching_a"};
function summarizePage263(sample = pageExample263) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Bipartite matching as flow",
kind: "graph",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage263());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Bipartite matching as flow.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the graph invariant described in the code comments and return a stable, inspectable result for page 263.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 264 / 561Chapter 19: Network Flow and Matching
Hopcroft-Karp
Page-local deep read
Mental model for Hopcroft-Karp: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 264, the goal is not memorizing hopcroft-karp; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Hopcroft-Karp is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Hopcroft-Karp before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: wrong residual updates. Make this risk visible in tests and in code comments.
Common pitfall: Most flow bugs are caused by updating only the forward edge and forgetting the reverse residual capacity.
# Page 264: Hopcroft-Karp
EXAMPLE = {'page': 264, 'topic': 'Hopcroft-Karp', 'chapter': 'Network Flow and Matching', 'kind': 'hopcroft_karp', 'scenario': 'Run a concrete hopcroft karp miniature for Hopcroft-Karp.', 'sample_input': {'values': [9, 20, 31, 2, 13, 24, 35], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Hopcroft-Karp', 'watch_for': 'The invariant that makes Hopcroft-Karp safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the hopcroft karp example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='264-hopcroft_karp-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def hopcroft_karp_p264(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return hopcroft_karp_p264(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Hopcroft-Karp, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Hopcroft-Karp.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hopcroft karp invariant described in the code comments and return a stable, inspectable result for page 264.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 265 / 561Chapter 19: Network Flow and Matching
Assignment problem
Page-local deep read
Mental model for Assignment problem: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 265, the goal is not memorizing assignment problem; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Assignment problem is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Assignment problem before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: wrong residual updates. Make this risk visible in tests and in code comments.
Common pitfall: Most flow bugs are caused by updating only the forward edge and forgetting the reverse residual capacity.
# Page 265: Assignment problem
EXAMPLE = {'page': 265, 'topic': 'Assignment problem', 'chapter': 'Network Flow and Matching', 'kind': 'flow', 'scenario': 'Run a concrete flow miniature for Assignment problem.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Assignment problem', 'watch_for': 'The invariant that makes Assignment problem safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the flow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='265-assignment_problem-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def assignment_problem_p265(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return assignment_problem_p265({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Assignment problem.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the flow invariant described in the code comments and return a stable, inspectable result for page 265.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement assignment problem twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 266 / 561Chapter 19: Network Flow and Matching
Min-cost max-flow
Page-local deep read
Mental model for Min-cost max-flow: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 266, the goal is not memorizing min-cost max-flow; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Min-cost max-flow is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Min-cost max-flow before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: wrong residual updates. Make this risk visible in tests and in code comments.
Common pitfall: Most flow bugs are caused by updating only the forward edge and forgetting the reverse residual capacity.
# Page 266: Min-cost max-flow
EXAMPLE = {'page': 266, 'topic': 'Min-cost max-flow', 'chapter': 'Network Flow and Matching', 'kind': 'flow', 'scenario': 'Run a concrete flow miniature for Min-cost max-flow.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Min-cost max-flow', 'watch_for': 'The invariant that makes Min-cost max-flow safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the flow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='266-min_cost_max_flow-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def min_cost_max_flow_p266(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return min_cost_max_flow_p266({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Min-cost max-flow.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the flow invariant described in the code comments and return a stable, inspectable result for page 266.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for min-cost max-flow and explain what each one stresses.
Page 267 / 561Chapter 19: Network Flow and Matching
Circulations and demands
Page-local deep read
Mental model for Circulations and demands: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 267, the goal is not memorizing circulations and demands; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Circulations and demands is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Circulations and demands before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: wrong residual updates. Make this risk visible in tests and in code comments.
Common pitfall: Most flow bugs are caused by updating only the forward edge and forgetting the reverse residual capacity.
# Page 267: Circulations and demands
EXAMPLE = {'page': 267, 'topic': 'Circulations and demands', 'chapter': 'Network Flow and Matching', 'kind': 'flow', 'scenario': 'Run a concrete flow miniature for Circulations and demands.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Circulations and demands', 'watch_for': 'The invariant that makes Circulations and demands safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the flow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='267-circulations_and_d-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def circulations_and_demands_p267(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return circulations_and_demands_p267({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 267 curation harness: Circulations and demands
EXAMPLE_KIND = "flow"
EXAMPLE_TITLE = "Circulations and demands"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
],
[
"E",
"F",
1
]
],
"start": "A",
"goal": "F",
"page_marker": "267-circulations_and_dem"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "267-circulations_and_dem"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "267-circulations_and_dem"))
Browser JavaScript companion
// Page 267 browser-side experiment: Circulations and demands
const pageExample267 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3],["E","F",1]],"start":"A","goal":"F","page_marker":"267-circulations_and_dem"};
function summarizePage267(sample = pageExample267) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Circulations and demands",
kind: "flow",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage267());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Circulations and demands.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the flow invariant described in the code comments and return a stable, inspectable result for page 267.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for circulations and demands, then point to the line of code that preserves it.
Page 268 / 561Chapter 19: Network Flow and Matching
Flow modeling patterns
Page-local deep read
Mental model for Flow modeling patterns: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 268, the goal is not memorizing flow modeling patterns; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Flow modeling patterns is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Flow modeling patterns before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Flow modeling patterns whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: wrong residual updates. Make this risk visible in tests and in code comments.
Common pitfall: Most flow bugs are caused by updating only the forward edge and forgetting the reverse residual capacity.
# Page 268: Flow modeling patterns
EXAMPLE = {'page': 268, 'topic': 'Flow modeling patterns', 'chapter': 'Network Flow and Matching', 'kind': 'flow', 'scenario': 'Run a concrete flow miniature for Flow modeling patterns.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Flow modeling patterns', 'watch_for': 'The invariant that makes Flow modeling patterns safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the flow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='268-flow_modeling_patt-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def flow_modeling_patterns_p268(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return flow_modeling_patterns_p268({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Flow modeling patterns.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the flow invariant described in the code comments and return a stable, inspectable result for page 268.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 269 / 561Chapter 19: Network Flow and Matching
Matching edge cases
Page-local deep read
Mental model for Matching edge cases: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 269, the goal is not memorizing matching edge cases; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Matching edge cases is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Matching edge cases before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 269: Matching edge cases
EXAMPLE = {'page': 269, 'topic': 'Matching edge cases', 'chapter': 'Network Flow and Matching', 'kind': 'flow', 'scenario': 'Run a concrete flow miniature for Matching edge cases.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Matching edge cases', 'watch_for': 'The invariant that makes Matching edge cases safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the flow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='269-matching_edge_case-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def matching_edge_cases_p269(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return matching_edge_cases_p269({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['graph'], then compare it with the first line produced by Matching edge cases.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the flow invariant described in the code comments and return a stable, inspectable result for page 269.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 270 / 561Chapter 19: Network Flow and Matching
Flow implementation tests
Page-local deep read
Mental model for Flow implementation tests: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 270, the goal is not memorizing flow implementation tests; it is recognizing the representation, the safe transition, and the stopping condition inside the Network Flow and Matching chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Flow implementation tests is one small tool in the larger Network Flow and Matching toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Flow implementation tests before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 270: Flow implementation tests
EXAMPLE = {'page': 270, 'topic': 'Flow implementation tests', 'chapter': 'Network Flow and Matching', 'kind': 'flow', 'scenario': 'Run a concrete flow miniature for Flow implementation tests.', 'sample_input': {'graph': {'A': ['B', 'C'], 'B': ['D'], 'C': ['D', 'E'], 'D': ['F'], 'E': ['F'], 'F': []}, 'weighted_edges': [('A', 'B', 2), ('A', 'C', 5), ('B', 'D', 1), ('C', 'D', 2), ('D', 'F', 3), ('E', 'F', 1)], 'start': 'A', 'goal': 'F'}, 'expected_output': 'Inspectable result for Flow implementation tests', 'watch_for': 'The invariant that makes Flow implementation tests safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the flow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='270-flow_implementatio-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import deque, defaultdict
def flow_implementation_tests_p270(capacities, source, sink):
residual = defaultdict(dict)
for (u, v), cap in capacities.items(): residual[u][v] = cap; residual[v].setdefault(u, 0)
flow = 0
while True:
parent = {source: None}; q = deque([source])
while q and sink not in parent:
u = q.popleft()
for v, cap in residual[u].items():
if cap > 0 and v not in parent: parent[v] = u; q.append(v)
if sink not in parent: return flow
inc, v = float('inf'), sink
while parent[v] is not None:
u = parent[v]; inc = min(inc, residual[u][v]); v = u
v = sink
while parent[v] is not None:
u = parent[v]; residual[u][v] -= inc; residual[v][u] += inc; v = u
flow += inc
def run_example(example=EXAMPLE):
return flow_implementation_tests_p270({('s','a'):3,('s','b'):2,('a','b'):1,('a','t'):2,('b','t'):3}, 's', 't')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for What makes a problem dynamic programming: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 271, the goal is not memorizing what makes a problem dynamic programming; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: What makes a problem dynamic programming is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for What makes a problem dynamic programming before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 20: Dynamic Programming Foundations
function knapsack(weights, values, capacity) {
const dp = Array(capacity + 1).fill(0);
for (let i = 0; i < weights.length; i++) for (let c = capacity; c >= weights[i]; c--) dp[c] = Math.max(dp[c], dp[c - weights[i]] + values[i]);
return dp[capacity];
}
console.log(knapsack([2,3,4,5], [3,4,5,8], 8));
Chapter anchor: This page is the Chapter 20 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Dynamic Programming Foundations.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
# Page 271: What makes a problem dynamic programming
EXAMPLE = {'page': 271, 'topic': 'What makes a problem dynamic programming', 'chapter': 'Dynamic Programming Foundations', 'kind': 'dp', 'scenario': 'Run a concrete dp miniature for What makes a problem dynamic programming.', 'sample_input': {'n': 7, 'values': [3, 1, 4, 1, 5, 9, 2], 'text_a': 'ALGORITHM', 'text_b': 'LOGARITHM', 'weights': [2, 3, 4, 5], 'profits': [3, 4, 5, 8], 'capacity': 8}, 'expected_output': 'Inspectable result for What makes a problem dynamic programming', 'watch_for': 'The invariant that makes What makes a problem dynamic programming safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dp example changes first.', 'docs': [('Python functools.cache/lru_cache', 'https://docs.python.org/3/library/functools.html')]}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='271-what_makes_a_probl-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def what_makes_a_problem_dynamic_programming_p271(n):
dp = [0] * (n + 2); dp[0], dp[1] = 1, 1
for i in range(2, n + 1): dp[i] = dp[i-1] + dp[i-2]
return {'ways': dp[n], 'table': dp[:n+1]}
def run_example(example=EXAMPLE):
return what_makes_a_problem_dynamic_programming_p271(example['sample_input']['n'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Choose n and see a Fibonacci table fill from base cases upward.
Manual review notes for students
What to inspect first
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "What makes a problem dynamic programming" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 271 curation harness: What makes a problem dynamic programming
EXAMPLE_KIND = "dp"
EXAMPLE_TITLE = "What makes a problem dynamic programming"
SAMPLE = {
"n": 7,
"values": [
3,
1,
4,
1,
5,
9,
2
],
"text_a": "ALGORITHM",
"text_b": "LOGARITHM",
"weights": [
2,
3,
4,
5
],
"profits": [
3,
4,
5,
8
],
"capacity": 8,
"page_marker": "271-what_makes_a_problem"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "271-what_makes_a_problem"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "271-what_makes_a_problem"))
Browser JavaScript companion
// Page 271 browser-side experiment: What makes a problem dynamic programming
const pageExample271 = {"n":7,"values":[3,1,4,1,5,9,2],"text_a":"ALGORITHM","text_b":"LOGARITHM","weights":[2,3,4,5],"profits":[3,4,5,8],"capacity":8,"page_marker":"271-what_makes_a_problem"};
function summarizePage271(sample = pageExample271) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "What makes a problem dynamic programming",
kind: "dp",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage271());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by What makes a problem dynamic programming.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dp invariant described in the code comments and return a stable, inspectable result for page 271.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for what makes a problem dynamic programming and explain what each one stresses.
Mental model for State definition: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 272, the goal is not memorizing state definition; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: State definition is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for State definition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "State definition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Transition design: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 273, the goal is not memorizing transition design; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Transition design is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Transition design before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as states × transition cost time and state table space in the common model, then revisit the bound when the input representation changes.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Transition design" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Top-down memoization: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 274, the goal is not memorizing top-down memoization; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Top-down memoization is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Top-down memoization before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
# Page 274: Top-down memoization
EXAMPLE = {'page': 274, 'topic': 'Top-down memoization', 'chapter': 'Dynamic Programming Foundations', 'kind': 'memoized_recursion', 'scenario': 'Run a concrete memoized recursion miniature for Top-down memoization.', 'sample_input': {'values': [39, 10, 21, 32, 3, 14, 25], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Top-down memoization', 'watch_for': 'The invariant that makes Top-down memoization safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the memoized recursion example changes first.', 'docs': [('Python functools.cache/lru_cache', 'https://docs.python.org/3/library/functools.html')]}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='274-top_down_memoizati-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def top_down_memoization_p274(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return top_down_memoization_p274(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Top-down memoization, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Bottom-up tabulation: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 275, the goal is not memorizing bottom-up tabulation; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bottom-up tabulation is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bottom-up tabulation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Bottom-up tabulation" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for DAG view of DP: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 276, the goal is not memorizing dag view of dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DAG view of DP is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DAG view of DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "DAG view of DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Ordering states: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 277, the goal is not memorizing ordering states; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Ordering states is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Ordering states before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Ordering states" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Base cases: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 278, the goal is not memorizing base cases; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Base cases is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Base cases before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Base cases whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
# Page 278: Base cases
EXAMPLE = {'page': 278, 'topic': 'Base cases', 'chapter': 'Dynamic Programming Foundations', 'kind': 'recursion_pattern', 'scenario': 'Run a concrete recursion pattern miniature for Base cases.', 'sample_input': {'values': [27, 38, 9, 20, 31, 2, 13], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Base cases', 'watch_for': 'The invariant that makes Base cases safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the recursion pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='278-base_cases-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def base_cases_p278(base, exponent):
if exponent == 0: return 1
half = base_cases_p278(base, exponent // 2)
return half * half if exponent % 2 == 0 else half * half * base
def trace_power(base, exponent):
return {'base': base, 'exponent': exponent, 'value': base_cases_p278(base, exponent)}
def run_example(example=EXAMPLE):
return trace_power(3, 7)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Base cases, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Space optimization: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 279, the goal is not memorizing space optimization; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Space optimization is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Space optimization before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Space optimization" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Recovering decisions: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 280, the goal is not memorizing recovering decisions; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Recovering decisions is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Recovering decisions before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Recovering decisions" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Counting versus optimization DP: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 281, the goal is not memorizing counting versus optimization dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Counting versus optimization DP is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Counting versus optimization DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Counting versus optimization DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Expected value DP: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 282, the goal is not memorizing expected value dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Expected value DP is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Expected value DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Expected value DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for DP correctness proofs: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 283, the goal is not memorizing dp correctness proofs; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DP correctness proofs is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DP correctness proofs before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as states × transition cost time and state table space in the common model, then revisit the bound when the input representation changes.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "DP correctness proofs" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for DP complexity accounting: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 284, the goal is not memorizing dp complexity accounting; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DP complexity accounting is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DP complexity accounting before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "DP complexity accounting" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Rolling arrays: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 285, the goal is not memorizing rolling arrays; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rolling arrays is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rolling arrays before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Rolling arrays" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Sentinel states: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 286, the goal is not memorizing sentinel states; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sentinel states is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sentinel states before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
# Page 286: Sentinel states
EXAMPLE = {'page': 286, 'topic': 'Sentinel states', 'chapter': 'Dynamic Programming Foundations', 'kind': 'sentinel_scan', 'scenario': 'Run a concrete sentinel scan miniature for Sentinel states.', 'sample_input': {'values': [3, 14, 25, 36, 7, 18, 29], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Sentinel states', 'watch_for': 'The invariant that makes Sentinel states safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sentinel scan example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='286-sentinel_states-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def sentinel_states_p286(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return sentinel_states_p286(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Sentinel states, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Memoization cache keys: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 287, the goal is not memorizing memoization cache keys; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Memoization cache keys is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Memoization cache keys before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Memoization cache keys, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for DP debugging worksheet: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 288, the goal is not memorizing dp debugging worksheet; it is recognizing the representation, the safe transition, and the stopping condition inside the Dynamic Programming Foundations chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DP debugging worksheet is one small tool in the larger Dynamic Programming Foundations toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DP debugging worksheet before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for DP debugging worksheet whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A DP with a vague state often leads to duplicate states, missing information, or an exponential transition loop.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "DP debugging worksheet" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by DP debugging worksheet.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dp invariant described in the code comments and return a stable, inspectable result for page 288.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 289 / 561Chapter 21: Sequence and String Dynamic Programming
Fibonacci as a tiny DP
Page-local deep read
Mental model for Fibonacci as a tiny DP: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 289, the goal is not memorizing fibonacci as a tiny dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Fibonacci as a tiny DP is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Fibonacci as a tiny DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 21: Sequence and String Dynamic Programming
function lcs(a, b) {
const dp = Array.from({length:a.length+1}, () => Array(b.length+1).fill(0));
for (let i=1;i<=a.length;i++) for (let j=1;j<=b.length;j++) dp[i][j] = a[i-1] === b[j-1] ? dp[i-1][j-1]+1 : Math.max(dp[i-1][j], dp[i][j-1]);
return dp[a.length][b.length];
}
console.log(lcs('algorithm', 'logarithm'));
Chapter anchor: This page is the Chapter 21 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Sequence and String Dynamic Programming.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Fibonacci as a tiny DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 289 curation harness: Fibonacci as a tiny DP
EXAMPLE_KIND = "fibonacci_dp"
EXAMPLE_TITLE = "Fibonacci as a tiny DP"
SAMPLE = {
"n": 7,
"values": [
3,
1,
4,
1,
5,
9,
2
],
"text_a": "ALGORITHM",
"text_b": "LOGARITHM",
"weights": [
2,
3,
4,
5
],
"profits": [
3,
4,
5,
8
],
"capacity": 8,
"page_marker": "289-fibonacci_as_a_tiny_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "289-fibonacci_as_a_tiny_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "289-fibonacci_as_a_tiny_"))
Browser JavaScript companion
// Page 289 browser-side experiment: Fibonacci as a tiny DP
const pageExample289 = {"n":7,"values":[3,1,4,1,5,9,2],"text_a":"ALGORITHM","text_b":"LOGARITHM","weights":[2,3,4,5],"profits":[3,4,5,8],"capacity":8,"page_marker":"289-fibonacci_as_a_tiny_"};
function summarizePage289(sample = pageExample289) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Fibonacci as a tiny DP",
kind: "fibonacci_dp",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage289());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Fibonacci as a tiny DP.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the fibonacci dp invariant described in the code comments and return a stable, inspectable result for page 289.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 290 / 561Chapter 21: Sequence and String Dynamic Programming
Climbing stairs
Page-local deep read
Mental model for Climbing stairs: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 290, the goal is not memorizing climbing stairs; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Climbing stairs is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Climbing stairs before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 290: Climbing stairs
EXAMPLE = {'page': 290, 'topic': 'Climbing stairs', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'climbing_stairs', 'scenario': 'Run a concrete climbing stairs miniature for Climbing stairs.', 'sample_input': {'n': 8, 'values': [3, 1, 4, 1, 5, 9, 2], 'text_a': 'ALGORITHM', 'text_b': 'LOGARITHM', 'weights': [2, 3, 4, 5], 'profits': [3, 4, 5, 8], 'capacity': 8}, 'expected_output': 'Inspectable result for Climbing stairs', 'watch_for': 'The invariant that makes Climbing stairs safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the climbing stairs example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='290-climbing_stairs-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def climbing_stairs_p290(n):
dp = [0] * (n + 2); dp[0], dp[1] = 1, 1
for i in range(2, n + 1): dp[i] = dp[i-1] + dp[i-2]
return {'ways': dp[n], 'table': dp[:n+1]}
def run_example(example=EXAMPLE):
return climbing_stairs_p290(example['sample_input']['n'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track n, values, text_a, text_b before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Climbing stairs, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Climbing stairs.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the climbing stairs invariant described in the code comments and return a stable, inspectable result for page 290.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement climbing stairs twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 291 / 561Chapter 21: Sequence and String Dynamic Programming
Longest increasing subsequence
Page-local deep read
Mental model for Longest increasing subsequence: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 291, the goal is not memorizing longest increasing subsequence; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Longest increasing subsequence is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Longest increasing subsequence before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
# Page 291: Longest increasing subsequence
EXAMPLE = {'page': 291, 'topic': 'Longest increasing subsequence', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'lis', 'scenario': 'Run a concrete lis miniature for Longest increasing subsequence.', 'sample_input': {'n': 9, 'values': [3, 1, 4, 1, 5, 9, 2], 'text_a': 'ALGORITHM', 'text_b': 'LOGARITHM', 'weights': [2, 3, 4, 5], 'profits': [3, 4, 5, 8], 'capacity': 8}, 'expected_output': 'Inspectable result for Longest increasing subsequence', 'watch_for': 'The invariant that makes Longest increasing subsequence safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the lis example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='291-longest_increasing-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from bisect import bisect_left
def longest_increasing_subsequence_p291(values):
tails = []
for value in values:
i = bisect_left(tails, value)
if i == len(tails): tails.append(value)
else: tails[i] = value
return len(tails), tails
def run_example(example=EXAMPLE):
return longest_increasing_subsequence_p291(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track n, values, text_a, text_b before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Longest increasing subsequence, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Longest increasing subsequence.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the lis invariant described in the code comments and return a stable, inspectable result for page 291.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for longest increasing subsequence and explain what each one stresses.
Page 292 / 561Chapter 21: Sequence and String Dynamic Programming
Longest common subsequence
Page-local deep read
Mental model for Longest common subsequence: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 292, the goal is not memorizing longest common subsequence; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Longest common subsequence is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Longest common subsequence before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 292: Longest common subsequence
EXAMPLE = {'page': 292, 'topic': 'Longest common subsequence', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'lcs', 'scenario': 'Run a concrete lcs miniature for Longest common subsequence.', 'sample_input': {'n': 10, 'values': [3, 1, 4, 1, 5, 9, 2], 'text_a': 'ALGORITHM', 'text_b': 'LOGARITHM', 'weights': [2, 3, 4, 5], 'profits': [3, 4, 5, 8], 'capacity': 8}, 'expected_output': 'Inspectable result for Longest common subsequence', 'watch_for': 'The invariant that makes Longest common subsequence safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the lcs example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='292-longest_common_sub-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def longest_common_subsequence_p292(a, b):
dp = [[0]*(len(b)+1) for _ in range(len(a)+1)]
for i, ca in enumerate(a, 1):
for j, cb in enumerate(b, 1):
dp[i][j] = dp[i-1][j-1]+1 if ca==cb else max(dp[i-1][j], dp[i][j-1])
return dp[-1][-1]
def run_example(example=EXAMPLE):
d=example['sample_input']; return longest_common_subsequence_p292(d['text_a'], d['text_b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track n, values, text_a, text_b before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Longest common subsequence, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 292 curation harness: Longest common subsequence
EXAMPLE_KIND = "lcs"
EXAMPLE_TITLE = "Longest common subsequence"
SAMPLE = {
"n": 10,
"values": [
3,
1,
4,
1,
5,
9,
2
],
"text_a": "ALGORITHM",
"text_b": "LOGARITHM",
"weights": [
2,
3,
4,
5
],
"profits": [
3,
4,
5,
8
],
"capacity": 8,
"page_marker": "292-longest_common_subse"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "292-longest_common_subse"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "292-longest_common_subse"))
Browser JavaScript companion
// Page 292 browser-side experiment: Longest common subsequence
const pageExample292 = {"n":10,"values":[3,1,4,1,5,9,2],"text_a":"ALGORITHM","text_b":"LOGARITHM","weights":[2,3,4,5],"profits":[3,4,5,8],"capacity":8,"page_marker":"292-longest_common_subse"};
function summarizePage292(sample = pageExample292) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Longest common subsequence",
kind: "lcs",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage292());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Longest common subsequence.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the lcs invariant described in the code comments and return a stable, inspectable result for page 292.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for longest common subsequence, then point to the line of code that preserves it.
Page 293 / 561Chapter 21: Sequence and String Dynamic Programming
Edit distance
Page-local deep read
Mental model for Edit distance: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 293, the goal is not memorizing edit distance; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Edit distance is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Edit distance before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as states × transition cost time and state table space in the common model, then revisit the bound when the input representation changes.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
# Page 293: Edit distance
EXAMPLE = {'page': 293, 'topic': 'Edit distance', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'edit_distance', 'scenario': 'Run a concrete edit distance miniature for Edit distance.', 'sample_input': {'n': 11, 'values': [3, 1, 4, 1, 5, 9, 2], 'text_a': 'ALGORITHM', 'text_b': 'LOGARITHM', 'weights': [2, 3, 4, 5], 'profits': [3, 4, 5, 8], 'capacity': 8}, 'expected_output': 'Inspectable result for Edit distance', 'watch_for': 'The invariant that makes Edit distance safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the edit distance example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='293-edit_distance-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def edit_distance_p293(a, b):
dp = [[i+j if i*j==0 else 0 for j in range(len(b)+1)] for i in range(len(a)+1)]
for i in range(1, len(a)+1):
for j in range(1, len(b)+1):
cost = 0 if a[i-1] == b[j-1] else 1
dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1, dp[i-1][j-1]+cost)
return dp[-1][-1]
def run_example(example=EXAMPLE):
return edit_distance_p293('kitten', 'sitting')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track n, values, text_a, text_b before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Edit distance, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Edit distance.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the edit distance invariant described in the code comments and return a stable, inspectable result for page 293.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 294 / 561Chapter 21: Sequence and String Dynamic Programming
Knapsack 0/1
Page-local deep read
Mental model for Knapsack 0/1: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 294, the goal is not memorizing knapsack 0/1; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Knapsack 0/1 is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Knapsack 0/1 before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
# Page 294: Knapsack 0/1
EXAMPLE = {'page': 294, 'topic': 'Knapsack 0/1', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'knapsack', 'scenario': 'Run a concrete knapsack miniature for Knapsack 0/1.', 'sample_input': {'n': 12, 'values': [3, 1, 4, 1, 5, 9, 2], 'text_a': 'ALGORITHM', 'text_b': 'LOGARITHM', 'weights': [2, 3, 4, 5], 'profits': [3, 4, 5, 8], 'capacity': 8}, 'expected_output': 'Inspectable result for Knapsack 0/1', 'watch_for': 'The invariant that makes Knapsack 0/1 safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the knapsack example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='294-knapsack_0_1-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def knapsack_0_1_p294(weights, profits, capacity):
dp = [0] * (capacity + 1)
for w, p in zip(weights, profits):
for c in range(capacity, w-1, -1):
dp[c] = max(dp[c], dp[c-w] + p)
return dp[capacity], dp
def run_example(example=EXAMPLE):
d=example['sample_input']; return knapsack_0_1_p294(d['weights'], d['profits'], d['capacity'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track n, values, text_a, text_b before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Knapsack 0/1, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Knapsack 0/1.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the knapsack invariant described in the code comments and return a stable, inspectable result for page 294.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 295 / 561Chapter 21: Sequence and String Dynamic Programming
Unbounded knapsack
Page-local deep read
Mental model for Unbounded knapsack: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 295, the goal is not memorizing unbounded knapsack; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Unbounded knapsack is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Unbounded knapsack before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
# Page 295: Unbounded knapsack
EXAMPLE = {'page': 295, 'topic': 'Unbounded knapsack', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'unbounded_knapsack', 'scenario': 'Run a concrete unbounded knapsack miniature for Unbounded knapsack.', 'sample_input': {'n': 13, 'values': [3, 1, 4, 1, 5, 9, 2], 'text_a': 'ALGORITHM', 'text_b': 'LOGARITHM', 'weights': [2, 3, 4, 5], 'profits': [3, 4, 5, 8], 'capacity': 8}, 'expected_output': 'Inspectable result for Unbounded knapsack', 'watch_for': 'The invariant that makes Unbounded knapsack safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the unbounded knapsack example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='295-unbounded_knapsack-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def unbounded_knapsack_p295(weights, profits, capacity):
dp = [0] * (capacity + 1)
for w, p in zip(weights, profits):
for c in range(w, capacity+1):
dp[c] = max(dp[c], dp[c-w] + p)
return dp[capacity], dp
def run_example(example=EXAMPLE):
d=example['sample_input']; return unbounded_knapsack_p295(d['weights'], d['profits'], d['capacity'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track n, values, text_a, text_b before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Unbounded knapsack, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Unbounded knapsack.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the unbounded knapsack invariant described in the code comments and return a stable, inspectable result for page 295.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement unbounded knapsack twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 296 / 561Chapter 21: Sequence and String Dynamic Programming
Coin change
Page-local deep read
Mental model for Coin change: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 296, the goal is not memorizing coin change; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Coin change is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Coin change before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
# Page 296: Coin change
EXAMPLE = {'page': 296, 'topic': 'Coin change', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'coin_change', 'scenario': 'Run a concrete coin change miniature for Coin change.', 'sample_input': {'n': 14, 'values': [3, 1, 4, 1, 5, 9, 2], 'text_a': 'ALGORITHM', 'text_b': 'LOGARITHM', 'weights': [2, 3, 4, 5], 'profits': [3, 4, 5, 8], 'capacity': 8}, 'expected_output': 'Inspectable result for Coin change', 'watch_for': 'The invariant that makes Coin change safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the coin change example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='296-coin_change-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def coin_change_p296(coins, amount):
ways = [0] * (amount + 1); ways[0] = 1
for coin in coins:
for total in range(coin, amount + 1): ways[total] += ways[total-coin]
return ways[amount], ways
def run_example(example=EXAMPLE):
return coin_change_p296([1,2,5], 11)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track n, values, text_a, text_b before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Coin change, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Coin change.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the coin change invariant described in the code comments and return a stable, inspectable result for page 296.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for coin change and explain what each one stresses.
Page 297 / 561Chapter 21: Sequence and String Dynamic Programming
Subset sum
Page-local deep read
Mental model for Subset sum: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 297, the goal is not memorizing subset sum; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Subset sum is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Subset sum before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
# Page 297: Subset sum
EXAMPLE = {'page': 297, 'topic': 'Subset sum', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'subset_sum', 'scenario': 'Run a concrete subset sum miniature for Subset sum.', 'sample_input': {'n': 6, 'values': [3, 1, 4, 1, 5, 9, 2], 'text_a': 'ALGORITHM', 'text_b': 'LOGARITHM', 'weights': [2, 3, 4, 5], 'profits': [3, 4, 5, 8], 'capacity': 8}, 'expected_output': 'Inspectable result for Subset sum', 'watch_for': 'The invariant that makes Subset sum safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the subset sum example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='297-subset_sum-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def subset_sum_p297(values, target):
possible = {0}
for value in values:
possible |= {s + value for s in list(possible)}
return target in possible, sorted(x for x in possible if x <= target)
def run_example(example=EXAMPLE):
return subset_sum_p297([3, 34, 4, 12, 5, 2], 9)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track n, values, text_a, text_b before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Subset sum, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Subset sum.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the subset sum invariant described in the code comments and return a stable, inspectable result for page 297.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for subset sum, then point to the line of code that preserves it.
Page 298 / 561Chapter 21: Sequence and String Dynamic Programming
Partition DP
Page-local deep read
Mental model for Partition DP: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 298, the goal is not memorizing partition dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Partition DP is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Partition DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Partition DP whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Partition DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Partition DP.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dp invariant described in the code comments and return a stable, inspectable result for page 298.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 299 / 561Chapter 21: Sequence and String Dynamic Programming
Palindromic subsequences
Page-local deep read
Mental model for Palindromic subsequences: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 299, the goal is not memorizing palindromic subsequences; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Palindromic subsequences is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Palindromic subsequences before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Palindromic subsequences" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Palindromic subsequences.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dp invariant described in the code comments and return a stable, inspectable result for page 299.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 300 / 561Chapter 21: Sequence and String Dynamic Programming
Palindrome partitioning
Page-local deep read
Mental model for Palindrome partitioning: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 300, the goal is not memorizing palindrome partitioning; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Palindrome partitioning is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Palindrome partitioning before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 300: Palindrome partitioning
EXAMPLE = {'page': 300, 'topic': 'Palindrome partitioning', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'partition_array', 'scenario': 'Run a concrete partition array miniature for Palindrome partitioning.', 'sample_input': {'values': [21, 32, 3, 14, 25, 36, 7], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Palindrome partitioning', 'watch_for': 'The invariant that makes Palindrome partitioning safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the partition array example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='300-palindrome_partiti-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def palindrome_partitioning_p300(values, pivot):
smaller, equal, greater = [], [], []
for value in values:
if value < pivot: smaller.append(value)
elif value == pivot: equal.append(value)
else: greater.append(value)
return smaller + equal + greater
def run_example(example=EXAMPLE):
vals=example['sample_input']['values']; return palindrome_partitioning_p300(vals, vals[len(vals)//2])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Palindrome partitioning.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the partition array invariant described in the code comments and return a stable, inspectable result for page 300.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement palindrome partitioning twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 301 / 561Chapter 21: Sequence and String Dynamic Programming
Matrix chain multiplication
Page-local deep read
Mental model for Matrix chain multiplication: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 301, the goal is not memorizing matrix chain multiplication; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Matrix chain multiplication is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Matrix chain multiplication before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
# Page 301: Matrix chain multiplication
EXAMPLE = {'page': 301, 'topic': 'Matrix chain multiplication', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'matrix_chain', 'scenario': 'Run a concrete matrix chain miniature for Matrix chain multiplication.', 'sample_input': {'n': 10, 'values': [3, 1, 4, 1, 5, 9, 2], 'text_a': 'ALGORITHM', 'text_b': 'LOGARITHM', 'weights': [2, 3, 4, 5], 'profits': [3, 4, 5, 8], 'capacity': 8}, 'expected_output': 'Inspectable result for Matrix chain multiplication', 'watch_for': 'The invariant that makes Matrix chain multiplication safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the matrix chain example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='301-matrix_chain_multi-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def matrix_chain_multiplication_p301(dims):
n = len(dims) - 1; dp = [[0]*n for _ in range(n)]
for length in range(2, n+1):
for i in range(n-length+1):
j = i + length - 1
dp[i][j] = min(dp[i][k] + dp[k+1][j] + dims[i]*dims[k+1]*dims[j+1] for k in range(i,j))
return dp[0][-1]
def run_example(example=EXAMPLE):
return matrix_chain_multiplication_p301([10, 30, 5, 60])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track n, values, text_a, text_b before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Matrix chain multiplication, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Matrix chain multiplication.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the matrix chain invariant described in the code comments and return a stable, inspectable result for page 301.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for matrix chain multiplication and explain what each one stresses.
Page 302 / 561Chapter 21: Sequence and String Dynamic Programming
Optimal binary search tree
Page-local deep read
Mental model for Optimal binary search tree: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 302, the goal is not memorizing optimal binary search tree; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Optimal binary search tree is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Optimal binary search tree before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Optimal binary search tree" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Optimal binary search tree.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dp invariant described in the code comments and return a stable, inspectable result for page 302.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for optimal binary search tree, then point to the line of code that preserves it.
Page 303 / 561Chapter 21: Sequence and String Dynamic Programming
Word break
Page-local deep read
Mental model for Word break: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 303, the goal is not memorizing word break; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Word break is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Word break before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as states × transition cost time and state table space in the common model, then revisit the bound when the input representation changes.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Word break" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Word break.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dp invariant described in the code comments and return a stable, inspectable result for page 303.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 304 / 561Chapter 21: Sequence and String Dynamic Programming
Regular expression matching
Page-local deep read
Mental model for Regular expression matching: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 304, the goal is not memorizing regular expression matching; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Regular expression matching is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Regular expression matching before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
# Page 304: Regular expression matching
EXAMPLE = {'page': 304, 'topic': 'Regular expression matching', 'chapter': 'Sequence and String Dynamic Programming', 'kind': 'expression_stack', 'scenario': 'Run a concrete expression stack miniature for Regular expression matching.', 'sample_input': {'values': [9, 20, 31, 2, 13, 24, 35], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Regular expression matching', 'watch_for': 'The invariant that makes Regular expression matching safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the expression stack example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='304-regular_expression-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def regular_expression_matching_p304(tokens):
stack = []
for token in tokens:
if token.isdigit(): stack.append(int(token)); continue
b, a = stack.pop(), stack.pop()
stack.append(a + b if token == '+' else a * b)
return stack[-1]
def run_example(example=EXAMPLE):
return regular_expression_matching_p304(['2','3','+','4','*'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Regular expression matching, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Regular expression matching.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the expression stack invariant described in the code comments and return a stable, inspectable result for page 304.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 305 / 561Chapter 21: Sequence and String Dynamic Programming
Sequence alignment
Page-local deep read
Mental model for Sequence alignment: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 305, the goal is not memorizing sequence alignment; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sequence alignment is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sequence alignment before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Sequence alignment" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Sequence alignment.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dp invariant described in the code comments and return a stable, inspectable result for page 305.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement sequence alignment twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 306 / 561Chapter 21: Sequence and String Dynamic Programming
DP reconstruction
Page-local deep read
Mental model for DP reconstruction: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 306, the goal is not memorizing dp reconstruction; it is recognizing the representation, the safe transition, and the stopping condition inside the Sequence and String Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DP reconstruction is one small tool in the larger Sequence and String Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DP reconstruction before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Filling the table in an order that uses uncomputed neighbors gives plausible but wrong values.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "DP reconstruction" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Grid paths: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 307, the goal is not memorizing grid paths; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Grid paths is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Grid paths before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 22: Grid, Tree, and Bitmask Dynamic Programming
function gridPaths(rows, cols) {
const dp = Array.from({length:rows}, () => Array(cols).fill(1));
for (let r=1;r<rows;r++) for (let c=1;c<cols;c++) dp[r][c] = dp[r-1][c] + dp[r][c-1];
return dp[rows-1][cols-1];
}
console.log(gridPaths(3, 4));
Chapter anchor: This page is the Chapter 22 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Grid, Tree, and Bitmask Dynamic Programming.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 307: Grid paths
EXAMPLE = {'page': 307, 'topic': 'Grid paths', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Grid paths.', 'sample_input': {'values': [30, 1, 12, 23, 34, 5, 16], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Grid paths', 'watch_for': 'The invariant that makes Grid paths safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='307-grid_paths-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def grid_paths_p307(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return grid_paths_p307(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Grid paths" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Obstacle grids: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 308, the goal is not memorizing obstacle grids; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Obstacle grids is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Obstacle grids before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Obstacle grids whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 308: Obstacle grids
EXAMPLE = {'page': 308, 'topic': 'Obstacle grids', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Obstacle grids.', 'sample_input': {'values': [37, 8, 19, 30, 1, 12, 23], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Obstacle grids', 'watch_for': 'The invariant that makes Obstacle grids safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='308-obstacle_grids-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def obstacle_grids_p308(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return obstacle_grids_p308(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Obstacle grids" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Minimum path sum: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 309, the goal is not memorizing minimum path sum; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Minimum path sum is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Minimum path sum before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 309: Minimum path sum
EXAMPLE = {'page': 309, 'topic': 'Minimum path sum', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Minimum path sum.', 'sample_input': {'values': [4, 15, 26, 37, 8, 19, 30], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Minimum path sum', 'watch_for': 'The invariant that makes Minimum path sum safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='309-minimum_path_sum-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def minimum_path_sum_p309(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return minimum_path_sum_p309(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Minimum path sum" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Dungeon game style DP: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 310, the goal is not memorizing dungeon game style dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Dungeon game style DP is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Dungeon game style DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 310: Dungeon game style DP
EXAMPLE = {'page': 310, 'topic': 'Dungeon game style DP', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Dungeon game style DP.', 'sample_input': {'values': [11, 22, 33, 4, 15, 26, 37], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Dungeon game style DP', 'watch_for': 'The invariant that makes Dungeon game style DP safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='310-dungeon_game_style-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def dungeon_game_style_dp_p310(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return dungeon_game_style_dp_p310(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Dungeon game style DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Tree DP: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 311, the goal is not memorizing tree dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Tree DP is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Tree DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 311: Tree DP
EXAMPLE = {'page': 311, 'topic': 'Tree DP', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Tree DP.', 'sample_input': {'values': [18, 29, 40, 11, 22, 33, 4], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Tree DP', 'watch_for': 'The invariant that makes Tree DP safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='311-tree_dp-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def tree_dp_p311(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return tree_dp_p311(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Tree DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Rerooting DP: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 312, the goal is not memorizing rerooting dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rerooting DP is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rerooting DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 312: Rerooting DP
EXAMPLE = {'page': 312, 'topic': 'Rerooting DP', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Rerooting DP.', 'sample_input': {'values': [25, 36, 7, 18, 29, 40, 11], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Rerooting DP', 'watch_for': 'The invariant that makes Rerooting DP safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='312-rerooting_dp-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def rerooting_dp_p312(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return rerooting_dp_p312(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Rerooting DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Independent set on trees: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 313, the goal is not memorizing independent set on trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Independent set on trees is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Independent set on trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as states × transition cost time and state table space in the common model, then revisit the bound when the input representation changes.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 313: Independent set on trees
EXAMPLE = {'page': 313, 'topic': 'Independent set on trees', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Independent set on trees.', 'sample_input': {'values': [32, 3, 14, 25, 36, 7, 18], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Independent set on trees', 'watch_for': 'The invariant that makes Independent set on trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='313-independent_set_on-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def independent_set_on_trees_p313(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return independent_set_on_trees_p313(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Independent set on trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Vertex cover on trees: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 314, the goal is not memorizing vertex cover on trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Vertex cover on trees is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Vertex cover on trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 314: Vertex cover on trees
EXAMPLE = {'page': 314, 'topic': 'Vertex cover on trees', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Vertex cover on trees.', 'sample_input': {'values': [39, 10, 21, 32, 3, 14, 25], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Vertex cover on trees', 'watch_for': 'The invariant that makes Vertex cover on trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='314-vertex_cover_on_tr-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def vertex_cover_on_trees_p314(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return vertex_cover_on_trees_p314(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Vertex cover on trees" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Bitmask DP: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 315, the goal is not memorizing bitmask dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bitmask DP is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bitmask DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 315: Bitmask DP
EXAMPLE = {'page': 315, 'topic': 'Bitmask DP', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Bitmask DP.', 'sample_input': {'values': [6, 17, 28, 39, 10, 21, 32], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Bitmask DP', 'watch_for': 'The invariant that makes Bitmask DP safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='315-bitmask_dp-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def bitmask_dp_p315(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return bitmask_dp_p315(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Bitmask DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Traveling salesperson DP: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 316, the goal is not memorizing traveling salesperson dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Traveling salesperson DP is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Traveling salesperson DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 316: Traveling salesperson DP
EXAMPLE = {'page': 316, 'topic': 'Traveling salesperson DP', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Traveling salesperson DP.', 'sample_input': {'values': [13, 24, 35, 6, 17, 28, 39], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Traveling salesperson DP', 'watch_for': 'The invariant that makes Traveling salesperson DP safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='316-traveling_salesper-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def traveling_salesperson_dp_p316(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return traveling_salesperson_dp_p316(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Traveling salesperson DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Assignment DP: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 317, the goal is not memorizing assignment dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Assignment DP is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Assignment DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 317: Assignment DP
EXAMPLE = {'page': 317, 'topic': 'Assignment DP', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Assignment DP.', 'sample_input': {'values': [20, 31, 2, 13, 24, 35, 6], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Assignment DP', 'watch_for': 'The invariant that makes Assignment DP safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='317-assignment_dp-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def assignment_dp_p317(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return assignment_dp_p317(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Assignment DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Profile DP: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 318, the goal is not memorizing profile dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Profile DP is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Profile DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Profile DP whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 318: Profile DP
EXAMPLE = {'page': 318, 'topic': 'Profile DP', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Profile DP.', 'sample_input': {'values': [27, 38, 9, 20, 31, 2, 13], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Profile DP', 'watch_for': 'The invariant that makes Profile DP safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='318-profile_dp-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def profile_dp_p318(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return profile_dp_p318(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Profile DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Digit DP: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 319, the goal is not memorizing digit dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Digit DP is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Digit DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 319: Digit DP
EXAMPLE = {'page': 319, 'topic': 'Digit DP', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Digit DP.', 'sample_input': {'values': [34, 5, 16, 27, 38, 9, 20], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Digit DP', 'watch_for': 'The invariant that makes Digit DP safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='319-digit_dp-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def digit_dp_p319(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return digit_dp_p319(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Digit DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Interval DP: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 320, the goal is not memorizing interval dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Interval DP is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Interval DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 320: Interval DP
EXAMPLE = {'page': 320, 'topic': 'Interval DP', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'merge_intervals', 'scenario': 'Run a concrete merge intervals miniature for Interval DP.', 'sample_input': {'values': [1, 12, 23, 34, 5, 16, 27], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Interval DP', 'watch_for': 'The invariant that makes Interval DP safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the merge intervals example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='320-interval_dp-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def interval_dp_p320(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return interval_dp_p320(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Interval DP, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Divide-and-conquer DP optimization: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 321, the goal is not memorizing divide-and-conquer dp optimization; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Divide-and-conquer DP optimization is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Divide-and-conquer DP optimization before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 321: Divide-and-conquer DP optimization
EXAMPLE = {'page': 321, 'topic': 'Divide-and-conquer DP optimization', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Divide-and-conquer DP optimization.', 'sample_input': {'values': [8, 19, 30, 1, 12, 23, 34], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Divide-and-conquer DP optimization', 'watch_for': 'The invariant that makes Divide-and-conquer DP optimization safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='321-divide_and_conquer-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def divide_and_conquer_dp_optimization_p321(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return divide_and_conquer_dp_optimization_p321(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Divide-and-conquer DP optimization" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Knuth optimization: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 322, the goal is not memorizing knuth optimization; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Knuth optimization is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Knuth optimization before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 322: Knuth optimization
EXAMPLE = {'page': 322, 'topic': 'Knuth optimization', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Knuth optimization.', 'sample_input': {'values': [15, 26, 37, 8, 19, 30, 1], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Knuth optimization', 'watch_for': 'The invariant that makes Knuth optimization safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='322-knuth_optimization-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def knuth_optimization_p322(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return knuth_optimization_p322(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Knuth optimization" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for Convex hull trick: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 323, the goal is not memorizing convex hull trick; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Convex hull trick is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Convex hull trick before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as states × transition cost time and state table space in the common model, then revisit the bound when the input representation changes.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 323: Convex hull trick
EXAMPLE = {'page': 323, 'topic': 'Convex hull trick', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Convex hull trick.', 'sample_input': {'values': [22, 33, 4, 15, 26, 37, 8], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Convex hull trick', 'watch_for': 'The invariant that makes Convex hull trick safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='323-convex_hull_trick-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def convex_hull_trick_p323(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return convex_hull_trick_p323(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Convex hull trick" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Mental model for DP optimization cautions: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 324, the goal is not memorizing dp optimization cautions; it is recognizing the representation, the safe transition, and the stopping condition inside the Grid, Tree, and Bitmask Dynamic Programming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: DP optimization cautions is one small tool in the larger Grid, Tree, and Bitmask Dynamic Programming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for DP optimization cautions before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Bitmask DP grows exponentially; n=20 may be fine, n=30 usually is not.
# Page 324: DP optimization cautions
EXAMPLE = {'page': 324, 'topic': 'DP optimization cautions', 'chapter': 'Grid, Tree, and Bitmask Dynamic Programming', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for DP optimization cautions.', 'sample_input': {'values': [29, 40, 11, 22, 33, 4, 15], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for DP optimization cautions', 'watch_for': 'The invariant that makes DP optimization cautions safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='324-dp_optimization_ca-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def dp_optimization_cautions_p324(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return dp_optimization_cautions_p324(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "DP optimization cautions" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by DP optimization cautions.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 324.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 325 / 561Chapter 23: Greedy Algorithms
Greedy choice property
Page-local deep read
Mental model for Greedy choice property: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 325, the goal is not memorizing greedy choice property; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Greedy choice property is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Greedy choice property before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 23: Greedy Algorithms
function intervalSchedule(intervals) {
const chosen = []; let end = -Infinity;
for (const [s, f] of intervals.sort((a,b)=>a[1]-b[1])) if (s >= end) { chosen.push([s,f]); end = f; }
return chosen;
}
console.log(intervalSchedule([[1,4],[3,5],[5,7],[8,9]]));
Chapter anchor: This page is the Chapter 23 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Greedy Algorithms.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: unproved local choices. Make this risk visible in tests and in code comments.
Common pitfall: Greedy code is easy to write and easy to be wrong; proof is the algorithm, not decoration.
# Page 325: Greedy choice property
EXAMPLE = {'page': 325, 'topic': 'Greedy choice property', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Greedy choice property.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Greedy choice property', 'watch_for': 'The invariant that makes Greedy choice property safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='325-greedy_choice_prop-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def greedy_choice_property_p325(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return greedy_choice_property_p325(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Greedy choice property" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Greedy choice property.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 325.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement greedy choice property twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 326 / 561Chapter 23: Greedy Algorithms
Interval scheduling
Page-local deep read
Mental model for Interval scheduling: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 326, the goal is not memorizing interval scheduling; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Interval scheduling is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Interval scheduling before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: unproved local choices. Make this risk visible in tests and in code comments.
Common pitfall: Greedy code is easy to write and easy to be wrong; proof is the algorithm, not decoration.
# Page 326: Interval scheduling
EXAMPLE = {'page': 326, 'topic': 'Interval scheduling', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Interval scheduling.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Interval scheduling', 'watch_for': 'The invariant that makes Interval scheduling safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='326-interval_schedulin-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def interval_scheduling_p326(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return interval_scheduling_p326(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Interval scheduling" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Interval scheduling.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 326.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for interval scheduling and explain what each one stresses.
Page 327 / 561Chapter 23: Greedy Algorithms
Activity selection
Page-local deep read
Mental model for Activity selection: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 327, the goal is not memorizing activity selection; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Activity selection is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Activity selection before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: unproved local choices. Make this risk visible in tests and in code comments.
Common pitfall: Greedy code is easy to write and easy to be wrong; proof is the algorithm, not decoration.
# Page 327: Activity selection
EXAMPLE = {'page': 327, 'topic': 'Activity selection', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Activity selection.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Activity selection', 'watch_for': 'The invariant that makes Activity selection safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='327-activity_selection-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def activity_selection_p327(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return activity_selection_p327(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Activity selection" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Activity selection.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 327.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for activity selection, then point to the line of code that preserves it.
Page 328 / 561Chapter 23: Greedy Algorithms
Fractional knapsack
Page-local deep read
Mental model for Fractional knapsack: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 328, the goal is not memorizing fractional knapsack; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Fractional knapsack is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Fractional knapsack before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Fractional knapsack whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Greedy code is easy to write and easy to be wrong; proof is the algorithm, not decoration.
# Page 328: Fractional knapsack
EXAMPLE = {'page': 328, 'topic': 'Fractional knapsack', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Fractional knapsack.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Fractional knapsack', 'watch_for': 'The invariant that makes Fractional knapsack safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='328-fractional_knapsac-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def fractional_knapsack_p328(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return fractional_knapsack_p328(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Fractional knapsack" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Fractional knapsack.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 328.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 329 / 561Chapter 23: Greedy Algorithms
Huffman coding
Page-local deep read
Mental model for Huffman coding: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 329, the goal is not memorizing huffman coding; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Huffman coding is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Huffman coding before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 329: Huffman coding
EXAMPLE = {'page': 329, 'topic': 'Huffman coding', 'chapter': 'Greedy Algorithms', 'kind': 'huffman', 'scenario': 'Run a concrete huffman miniature for Huffman coding.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Huffman coding', 'watch_for': 'The invariant that makes Huffman coding safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the huffman example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='329-huffman_coding-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def huffman_coding_p329(weights):
heap = [(w, symbol) for symbol, w in weights.items()]
heapq.heapify(heap)
while len(heap) > 1:
w1, a = heapq.heappop(heap); w2, b = heapq.heappop(heap)
heapq.heappush(heap, (w1+w2, (a,b)))
return heap[0][1]
def run_example(example=EXAMPLE):
return huffman_coding_p329(example['sample_input']['weights'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Huffman coding, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Huffman coding.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the huffman invariant described in the code comments and return a stable, inspectable result for page 329.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 330 / 561Chapter 23: Greedy Algorithms
Job sequencing
Page-local deep read
Mental model for Job sequencing: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 330, the goal is not memorizing job sequencing; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Job sequencing is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Job sequencing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 330: Job sequencing
EXAMPLE = {'page': 330, 'topic': 'Job sequencing', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Job sequencing.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Job sequencing', 'watch_for': 'The invariant that makes Job sequencing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='330-job_sequencing-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def job_sequencing_p330(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return job_sequencing_p330(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Job sequencing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Job sequencing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 330.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement job sequencing twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 331 / 561Chapter 23: Greedy Algorithms
Minimum platforms
Page-local deep read
Mental model for Minimum platforms: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 331, the goal is not memorizing minimum platforms; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Minimum platforms is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Minimum platforms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: unproved local choices. Make this risk visible in tests and in code comments.
Common pitfall: Greedy code is easy to write and easy to be wrong; proof is the algorithm, not decoration.
# Page 331: Minimum platforms
EXAMPLE = {'page': 331, 'topic': 'Minimum platforms', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Minimum platforms.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Minimum platforms', 'watch_for': 'The invariant that makes Minimum platforms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='331-minimum_platforms-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def minimum_platforms_p331(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return minimum_platforms_p331(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Minimum platforms" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Minimum platforms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 331.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for minimum platforms and explain what each one stresses.
Page 332 / 561Chapter 23: Greedy Algorithms
Gas station
Page-local deep read
Mental model for Gas station: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 332, the goal is not memorizing gas station; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Gas station is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Gas station before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 332: Gas station
EXAMPLE = {'page': 332, 'topic': 'Gas station', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Gas station.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Gas station', 'watch_for': 'The invariant that makes Gas station safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='332-gas_station-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def gas_station_p332(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return gas_station_p332(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Gas station" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 332 curation harness: Gas station
EXAMPLE_KIND = "greedy"
EXAMPLE_TITLE = "Gas station"
SAMPLE = {
"intervals": [
[
0,
3
],
[
1,
2
],
[
3,
5
],
[
4,
7
],
[
5,
9
]
],
"weights": {
"a": 5,
"b": 9,
"c": 12,
"d": 13,
"e": 16,
"f": 45
},
"jobs": [
[
"A",
2,
100
],
[
"B",
1,
19
],
[
"C",
2,
27
],
[
"D",
1,
25
]
],
"page_marker": "332-gas_station"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "intervals",
"marker": sample.get("page_marker", "332-gas_station"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "intervals": []} if "intervals" in sample else dict(sample)),
("single-step", {**sample, "intervals": sample.get("intervals", [])[:1]} if isinstance(sample.get("intervals"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "332-gas_station"))
Browser JavaScript companion
// Page 332 browser-side experiment: Gas station
const pageExample332 = {"intervals":[[0,3],[1,2],[3,5],[4,7],[5,9]],"weights":{"a":5,"b":9,"c":12,"d":13,"e":16,"f":45},"jobs":[["A",2,100],["B",1,19],["C",2,27],["D",1,25]],"page_marker":"332-gas_station"};
function summarizePage332(sample = pageExample332) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Gas station",
kind: "greedy",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage332());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Gas station.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 332.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for gas station, then point to the line of code that preserves it.
Page 333 / 561Chapter 23: Greedy Algorithms
Jump game
Page-local deep read
Mental model for Jump game: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 333, the goal is not memorizing jump game; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Jump game is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Jump game before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 333: Jump game
EXAMPLE = {'page': 333, 'topic': 'Jump game', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Jump game.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Jump game', 'watch_for': 'The invariant that makes Jump game safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='333-jump_game-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def jump_game_p333(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return jump_game_p333(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Jump game" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Jump game.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 333.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 334 / 561Chapter 23: Greedy Algorithms
Candy distribution
Page-local deep read
Mental model for Candy distribution: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 334, the goal is not memorizing candy distribution; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Candy distribution is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Candy distribution before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: unproved local choices. Make this risk visible in tests and in code comments.
Common pitfall: Greedy code is easy to write and easy to be wrong; proof is the algorithm, not decoration.
# Page 334: Candy distribution
EXAMPLE = {'page': 334, 'topic': 'Candy distribution', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Candy distribution.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Candy distribution', 'watch_for': 'The invariant that makes Candy distribution safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='334-candy_distribution-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def candy_distribution_p334(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return candy_distribution_p334(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Candy distribution" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Candy distribution.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 334.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 335 / 561Chapter 23: Greedy Algorithms
Scheduling with deadlines
Page-local deep read
Mental model for Scheduling with deadlines: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 335, the goal is not memorizing scheduling with deadlines; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Scheduling with deadlines is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Scheduling with deadlines before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: unproved local choices. Make this risk visible in tests and in code comments.
Common pitfall: Greedy code is easy to write and easy to be wrong; proof is the algorithm, not decoration.
# Page 335: Scheduling with deadlines
EXAMPLE = {'page': 335, 'topic': 'Scheduling with deadlines', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Scheduling with deadlines.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Scheduling with deadlines', 'watch_for': 'The invariant that makes Scheduling with deadlines safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='335-scheduling_with_de-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def scheduling_with_deadlines_p335(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return scheduling_with_deadlines_p335(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Scheduling with deadlines" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 335 curation harness: Scheduling with deadlines
EXAMPLE_KIND = "greedy"
EXAMPLE_TITLE = "Scheduling with deadlines"
SAMPLE = {
"intervals": [
[
0,
3
],
[
1,
2
],
[
3,
5
],
[
4,
7
],
[
5,
9
]
],
"weights": {
"a": 5,
"b": 9,
"c": 12,
"d": 13,
"e": 16,
"f": 45
},
"jobs": [
[
"A",
2,
100
],
[
"B",
1,
19
],
[
"C",
2,
27
],
[
"D",
1,
25
]
],
"page_marker": "335-scheduling_with_dead"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "intervals",
"marker": sample.get("page_marker", "335-scheduling_with_dead"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "intervals": []} if "intervals" in sample else dict(sample)),
("single-step", {**sample, "intervals": sample.get("intervals", [])[:1]} if isinstance(sample.get("intervals"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "335-scheduling_with_dead"))
Browser JavaScript companion
// Page 335 browser-side experiment: Scheduling with deadlines
const pageExample335 = {"intervals":[[0,3],[1,2],[3,5],[4,7],[5,9]],"weights":{"a":5,"b":9,"c":12,"d":13,"e":16,"f":45},"jobs":[["A",2,100],["B",1,19],["C",2,27],["D",1,25]],"page_marker":"335-scheduling_with_dead"};
function summarizePage335(sample = pageExample335) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Scheduling with deadlines",
kind: "greedy",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage335());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Scheduling with deadlines.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 335.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement scheduling with deadlines twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 336 / 561Chapter 23: Greedy Algorithms
Matroid intuition
Page-local deep read
Mental model for Matroid intuition: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 336, the goal is not memorizing matroid intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Matroid intuition is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Matroid intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: unproved local choices. Make this risk visible in tests and in code comments.
Common pitfall: Greedy code is easy to write and easy to be wrong; proof is the algorithm, not decoration.
# Page 336: Matroid intuition
EXAMPLE = {'page': 336, 'topic': 'Matroid intuition', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Matroid intuition.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Matroid intuition', 'watch_for': 'The invariant that makes Matroid intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='336-matroid_intuition-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def matroid_intuition_p336(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return matroid_intuition_p336(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Matroid intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Matroid intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 336.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for matroid intuition and explain what each one stresses.
Page 337 / 561Chapter 23: Greedy Algorithms
Greedy stays-ahead
Page-local deep read
Mental model for Greedy stays-ahead: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 337, the goal is not memorizing greedy stays-ahead; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Greedy stays-ahead is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Greedy stays-ahead before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: unproved local choices. Make this risk visible in tests and in code comments.
Common pitfall: Greedy code is easy to write and easy to be wrong; proof is the algorithm, not decoration.
# Page 337: Greedy stays-ahead
EXAMPLE = {'page': 337, 'topic': 'Greedy stays-ahead', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Greedy stays-ahead.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Greedy stays-ahead', 'watch_for': 'The invariant that makes Greedy stays-ahead safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='337-greedy_stays_ahead-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def greedy_stays_ahead_p337(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return greedy_stays_ahead_p337(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Greedy stays-ahead" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Greedy stays-ahead.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 337.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for greedy stays-ahead, then point to the line of code that preserves it.
Page 338 / 561Chapter 23: Greedy Algorithms
Exchange proof lab
Page-local deep read
Mental model for Exchange proof lab: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 338, the goal is not memorizing exchange proof lab; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Exchange proof lab is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Exchange proof lab before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Exchange proof lab whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: unproved local choices. Make this risk visible in tests and in code comments.
Common pitfall: Greedy code is easy to write and easy to be wrong; proof is the algorithm, not decoration.
# Page 338: Exchange proof lab
EXAMPLE = {'page': 338, 'topic': 'Exchange proof lab', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for Exchange proof lab.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Exchange proof lab', 'watch_for': 'The invariant that makes Exchange proof lab safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='338-exchange_proof_lab-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def exchange_proof_lab_p338(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return exchange_proof_lab_p338(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "Exchange proof lab" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Exchange proof lab.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 338.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 339 / 561Chapter 23: Greedy Algorithms
When greedy fails
Page-local deep read
Mental model for When greedy fails: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 339, the goal is not memorizing when greedy fails; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: When greedy fails is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for When greedy fails before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 339: When greedy fails
EXAMPLE = {'page': 339, 'topic': 'When greedy fails', 'chapter': 'Greedy Algorithms', 'kind': 'greedy', 'scenario': 'Run a concrete greedy miniature for When greedy fails.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for When greedy fails', 'watch_for': 'The invariant that makes When greedy fails safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the greedy example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='339-when_greedy_fails-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def when_greedy_fails_p339(intervals):
intervals = sorted(intervals, key=lambda x: x[1])
chosen, end = [], float('-inf')
for start, finish in intervals:
if start >= end:
chosen.append((start, finish)); end = finish
return chosen
def run_example(example=EXAMPLE):
return when_greedy_fails_p339(example['sample_input']['intervals'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Do not memorize the label "When greedy fails" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by When greedy fails.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the greedy invariant described in the code comments and return a stable, inspectable result for page 339.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 340 / 561Chapter 23: Greedy Algorithms
Greedy versus DP
Page-local deep read
Mental model for Greedy versus DP: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 340, the goal is not memorizing greedy versus dp; it is recognizing the representation, the safe transition, and the stopping condition inside the Greedy Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Greedy versus DP is one small tool in the larger Greedy Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Greedy versus DP before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track n, values, text_a, text_b before reading the answer.
Common trap
Do not memorize the label "Greedy versus DP" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 340 curation harness: Greedy versus DP
EXAMPLE_KIND = "dp"
EXAMPLE_TITLE = "Greedy versus DP"
SAMPLE = {
"n": 13,
"values": [
3,
1,
4,
1,
5,
9,
2
],
"text_a": "ALGORITHM",
"text_b": "LOGARITHM",
"weights": [
2,
3,
4,
5
],
"profits": [
3,
4,
5,
8
],
"capacity": 8,
"page_marker": "340-greedy_versus_dp"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "340-greedy_versus_dp"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "340-greedy_versus_dp"))
Browser JavaScript companion
// Page 340 browser-side experiment: Greedy versus DP
const pageExample340 = {"n":13,"values":[3,1,4,1,5,9,2],"text_a":"ALGORITHM","text_b":"LOGARITHM","weights":[2,3,4,5],"profits":[3,4,5,8],"capacity":8,"page_marker":"340-greedy_versus_dp"};
function summarizePage340(sample = pageExample340) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Greedy versus DP",
kind: "dp",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage340());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['n'], then compare it with the first line produced by Greedy versus DP.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dp invariant described in the code comments and return a stable, inspectable result for page 340.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement greedy versus dp twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 341 / 561Chapter 24: Backtracking and Combinatorial Search
Backtracking template
Page-local deep read
Mental model for Backtracking template: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 341, the goal is not memorizing backtracking template; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Backtracking template is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Backtracking template before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
This is a chapter-level anchor example. Read it alongside the page-specific labs lower down.
def solve_n_queens(n: int) -> list[list[str]]:
cols, diag1, diag2 = set(), set(), set()
board = [['.'] * n for _ in range(n)]
out = []
def dfs(r: int) -> None:
if r == n:
out.append([''.join(row) for row in board])
return
for c in range(n):
if c in cols or r - c in diag1 or r + c in diag2:
continue
cols.add(c); diag1.add(r - c); diag2.add(r + c)
board[r][c] = 'Q'
dfs(r + 1)
board[r][c] = '.'
cols.remove(c); diag1.remove(r - c); diag2.remove(r + c)
dfs(0)
return out
print(solve_n_queens(4)[0])
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 24: Backtracking and Combinatorial Search
function subsets(items) {
const out = [];
function dfs(i, path) { if (i === items.length) return out.push([...path]); dfs(i+1, path); path.push(items[i]); dfs(i+1, path); path.pop(); }
dfs(0, []); return out;
}
console.log(subsets([1,2,3]));
Chapter anchor: This page is the Chapter 24 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Backtracking and Combinatorial Search.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: Mutating shared state without undoing it correctly causes ghosts from one branch to corrupt another.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the decision tree prefix, pruning rule, undo step, and first three leaves visited.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Backtracking template.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the backtracking invariant described in the code comments and return a stable, inspectable result for page 341.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for backtracking template and explain what each one stresses.
Page 342 / 561Chapter 24: Backtracking and Combinatorial Search
Permutations
Page-local deep read
Mental model for Permutations: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 342, the goal is not memorizing permutations; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Permutations is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Permutations before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Permutations, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Permutations.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the permutations invariant described in the code comments and return a stable, inspectable result for page 342.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for permutations, then point to the line of code that preserves it.
Page 343 / 561Chapter 24: Backtracking and Combinatorial Search
Combinations
Page-local deep read
Mental model for Combinations: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 343, the goal is not memorizing combinations; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Combinations is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Combinations before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as exponential worst case time and depth-dependent space in the common model, then revisit the bound when the input representation changes.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: Mutating shared state without undoing it correctly causes ghosts from one branch to corrupt another.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Combinations, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Combinations.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the combinations invariant described in the code comments and return a stable, inspectable result for page 343.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 344 / 561Chapter 24: Backtracking and Combinatorial Search
Subsets
Page-local deep read
Mental model for Subsets: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 344, the goal is not memorizing subsets; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Subsets is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Subsets before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: Mutating shared state without undoing it correctly causes ghosts from one branch to corrupt another.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Subsets, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Subsets.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the subsets invariant described in the code comments and return a stable, inspectable result for page 344.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 345 / 561Chapter 24: Backtracking and Combinatorial Search
N-Queens
Page-local deep read
Mental model for N-Queens: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 345, the goal is not memorizing n-queens; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: N-Queens is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for N-Queens before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: Mutating shared state without undoing it correctly causes ghosts from one branch to corrupt another.
# Page 345: N-Queens
EXAMPLE = {'page': 345, 'topic': 'N-Queens', 'chapter': 'Backtracking and Combinatorial Search', 'kind': 'n_queens', 'scenario': 'Run a concrete n queens miniature for N-Queens.', 'sample_input': {'items': [1, 2, 3, 4], 'n': 4, 'target': 5, 'grid': [[0, 0, 0, 2], [0, 0, 3, 0], [0, 1, 0, 0], [4, 0, 0, 0]]}, 'expected_output': 'Inspectable result for N-Queens', 'watch_for': 'The invariant that makes N-Queens safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the n queens example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='345-n_queens-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def n_queens_p345(n):
cols, diag1, diag2, board, out = set(), set(), set(), [], []
def place(r):
if r == n: out.append(board.copy()); return
for c in range(n):
if c in cols or r-c in diag1 or r+c in diag2: continue
cols.add(c); diag1.add(r-c); diag2.add(r+c); board.append(c)
place(r+1)
board.pop(); cols.remove(c); diag1.remove(r-c); diag2.remove(r+c)
place(0); return out
def run_example(example=EXAMPLE):
return n_queens_p345(4)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
N-Queens Backtracking
Generate a solution and inspect the board. Each queen attacks rows, columns, and diagonals.
Manual review notes for students
What to inspect first
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of N-Queens, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by N-Queens.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the n queens invariant described in the code comments and return a stable, inspectable result for page 345.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement n-queens twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 346 / 561Chapter 24: Backtracking and Combinatorial Search
Sudoku solving
Page-local deep read
Mental model for Sudoku solving: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 346, the goal is not memorizing sudoku solving; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sudoku solving is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sudoku solving before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: Mutating shared state without undoing it correctly causes ghosts from one branch to corrupt another.
# Page 346: Sudoku solving
EXAMPLE = {'page': 346, 'topic': 'Sudoku solving', 'chapter': 'Backtracking and Combinatorial Search', 'kind': 'sudoku', 'scenario': 'Run a concrete sudoku miniature for Sudoku solving.', 'sample_input': {'items': [1, 2, 3, 4], 'n': 4, 'target': 5, 'grid': [[0, 0, 0, 2], [0, 0, 3, 0], [0, 1, 0, 0], [4, 0, 0, 0]]}, 'expected_output': 'Inspectable result for Sudoku solving', 'watch_for': 'The invariant that makes Sudoku solving safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sudoku example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='346-sudoku_solving-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def sudoku_solving_p346(grid):
n = len(grid)
def ok(r,c,v):
box = int(n ** 0.5); br, bc = r//box*box, c//box*box
return all(grid[r][j] != v for j in range(n)) and all(grid[i][c] != v for i in range(n)) and all(grid[i][j] != v for i in range(br, br+box) for j in range(bc, bc+box))
def solve():
for r in range(n):
for c in range(n):
if grid[r][c] == 0:
for v in range(1, n+1):
if ok(r,c,v):
grid[r][c] = v
if solve(): return True
grid[r][c] = 0
return False
return True
solve(); return grid
def run_example(example=EXAMPLE):
return sudoku_solving_p346([row[:] for row in example['sample_input']['grid']])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Sudoku solving, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Sudoku solving.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sudoku invariant described in the code comments and return a stable, inspectable result for page 346.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for sudoku solving and explain what each one stresses.
Page 347 / 561Chapter 24: Backtracking and Combinatorial Search
Constraint propagation
Page-local deep read
Mental model for Constraint propagation: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 347, the goal is not memorizing constraint propagation; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Constraint propagation is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Constraint propagation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: Mutating shared state without undoing it correctly causes ghosts from one branch to corrupt another.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the decision tree prefix, pruning rule, undo step, and first three leaves visited.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Constraint propagation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the backtracking invariant described in the code comments and return a stable, inspectable result for page 347.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for constraint propagation, then point to the line of code that preserves it.
Page 348 / 561Chapter 24: Backtracking and Combinatorial Search
Branch and bound
Page-local deep read
Mental model for Branch and bound: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 348, the goal is not memorizing branch and bound; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Branch and bound is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Branch and bound before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Branch and bound whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: Mutating shared state without undoing it correctly causes ghosts from one branch to corrupt another.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the decision tree prefix, pruning rule, undo step, and first three leaves visited.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 348 curation harness: Branch and bound
EXAMPLE_KIND = "backtracking"
EXAMPLE_TITLE = "Branch and bound"
SAMPLE = {
"items": [
1,
2,
3,
4
],
"n": 4,
"target": 5,
"grid": [
[
0,
0,
0,
2
],
[
0,
0,
3,
0
],
[
0,
1,
0,
0
],
[
4,
0,
0,
0
]
],
"page_marker": "348-branch_and_bound"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "items",
"marker": sample.get("page_marker", "348-branch_and_bound"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "items": []} if "items" in sample else dict(sample)),
("single-step", {**sample, "items": sample.get("items", [])[:1]} if isinstance(sample.get("items"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "348-branch_and_bound"))
Browser JavaScript companion
// Page 348 browser-side experiment: Branch and bound
const pageExample348 = {"items":[1,2,3,4],"n":4,"target":5,"grid":[[0,0,0,2],[0,0,3,0],[0,1,0,0],[4,0,0,0]],"page_marker":"348-branch_and_bound"};
function summarizePage348(sample = pageExample348) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Branch and bound",
kind: "backtracking",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage348());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Branch and bound.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the backtracking invariant described in the code comments and return a stable, inspectable result for page 348.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 349 / 561Chapter 24: Backtracking and Combinatorial Search
Meet-in-the-middle
Page-local deep read
Mental model for Meet-in-the-middle: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 349, the goal is not memorizing meet-in-the-middle; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Meet-in-the-middle is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Meet-in-the-middle before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 349: Meet-in-the-middle
EXAMPLE = {'page': 349, 'topic': 'Meet-in-the-middle', 'chapter': 'Backtracking and Combinatorial Search', 'kind': 'meet_middle', 'scenario': 'Run a concrete meet middle miniature for Meet-in-the-middle.', 'sample_input': {'values': [4, 15, 26, 37, 8, 19, 30], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Meet-in-the-middle', 'watch_for': 'The invariant that makes Meet-in-the-middle safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the meet middle example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='349-meet_in_the_middle-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def meet_in_the_middle_p349(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return meet_in_the_middle_p349(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Meet-in-the-middle, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Meet-in-the-middle.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the meet middle invariant described in the code comments and return a stable, inspectable result for page 349.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 350 / 561Chapter 24: Backtracking and Combinatorial Search
Exact cover and dancing links
Page-local deep read
Mental model for Exact cover and dancing links: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 350, the goal is not memorizing exact cover and dancing links; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Exact cover and dancing links is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Exact cover and dancing links before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the decision tree prefix, pruning rule, undo step, and first three leaves visited.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 350 curation harness: Exact cover and dancing links
EXAMPLE_KIND = "backtracking"
EXAMPLE_TITLE = "Exact cover and dancing links"
SAMPLE = {
"items": [
1,
2,
3,
4
],
"n": 4,
"target": 5,
"grid": [
[
0,
0,
0,
2
],
[
0,
0,
3,
0
],
[
0,
1,
0,
0
],
[
4,
0,
0,
0
]
],
"page_marker": "350-exact_cover_and_danc"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "items",
"marker": sample.get("page_marker", "350-exact_cover_and_danc"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "items": []} if "items" in sample else dict(sample)),
("single-step", {**sample, "items": sample.get("items", [])[:1]} if isinstance(sample.get("items"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "350-exact_cover_and_danc"))
Browser JavaScript companion
// Page 350 browser-side experiment: Exact cover and dancing links
const pageExample350 = {"items":[1,2,3,4],"n":4,"target":5,"grid":[[0,0,0,2],[0,0,3,0],[0,1,0,0],[4,0,0,0]],"page_marker":"350-exact_cover_and_danc"};
function summarizePage350(sample = pageExample350) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Exact cover and dancing links",
kind: "backtracking",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage350());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Exact cover and dancing links.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the backtracking invariant described in the code comments and return a stable, inspectable result for page 350.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement exact cover and dancing links twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 351 / 561Chapter 24: Backtracking and Combinatorial Search
Search ordering heuristics
Page-local deep read
Mental model for Search ordering heuristics: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 351, the goal is not memorizing search ordering heuristics; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Search ordering heuristics is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Search ordering heuristics before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: Mutating shared state without undoing it correctly causes ghosts from one branch to corrupt another.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the decision tree prefix, pruning rule, undo step, and first three leaves visited.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Search ordering heuristics.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the backtracking invariant described in the code comments and return a stable, inspectable result for page 351.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for search ordering heuristics and explain what each one stresses.
Page 352 / 561Chapter 24: Backtracking and Combinatorial Search
Iterative deepening
Page-local deep read
Mental model for Iterative deepening: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 352, the goal is not memorizing iterative deepening; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Iterative deepening is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Iterative deepening before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the decision tree prefix, pruning rule, undo step, and first three leaves visited.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Iterative deepening.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the backtracking invariant described in the code comments and return a stable, inspectable result for page 352.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for iterative deepening, then point to the line of code that preserves it.
Page 353 / 561Chapter 24: Backtracking and Combinatorial Search
Alpha-beta pruning
Page-local deep read
Mental model for Alpha-beta pruning: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 353, the goal is not memorizing alpha-beta pruning; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Alpha-beta pruning is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Alpha-beta pruning before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as exponential worst case time and depth-dependent space in the common model, then revisit the bound when the input representation changes.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: Mutating shared state without undoing it correctly causes ghosts from one branch to corrupt another.
# Page 353: Alpha-beta pruning
EXAMPLE = {'page': 353, 'topic': 'Alpha-beta pruning', 'chapter': 'Backtracking and Combinatorial Search', 'kind': 'alpha_beta', 'scenario': 'Run a concrete alpha beta miniature for Alpha-beta pruning.', 'sample_input': {'values': [32, 3, 14, 25, 36, 7, 18], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Alpha-beta pruning', 'watch_for': 'The invariant that makes Alpha-beta pruning safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the alpha beta example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='353-alpha_beta_pruning-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def alpha_beta_pruning_p353(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return alpha_beta_pruning_p353(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Alpha-beta pruning, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Alpha-beta pruning.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the alpha beta invariant described in the code comments and return a stable, inspectable result for page 353.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 354 / 561Chapter 24: Backtracking and Combinatorial Search
Backtracking performance traps
Page-local deep read
Mental model for Backtracking performance traps: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 354, the goal is not memorizing backtracking performance traps; it is recognizing the representation, the safe transition, and the stopping condition inside the Backtracking and Combinatorial Search chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Backtracking performance traps is one small tool in the larger Backtracking and Combinatorial Search toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Backtracking performance traps before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: pruning. Make this risk visible in tests and in code comments.
Common pitfall: Mutating shared state without undoing it correctly causes ghosts from one branch to corrupt another.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the decision tree prefix, pruning rule, undo step, and first three leaves visited.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Backtracking performance traps.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the backtracking invariant described in the code comments and return a stable, inspectable result for page 354.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 355 / 561Chapter 25: String Algorithms and Automata
Naive pattern matching
Page-local deep read
Mental model for Naive pattern matching: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 355, the goal is not memorizing naive pattern matching; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Naive pattern matching is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Naive pattern matching before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
This is a chapter-level anchor example. Read it alongside the page-specific labs lower down.
from collections import deque
def neighbors(code: str):
for i, ch in enumerate(code):
digit = int(ch)
for delta in (-1, 1):
nd = (digit + delta) % 10
yield code[:i] + str(nd) + code[i + 1:]
def open_lock(start: str, target: str, blocked: set[str]) -> int:
q = deque([(start, 0)])
seen = {start}
while q:
state, dist = q.popleft()
if state == target:
return dist
for nxt in neighbors(state):
if nxt not in seen and nxt not in blocked:
seen.add(nxt)
q.append((nxt, dist + 1))
return -1
print(open_lock('0000', '0202', {'0101', '0102'}))
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 25: String Algorithms and Automata
function prefixFunction(s) {
const pi = Array(s.length).fill(0);
for (let i=1;i<s.length;i++) { let j = pi[i-1]; while (j > 0 && s[i] !== s[j]) j = pi[j-1]; if (s[i] === s[j]) j++; pi[i] = j; }
return pi;
}
console.log(prefixFunction('ababcababd'));
Chapter anchor: This page is the Chapter 25 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of String Algorithms and Automata.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 355: Naive pattern matching
EXAMPLE = {'page': 355, 'topic': 'Naive pattern matching', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Naive pattern matching.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Naive pattern matching', 'watch_for': 'The invariant that makes Naive pattern matching safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='355-naive_pattern_matc-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def naive_pattern_matching_p355(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return naive_pattern_matching_p355(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Naive pattern matching" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Naive pattern matching.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 355.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement naive pattern matching twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 356 / 561Chapter 25: String Algorithms and Automata
Prefix function
Page-local deep read
Mental model for Prefix function: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 356, the goal is not memorizing prefix function; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Prefix function is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Prefix function before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 356: Prefix function
EXAMPLE = {'page': 356, 'topic': 'Prefix function', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Prefix function.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Prefix function', 'watch_for': 'The invariant that makes Prefix function safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='356-prefix_function-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def prefix_function_p356(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return prefix_function_p356(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Prefix function" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 356 curation harness: Prefix function
EXAMPLE_KIND = "string_alg"
EXAMPLE_TITLE = "Prefix function"
SAMPLE = {
"text": "abracadabra",
"pattern": "abra",
"words": [
"he",
"she",
"his",
"hers"
],
"page_marker": "356-prefix_function"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "text",
"marker": sample.get("page_marker", "356-prefix_function"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "text": []} if "text" in sample else dict(sample)),
("single-step", {**sample, "text": sample.get("text", [])[:1]} if isinstance(sample.get("text"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "356-prefix_function"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Prefix function.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 356.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for prefix function and explain what each one stresses.
Page 357 / 561Chapter 25: String Algorithms and Automata
KMP search
Page-local deep read
Mental model for KMP search: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 357, the goal is not memorizing kmp search; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: KMP search is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for KMP search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 357: KMP search
EXAMPLE = {'page': 357, 'topic': 'KMP search', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for KMP search.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for KMP search', 'watch_for': 'The invariant that makes KMP search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='357-kmp_search-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def kmp_search_p357(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return kmp_search_p357(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
KMP String Matching
Build the prefix table and search without backing up in the text.
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "KMP search" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by KMP search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 357.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for kmp search, then point to the line of code that preserves it.
Page 358 / 561Chapter 25: String Algorithms and Automata
Z algorithm
Page-local deep read
Mental model for Z algorithm: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 358, the goal is not memorizing z algorithm; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Z algorithm is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Z algorithm before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Z algorithm whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 358: Z algorithm
EXAMPLE = {'page': 358, 'topic': 'Z algorithm', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Z algorithm.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Z algorithm', 'watch_for': 'The invariant that makes Z algorithm safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='358-z_algorithm-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def z_algorithm_p358(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return z_algorithm_p358(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Z algorithm" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 358 curation harness: Z algorithm
EXAMPLE_KIND = "string_alg"
EXAMPLE_TITLE = "Z algorithm"
SAMPLE = {
"text": "abracadabra",
"pattern": "abra",
"words": [
"he",
"she",
"his",
"hers"
],
"page_marker": "358-z_algorithm"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "text",
"marker": sample.get("page_marker", "358-z_algorithm"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "text": []} if "text" in sample else dict(sample)),
("single-step", {**sample, "text": sample.get("text", [])[:1]} if isinstance(sample.get("text"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "358-z_algorithm"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Z algorithm.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 358.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 359 / 561Chapter 25: String Algorithms and Automata
Rabin-Karp
Page-local deep read
Mental model for Rabin-Karp: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 359, the goal is not memorizing rabin-karp; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rabin-Karp is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rabin-Karp before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 359: Rabin-Karp
EXAMPLE = {'page': 359, 'topic': 'Rabin-Karp', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Rabin-Karp.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Rabin-Karp', 'watch_for': 'The invariant that makes Rabin-Karp safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='359-rabin_karp-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def rabin_karp_p359(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return rabin_karp_p359(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Rabin-Karp" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 359 curation harness: Rabin-Karp
EXAMPLE_KIND = "string_alg"
EXAMPLE_TITLE = "Rabin-Karp"
SAMPLE = {
"text": "abracadabra",
"pattern": "abra",
"words": [
"he",
"she",
"his",
"hers"
],
"page_marker": "359-rabin_karp"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "text",
"marker": sample.get("page_marker", "359-rabin_karp"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "text": []} if "text" in sample else dict(sample)),
("single-step", {**sample, "text": sample.get("text", [])[:1]} if isinstance(sample.get("text"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "359-rabin_karp"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Rabin-Karp.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 359.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 360 / 561Chapter 25: String Algorithms and Automata
Rolling hash collision handling
Page-local deep read
Mental model for Rolling hash collision handling: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 360, the goal is not memorizing rolling hash collision handling; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rolling hash collision handling is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rolling hash collision handling before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Rolling hash collision handling" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Rolling hash collision handling, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Rolling hash collision handling.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 360.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement rolling hash collision handling twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 361 / 561Chapter 25: String Algorithms and Automata
Manacher's algorithm
Page-local deep read
Mental model for Manacher's algorithm: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 361, the goal is not memorizing manacher's algorithm; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Manacher's algorithm is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Manacher's algorithm before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 361: Manacher's algorithm
EXAMPLE = {'page': 361, 'topic': "Manacher's algorithm", 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': "Run a concrete string alg miniature for Manacher's algorithm.", 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': "Inspectable result for Manacher's algorithm", 'watch_for': "The invariant that makes Manacher's algorithm safe is checked before the next transition.", 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='361-manacher_s_algorit-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def manacher_s_algorithm_p361(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return manacher_s_algorithm_p361(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Manacher's algorithm" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Manacher's algorithm.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 361.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for manacher's algorithm and explain what each one stresses.
Page 362 / 561Chapter 25: String Algorithms and Automata
Suffix arrays
Page-local deep read
Mental model for Suffix arrays: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 362, the goal is not memorizing suffix arrays; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Suffix arrays is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Suffix arrays before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 362: Suffix arrays
EXAMPLE = {'page': 362, 'topic': 'Suffix arrays', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Suffix arrays.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Suffix arrays', 'watch_for': 'The invariant that makes Suffix arrays safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='362-suffix_arrays-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def suffix_arrays_p362(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return suffix_arrays_p362(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Suffix arrays" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Suffix arrays.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 362.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for suffix arrays, then point to the line of code that preserves it.
Page 363 / 561Chapter 25: String Algorithms and Automata
LCP arrays
Page-local deep read
Mental model for LCP arrays: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 363, the goal is not memorizing lcp arrays; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: LCP arrays is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for LCP arrays before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as often linear after preprocessing time and preprocessing structures space in the common model, then revisit the bound when the input representation changes.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 363: LCP arrays
EXAMPLE = {'page': 363, 'topic': 'LCP arrays', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for LCP arrays.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for LCP arrays', 'watch_for': 'The invariant that makes LCP arrays safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='363-lcp_arrays-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def lcp_arrays_p363(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return lcp_arrays_p363(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "LCP arrays" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by LCP arrays.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 363.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 364 / 561Chapter 25: String Algorithms and Automata
Suffix automaton intuition
Page-local deep read
Mental model for Suffix automaton intuition: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 364, the goal is not memorizing suffix automaton intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Suffix automaton intuition is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Suffix automaton intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 364: Suffix automaton intuition
EXAMPLE = {'page': 364, 'topic': 'Suffix automaton intuition', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Suffix automaton intuition.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Suffix automaton intuition', 'watch_for': 'The invariant that makes Suffix automaton intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='364-suffix_automaton_i-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def suffix_automaton_intuition_p364(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return suffix_automaton_intuition_p364(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Suffix automaton intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Suffix automaton intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 364.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 365 / 561Chapter 25: String Algorithms and Automata
Aho-Corasick
Page-local deep read
Mental model for Aho-Corasick: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 365, the goal is not memorizing aho-corasick; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Aho-Corasick is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Aho-Corasick before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 365: Aho-Corasick
EXAMPLE = {'page': 365, 'topic': 'Aho-Corasick', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Aho-Corasick.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Aho-Corasick', 'watch_for': 'The invariant that makes Aho-Corasick safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='365-aho_corasick-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def aho_corasick_p365(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return aho_corasick_p365(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Aho-Corasick" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 365 curation harness: Aho-Corasick
EXAMPLE_KIND = "string_alg"
EXAMPLE_TITLE = "Aho-Corasick"
SAMPLE = {
"text": "abracadabra",
"pattern": "abra",
"words": [
"he",
"she",
"his",
"hers"
],
"page_marker": "365-aho_corasick"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "text",
"marker": sample.get("page_marker", "365-aho_corasick"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "text": []} if "text" in sample else dict(sample)),
("single-step", {**sample, "text": sample.get("text", [])[:1]} if isinstance(sample.get("text"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "365-aho_corasick"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Aho-Corasick.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 365.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement aho-corasick twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 366 / 561Chapter 25: String Algorithms and Automata
Trie search
Page-local deep read
Mental model for Trie search: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 366, the goal is not memorizing trie search; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Trie search is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Trie search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 366: Trie search
EXAMPLE = {'page': 366, 'topic': 'Trie search', 'chapter': 'String Algorithms and Automata', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Trie search.', 'sample_input': {'values': [3, 14, 25, 36, 7, 18, 29], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Trie search', 'watch_for': 'The invariant that makes Trie search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='366-trie_search-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def trie_search_p366(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return trie_search_p366(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Trie search" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Trie search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 366.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for trie search and explain what each one stresses.
Page 367 / 561Chapter 25: String Algorithms and Automata
Wildcard matching
Page-local deep read
Mental model for Wildcard matching: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 367, the goal is not memorizing wildcard matching; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Wildcard matching is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Wildcard matching before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 367: Wildcard matching
EXAMPLE = {'page': 367, 'topic': 'Wildcard matching', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Wildcard matching.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Wildcard matching', 'watch_for': 'The invariant that makes Wildcard matching safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='367-wildcard_matching-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def wildcard_matching_p367(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return wildcard_matching_p367(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Wildcard matching" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Wildcard matching.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 367.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for wildcard matching, then point to the line of code that preserves it.
Page 368 / 561Chapter 25: String Algorithms and Automata
Edit distance revisited
Page-local deep read
Mental model for Edit distance revisited: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 368, the goal is not memorizing edit distance revisited; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Edit distance revisited is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Edit distance revisited before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Edit distance revisited whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 368: Edit distance revisited
EXAMPLE = {'page': 368, 'topic': 'Edit distance revisited', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Edit distance revisited.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Edit distance revisited', 'watch_for': 'The invariant that makes Edit distance revisited safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='368-edit_distance_revi-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def edit_distance_revisited_p368(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return edit_distance_revisited_p368(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Edit distance revisited" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Edit distance revisited.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 368.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 369 / 561Chapter 25: String Algorithms and Automata
Longest palindromic substring
Page-local deep read
Mental model for Longest palindromic substring: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 369, the goal is not memorizing longest palindromic substring; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Longest palindromic substring is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Longest palindromic substring before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 369: Longest palindromic substring
EXAMPLE = {'page': 369, 'topic': 'Longest palindromic substring', 'chapter': 'String Algorithms and Automata', 'kind': 'balanced_tree', 'scenario': 'Run a concrete balanced tree miniature for Longest palindromic substring.', 'sample_input': {'values': [24, 35, 6, 17, 28, 39, 10], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Longest palindromic substring', 'watch_for': 'The invariant that makes Longest palindromic substring safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the balanced tree example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='369-longest_palindromi-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def longest_palindromic_substring_p369(sorted_values):
if not sorted_values: return None
mid = len(sorted_values)//2
return {'key': sorted_values[mid], 'left': longest_palindromic_substring_p369(sorted_values[:mid]), 'right': longest_palindromic_substring_p369(sorted_values[mid+1:])}
def inorder(node):
return [] if node is None else inorder(node['left']) + [node['key']] + inorder(node['right'])
def run_example(example=EXAMPLE):
vals=sorted(set(example['sample_input']['values']))
root=longest_palindromic_substring_p369(vals); return inorder(root)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Longest palindromic substring" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Longest palindromic substring.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the balanced tree invariant described in the code comments and return a stable, inspectable result for page 369.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 370 / 561Chapter 25: String Algorithms and Automata
Run-length encoding
Page-local deep read
Mental model for Run-length encoding: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 370, the goal is not memorizing run-length encoding; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Run-length encoding is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Run-length encoding before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 370: Run-length encoding
EXAMPLE = {'page': 370, 'topic': 'Run-length encoding', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Run-length encoding.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Run-length encoding', 'watch_for': 'The invariant that makes Run-length encoding safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='370-run_length_encodin-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def run_length_encoding_p370(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return run_length_encoding_p370(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Run-length encoding" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Run-length encoding.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 370.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement run-length encoding twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 371 / 561Chapter 25: String Algorithms and Automata
Burrows-Wheeler transform
Page-local deep read
Mental model for Burrows-Wheeler transform: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 371, the goal is not memorizing burrows-wheeler transform; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Burrows-Wheeler transform is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Burrows-Wheeler transform before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 371: Burrows-Wheeler transform
EXAMPLE = {'page': 371, 'topic': 'Burrows-Wheeler transform', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Burrows-Wheeler transform.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Burrows-Wheeler transform', 'watch_for': 'The invariant that makes Burrows-Wheeler transform safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='371-burrows_wheeler_tr-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def burrows_wheeler_transform_p371(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return burrows_wheeler_transform_p371(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Burrows-Wheeler transform" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Burrows-Wheeler transform.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 371.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for burrows-wheeler transform and explain what each one stresses.
Page 372 / 561Chapter 25: String Algorithms and Automata
Text indexing
Page-local deep read
Mental model for Text indexing: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 372, the goal is not memorizing text indexing; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Text indexing is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Text indexing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 372: Text indexing
EXAMPLE = {'page': 372, 'topic': 'Text indexing', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Text indexing.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Text indexing', 'watch_for': 'The invariant that makes Text indexing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='372-text_indexing-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def text_indexing_p372(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return text_indexing_p372(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Text indexing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 372 curation harness: Text indexing
EXAMPLE_KIND = "string_alg"
EXAMPLE_TITLE = "Text indexing"
SAMPLE = {
"text": "abracadabra",
"pattern": "abra",
"words": [
"he",
"she",
"his",
"hers"
],
"page_marker": "372-text_indexing"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "text",
"marker": sample.get("page_marker", "372-text_indexing"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "text": []} if "text" in sample else dict(sample)),
("single-step", {**sample, "text": sample.get("text", [])[:1]} if isinstance(sample.get("text"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "372-text_indexing"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Text indexing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 372.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for text indexing, then point to the line of code that preserves it.
Page 373 / 561Chapter 25: String Algorithms and Automata
Unicode and normalization
Page-local deep read
Mental model for Unicode and normalization: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 373, the goal is not memorizing unicode and normalization; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Unicode and normalization is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Unicode and normalization before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as often linear after preprocessing time and preprocessing structures space in the common model, then revisit the bound when the input representation changes.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 373: Unicode and normalization
EXAMPLE = {'page': 373, 'topic': 'Unicode and normalization', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Unicode and normalization.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Unicode and normalization', 'watch_for': 'The invariant that makes Unicode and normalization safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='373-unicode_and_normal-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def unicode_and_normalization_p373(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return unicode_and_normalization_p373(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Unicode and normalization" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 373 curation harness: Unicode and normalization
EXAMPLE_KIND = "string_alg"
EXAMPLE_TITLE = "Unicode and normalization"
SAMPLE = {
"text": "abracadabra",
"pattern": "abra",
"words": [
"he",
"she",
"his",
"hers"
],
"page_marker": "373-unicode_and_normaliz"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "text",
"marker": sample.get("page_marker", "373-unicode_and_normaliz"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "text": []} if "text" in sample else dict(sample)),
("single-step", {**sample, "text": sample.get("text", [])[:1]} if isinstance(sample.get("text"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "373-unicode_and_normaliz"))
Browser JavaScript companion
// Page 373 browser-side experiment: Unicode and normalization
const pageExample373 = {"text":"abracadabra","pattern":"abra","words":["he","she","his","hers"],"page_marker":"373-unicode_and_normaliz"};
function summarizePage373(sample = pageExample373) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Unicode and normalization",
kind: "string_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage373());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Unicode and normalization.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 373.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 374 / 561Chapter 25: String Algorithms and Automata
String algorithm test cases
Page-local deep read
Mental model for String algorithm test cases: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 374, the goal is not memorizing string algorithm test cases; it is recognizing the representation, the safe transition, and the stopping condition inside the String Algorithms and Automata chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: String algorithm test cases is one small tool in the larger String Algorithms and Automata toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for String algorithm test cases before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: encoding assumptions. Make this risk visible in tests and in code comments.
Common pitfall: Algorithms over characters can fail in user-facing text unless normalization and grapheme boundaries are considered.
# Page 374: String algorithm test cases
EXAMPLE = {'page': 374, 'topic': 'String algorithm test cases', 'chapter': 'String Algorithms and Automata', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for String algorithm test cases.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for String algorithm test cases', 'watch_for': 'The invariant that makes String algorithm test cases safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='374-string_algorithm_t-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def string_algorithm_test_cases_p374(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return string_algorithm_test_cases_p374(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "String algorithm test cases" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 374 curation harness: String algorithm test cases
EXAMPLE_KIND = "string_alg"
EXAMPLE_TITLE = "String algorithm test cases"
SAMPLE = {
"text": "abracadabra",
"pattern": "abra",
"words": [
"he",
"she",
"his",
"hers"
],
"page_marker": "374-string_algorithm_tes"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "text",
"marker": sample.get("page_marker", "374-string_algorithm_tes"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "text": []} if "text" in sample else dict(sample)),
("single-step", {**sample, "text": sample.get("text", [])[:1]} if isinstance(sample.get("text"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "374-string_algorithm_tes"))
Browser JavaScript companion
// Page 374 browser-side experiment: String algorithm test cases
const pageExample374 = {"text":"abracadabra","pattern":"abra","words":["he","she","his","hers"],"page_marker":"374-string_algorithm_tes"};
function summarizePage374(sample = pageExample374) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "String algorithm test cases",
kind: "string_alg",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage374());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by String algorithm test cases.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 374.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 375 / 561Chapter 26: Number Theory and Combinatorics
Euclidean algorithm
Page-local deep read
Mental model for Euclidean algorithm: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 375, the goal is not memorizing euclidean algorithm; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Euclidean algorithm is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Euclidean algorithm before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
This is a chapter-level anchor example. Read it alongside the page-specific labs lower down.
def smallest_prime_factors(n: int) -> list[int]:
spf = list(range(n + 1))
for i in range(2, int(n ** 0.5) + 1):
if spf[i] == i:
for j in range(i * i, n + 1, i):
if spf[j] == j:
spf[j] = i
return spf
def factorize(x: int, spf: list[int]) -> list[int]:
out = []
while x > 1:
out.append(spf[x])
x //= spf[x]
return out
spf = smallest_prime_factors(50)
print(factorize(36, spf))
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 26: Number Theory and Combinatorics
function gcd(a, b) { while (b !== 0) [a, b] = [b, a % b]; return Math.abs(a); }
function modPow(a, e, m) { let r = 1 % m; while (e > 0) { if (e & 1) r = (r * a) % m; a = (a * a) % m; e >>= 1; } return r; }
console.log(gcd(84, 30), modPow(7, 13, 19));
Chapter anchor: This page is the Chapter 26 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Number Theory and Combinatorics.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: integer size. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 375: Euclidean algorithm
EXAMPLE = {'page': 375, 'topic': 'Euclidean algorithm', 'chapter': 'Number Theory and Combinatorics', 'kind': 'gcd', 'scenario': 'Run a concrete gcd miniature for Euclidean algorithm.', 'sample_input': {'a': 89, 'b': 34, 'n': 65, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Euclidean algorithm', 'watch_for': 'The invariant that makes Euclidean algorithm safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the gcd example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='375-euclidean_algorith-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def euclidean_algorithm_p375(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return euclidean_algorithm_p375(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Euclidean algorithm, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Euclidean algorithm.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the gcd invariant described in the code comments and return a stable, inspectable result for page 375.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement euclidean algorithm twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 376 / 561Chapter 26: Number Theory and Combinatorics
Extended Euclid
Page-local deep read
Mental model for Extended Euclid: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 376, the goal is not memorizing extended euclid; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Extended Euclid is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Extended Euclid before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 376: Extended Euclid
EXAMPLE = {'page': 376, 'topic': 'Extended Euclid', 'chapter': 'Number Theory and Combinatorics', 'kind': 'extended_gcd', 'scenario': 'Run a concrete extended gcd miniature for Extended Euclid.', 'sample_input': {'a': 90, 'b': 35, 'n': 66, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Extended Euclid', 'watch_for': 'The invariant that makes Extended Euclid safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the extended gcd example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='376-extended_euclid-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def extended_euclid_p376(a, b):
if b == 0: return (abs(a), 1 if a >= 0 else -1, 0)
g, x1, y1 = extended_euclid_p376(b, a % b)
return g, y1, x1 - (a // b) * y1
def run_example(example=EXAMPLE):
d=example['sample_input']; return extended_euclid_p376(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Extended Euclid, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Extended Euclid.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the extended gcd invariant described in the code comments and return a stable, inspectable result for page 376.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for extended euclid and explain what each one stresses.
Page 377 / 561Chapter 26: Number Theory and Combinatorics
Modular arithmetic
Page-local deep read
Mental model for Modular arithmetic: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 377, the goal is not memorizing modular arithmetic; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Modular arithmetic is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Modular arithmetic before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 377: Modular arithmetic
EXAMPLE = {'page': 377, 'topic': 'Modular arithmetic', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Modular arithmetic.', 'sample_input': {'a': 91, 'b': 36, 'n': 67, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Modular arithmetic', 'watch_for': 'The invariant that makes Modular arithmetic safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='377-modular_arithmetic-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def modular_arithmetic_p377(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return modular_arithmetic_p377(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Modular arithmetic" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Modular arithmetic, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Modular arithmetic.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 377.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for modular arithmetic, then point to the line of code that preserves it.
Page 378 / 561Chapter 26: Number Theory and Combinatorics
Fast modular exponentiation
Page-local deep read
Mental model for Fast modular exponentiation: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 378, the goal is not memorizing fast modular exponentiation; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Fast modular exponentiation is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Fast modular exponentiation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Fast modular exponentiation whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: integer size. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 378: Fast modular exponentiation
EXAMPLE = {'page': 378, 'topic': 'Fast modular exponentiation', 'chapter': 'Number Theory and Combinatorics', 'kind': 'mod_pow', 'scenario': 'Run a concrete mod pow miniature for Fast modular exponentiation.', 'sample_input': {'a': 92, 'b': 30, 'n': 68, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Fast modular exponentiation', 'watch_for': 'The invariant that makes Fast modular exponentiation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the mod pow example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='378-fast_modular_expon-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def fast_modular_exponentiation_p378(base, exp, mod):
result = 1 % mod; base %= mod
while exp:
if exp & 1: result = result * base % mod
base = base * base % mod; exp >>= 1
return result
def run_example(example=EXAMPLE):
d=example['sample_input']; return fast_modular_exponentiation_p378(d['a'], d['b'], d['mod'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Fast modular exponentiation, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Fast modular exponentiation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the mod pow invariant described in the code comments and return a stable, inspectable result for page 378.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 379 / 561Chapter 26: Number Theory and Combinatorics
Modular inverse
Page-local deep read
Mental model for Modular inverse: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 379, the goal is not memorizing modular inverse; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Modular inverse is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Modular inverse before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 379: Modular inverse
EXAMPLE = {'page': 379, 'topic': 'Modular inverse', 'chapter': 'Number Theory and Combinatorics', 'kind': 'mod_inverse', 'scenario': 'Run a concrete mod inverse miniature for Modular inverse.', 'sample_input': {'a': 93, 'b': 31, 'n': 69, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Modular inverse', 'watch_for': 'The invariant that makes Modular inverse safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the mod inverse example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='379-modular_inverse-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def modular_inverse_p379(base, exp, mod):
result = 1 % mod; base %= mod
while exp:
if exp & 1: result = result * base % mod
base = base * base % mod; exp >>= 1
return result
def run_example(example=EXAMPLE):
d=example['sample_input']; return modular_inverse_p379(d['a'], d['b'], d['mod'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Modular inverse, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Modular inverse.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the mod inverse invariant described in the code comments and return a stable, inspectable result for page 379.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 380 / 561Chapter 26: Number Theory and Combinatorics
Sieve of Eratosthenes
Page-local deep read
Mental model for Sieve of Eratosthenes: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 380, the goal is not memorizing sieve of eratosthenes; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sieve of Eratosthenes is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sieve of Eratosthenes before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 380: Sieve of Eratosthenes
EXAMPLE = {'page': 380, 'topic': 'Sieve of Eratosthenes', 'chapter': 'Number Theory and Combinatorics', 'kind': 'sieve', 'scenario': 'Run a concrete sieve miniature for Sieve of Eratosthenes.', 'sample_input': {'a': 84, 'b': 32, 'n': 50, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Sieve of Eratosthenes', 'watch_for': 'The invariant that makes Sieve of Eratosthenes safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sieve example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='380-sieve_of_eratosthe-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def sieve_of_eratosthenes_p380(n):
is_prime = [True] * (n + 1); is_prime[:2] = [False, False]
p = 2
while p * p <= n:
if is_prime[p]:
for m in range(p*p, n+1, p): is_prime[m] = False
p += 1
return [i for i, ok in enumerate(is_prime) if ok]
def run_example(example=EXAMPLE):
return sieve_of_eratosthenes_p380(example['sample_input']['n'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Sieve of Eratosthenes, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 380 curation harness: Sieve of Eratosthenes
EXAMPLE_KIND = "sieve"
EXAMPLE_TITLE = "Sieve of Eratosthenes"
SAMPLE = {
"a": 84,
"b": 32,
"n": 50,
"mod": 101,
"residues": [
2,
3,
2
],
"moduli": [
3,
5,
7
],
"page_marker": "380-sieve_of_eratosthene"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "a",
"marker": sample.get("page_marker", "380-sieve_of_eratosthene"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "a": []} if "a" in sample else dict(sample)),
("single-step", {**sample, "a": sample.get("a", [])[:1]} if isinstance(sample.get("a"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "380-sieve_of_eratosthene"))
Browser JavaScript companion
// Page 380 browser-side experiment: Sieve of Eratosthenes
const pageExample380 = {"a":84,"b":32,"n":50,"mod":101,"residues":[2,3,2],"moduli":[3,5,7],"page_marker":"380-sieve_of_eratosthene"};
function summarizePage380(sample = pageExample380) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Sieve of Eratosthenes",
kind: "sieve",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage380());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Sieve of Eratosthenes.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sieve invariant described in the code comments and return a stable, inspectable result for page 380.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement sieve of eratosthenes twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 381 / 561Chapter 26: Number Theory and Combinatorics
Prime factorization
Page-local deep read
Mental model for Prime factorization: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 381, the goal is not memorizing prime factorization; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Prime factorization is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Prime factorization before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 381: Prime factorization
EXAMPLE = {'page': 381, 'topic': 'Prime factorization', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Prime factorization.', 'sample_input': {'a': 85, 'b': 33, 'n': 51, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Prime factorization', 'watch_for': 'The invariant that makes Prime factorization safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='381-prime_factorizatio-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prime_factorization_p381(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return prime_factorization_p381(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Prime factorization" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Prime factorization, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 381 curation harness: Prime factorization
EXAMPLE_KIND = "number_theory"
EXAMPLE_TITLE = "Prime factorization"
SAMPLE = {
"a": 85,
"b": 33,
"n": 51,
"mod": 101,
"residues": [
2,
3,
2
],
"moduli": [
3,
5,
7
],
"page_marker": "381-prime_factorization"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "a",
"marker": sample.get("page_marker", "381-prime_factorization"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "a": []} if "a" in sample else dict(sample)),
("single-step", {**sample, "a": sample.get("a", [])[:1]} if isinstance(sample.get("a"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "381-prime_factorization"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Prime factorization.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 381.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for prime factorization and explain what each one stresses.
Page 382 / 561Chapter 26: Number Theory and Combinatorics
Primality testing
Page-local deep read
Mental model for Primality testing: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 382, the goal is not memorizing primality testing; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Primality testing is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Primality testing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 382: Primality testing
EXAMPLE = {'page': 382, 'topic': 'Primality testing', 'chapter': 'Number Theory and Combinatorics', 'kind': 'primality', 'scenario': 'Run a concrete primality miniature for Primality testing.', 'sample_input': {'a': 86, 'b': 34, 'n': 52, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Primality testing', 'watch_for': 'The invariant that makes Primality testing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the primality example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='382-primality_testing-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def primality_testing_p382(n):
if n < 2: return False
if n % 2 == 0: return n == 2
d = 3
while d * d <= n:
if n % d == 0: return False
d += 2
return True
def run_example(example=EXAMPLE):
return {n: primality_testing_p382(n) for n in range(29, 38)}
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Primality testing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Primality testing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the primality invariant described in the code comments and return a stable, inspectable result for page 382.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for primality testing, then point to the line of code that preserves it.
Page 383 / 561Chapter 26: Number Theory and Combinatorics
Chinese remainder theorem
Page-local deep read
Mental model for Chinese remainder theorem: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 383, the goal is not memorizing chinese remainder theorem; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Chinese remainder theorem is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Chinese remainder theorem before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as often logarithmic or sieve-like time and varies space in the common model, then revisit the bound when the input representation changes.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 383: Chinese remainder theorem
EXAMPLE = {'page': 383, 'topic': 'Chinese remainder theorem', 'chapter': 'Number Theory and Combinatorics', 'kind': 'crt', 'scenario': 'Run a concrete crt miniature for Chinese remainder theorem.', 'sample_input': {'a': 87, 'b': 35, 'n': 53, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Chinese remainder theorem', 'watch_for': 'The invariant that makes Chinese remainder theorem safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the crt example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='383-chinese_remainder_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def inv(a, m):
return pow(a, -1, m)
def chinese_remainder_theorem_p383(residues, moduli):
M = 1
for m in moduli: M *= m
total = 0
for r, m in zip(residues, moduli):
Mi = M // m; total += r * Mi * inv(Mi, m)
return total % M
def run_example(example=EXAMPLE):
d=example['sample_input']; return chinese_remainder_theorem_p383(d['residues'], d['moduli'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Chinese remainder theorem, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Chinese remainder theorem.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the crt invariant described in the code comments and return a stable, inspectable result for page 383.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 384 / 561Chapter 26: Number Theory and Combinatorics
Euler phi
Page-local deep read
Mental model for Euler phi: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 384, the goal is not memorizing euler phi; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Euler phi is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Euler phi before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 384: Euler phi
EXAMPLE = {'page': 384, 'topic': 'Euler phi', 'chapter': 'Number Theory and Combinatorics', 'kind': 'tree_alg', 'scenario': 'Run a concrete tree alg miniature for Euler phi.', 'sample_input': {'values': [9, 20, 31, 2, 13, 24, 35], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Euler phi', 'watch_for': 'The invariant that makes Euler phi safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the tree alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='384-euler_phi-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def euler_phi_p384(tree, root):
order = []
def visit(node, depth):
order.append((node, depth))
for child in tree.get(node, []): visit(child, depth + 1)
visit(root, 0)
return order
def run_example(example=EXAMPLE):
return euler_phi_p384(example['sample_input']['tree'], 'A')
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Euler phi" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Euler phi.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the tree alg invariant described in the code comments and return a stable, inspectable result for page 384.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 385 / 561Chapter 26: Number Theory and Combinatorics
Combinations n choose k
Page-local deep read
Mental model for Combinations n choose k: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 385, the goal is not memorizing combinations n choose k; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Combinations n choose k is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Combinations n choose k before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 385: Combinations n choose k
EXAMPLE = {'page': 385, 'topic': 'Combinations n choose k', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Combinations n choose k.', 'sample_input': {'a': 89, 'b': 30, 'n': 55, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Combinations n choose k', 'watch_for': 'The invariant that makes Combinations n choose k safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='385-combinations_n_cho-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def combinations_n_choose_k_p385(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return combinations_n_choose_k_p385(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Combinations n choose k" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Combinations n choose k, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 385 curation harness: Combinations n choose k
EXAMPLE_KIND = "number_theory"
EXAMPLE_TITLE = "Combinations n choose k"
SAMPLE = {
"a": 89,
"b": 30,
"n": 55,
"mod": 101,
"residues": [
2,
3,
2
],
"moduli": [
3,
5,
7
],
"page_marker": "385-combinations_n_choos"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "a",
"marker": sample.get("page_marker", "385-combinations_n_choos"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "a": []} if "a" in sample else dict(sample)),
("single-step", {**sample, "a": sample.get("a", [])[:1]} if isinstance(sample.get("a"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "385-combinations_n_choos"))
Browser JavaScript companion
// Page 385 browser-side experiment: Combinations n choose k
const pageExample385 = {"a":89,"b":30,"n":55,"mod":101,"residues":[2,3,2],"moduli":[3,5,7],"page_marker":"385-combinations_n_choos"};
function summarizePage385(sample = pageExample385) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Combinations n choose k",
kind: "number_theory",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage385());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Combinations n choose k.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 385.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement combinations n choose k twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 386 / 561Chapter 26: Number Theory and Combinatorics
Pascal triangle
Page-local deep read
Mental model for Pascal triangle: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 386, the goal is not memorizing pascal triangle; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Pascal triangle is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Pascal triangle before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 386: Pascal triangle
EXAMPLE = {'page': 386, 'topic': 'Pascal triangle', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Pascal triangle.', 'sample_input': {'a': 90, 'b': 31, 'n': 56, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Pascal triangle', 'watch_for': 'The invariant that makes Pascal triangle safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='386-pascal_triangle-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def pascal_triangle_p386(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return pascal_triangle_p386(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Pascal triangle" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Pascal triangle, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Pascal triangle.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 386.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for pascal triangle and explain what each one stresses.
Page 387 / 561Chapter 26: Number Theory and Combinatorics
Inclusion-exclusion
Page-local deep read
Mental model for Inclusion-exclusion: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 387, the goal is not memorizing inclusion-exclusion; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Inclusion-exclusion is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Inclusion-exclusion before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 387: Inclusion-exclusion
EXAMPLE = {'page': 387, 'topic': 'Inclusion-exclusion', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Inclusion-exclusion.', 'sample_input': {'a': 91, 'b': 32, 'n': 57, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Inclusion-exclusion', 'watch_for': 'The invariant that makes Inclusion-exclusion safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='387-inclusion_exclusio-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def inclusion_exclusion_p387(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return inclusion_exclusion_p387(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Inclusion-exclusion" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Inclusion-exclusion, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Inclusion-exclusion.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 387.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for inclusion-exclusion, then point to the line of code that preserves it.
Page 388 / 561Chapter 26: Number Theory and Combinatorics
Pigeonhole principle
Page-local deep read
Mental model for Pigeonhole principle: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 388, the goal is not memorizing pigeonhole principle; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Pigeonhole principle is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Pigeonhole principle before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Pigeonhole principle whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 388: Pigeonhole principle
EXAMPLE = {'page': 388, 'topic': 'Pigeonhole principle', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Pigeonhole principle.', 'sample_input': {'a': 92, 'b': 33, 'n': 58, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Pigeonhole principle', 'watch_for': 'The invariant that makes Pigeonhole principle safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='388-pigeonhole_princip-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def pigeonhole_principle_p388(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return pigeonhole_principle_p388(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Pigeonhole principle" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Pigeonhole principle, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Pigeonhole principle.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 388.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 389 / 561Chapter 26: Number Theory and Combinatorics
Generating functions
Page-local deep read
Mental model for Generating functions: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 389, the goal is not memorizing generating functions; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Generating functions is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Generating functions before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 389: Generating functions
EXAMPLE = {'page': 389, 'topic': 'Generating functions', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Generating functions.', 'sample_input': {'a': 93, 'b': 34, 'n': 59, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Generating functions', 'watch_for': 'The invariant that makes Generating functions safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='389-generating_functio-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def generating_functions_p389(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return generating_functions_p389(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Generating functions" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Generating functions, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Generating functions.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 389.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 390 / 561Chapter 26: Number Theory and Combinatorics
Burnside lemma intuition
Page-local deep read
Mental model for Burnside lemma intuition: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 390, the goal is not memorizing burnside lemma intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Burnside lemma intuition is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Burnside lemma intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 390: Burnside lemma intuition
EXAMPLE = {'page': 390, 'topic': 'Burnside lemma intuition', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Burnside lemma intuition.', 'sample_input': {'a': 84, 'b': 35, 'n': 60, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Burnside lemma intuition', 'watch_for': 'The invariant that makes Burnside lemma intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='390-burnside_lemma_int-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def burnside_lemma_intuition_p390(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return burnside_lemma_intuition_p390(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Burnside lemma intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Burnside lemma intuition, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Burnside lemma intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 390.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement burnside lemma intuition twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 391 / 561Chapter 26: Number Theory and Combinatorics
Catalan numbers
Page-local deep read
Mental model for Catalan numbers: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 391, the goal is not memorizing catalan numbers; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Catalan numbers is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Catalan numbers before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 391: Catalan numbers
EXAMPLE = {'page': 391, 'topic': 'Catalan numbers', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Catalan numbers.', 'sample_input': {'a': 85, 'b': 36, 'n': 61, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Catalan numbers', 'watch_for': 'The invariant that makes Catalan numbers safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='391-catalan_numbers-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def catalan_numbers_p391(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return catalan_numbers_p391(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Catalan numbers" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Catalan numbers, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Catalan numbers.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 391.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for catalan numbers and explain what each one stresses.
Page 392 / 561Chapter 26: Number Theory and Combinatorics
Random number generation cautions
Page-local deep read
Mental model for Random number generation cautions: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 392, the goal is not memorizing random number generation cautions; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Random number generation cautions is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Random number generation cautions before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 392: Random number generation cautions
EXAMPLE = {'page': 392, 'topic': 'Random number generation cautions', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Random number generation cautions.', 'sample_input': {'a': 86, 'b': 30, 'n': 62, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Random number generation cautions', 'watch_for': 'The invariant that makes Random number generation cautions safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='392-random_number_gene-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def random_number_generation_cautions_p392(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return random_number_generation_cautions_p392(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Random number generation cautions" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Random number generation cautions, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 392 curation harness: Random number generation cautions
EXAMPLE_KIND = "number_theory"
EXAMPLE_TITLE = "Random number generation cautions"
SAMPLE = {
"a": 86,
"b": 30,
"n": 62,
"mod": 101,
"residues": [
2,
3,
2
],
"moduli": [
3,
5,
7
],
"page_marker": "392-random_number_genera"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "a",
"marker": sample.get("page_marker", "392-random_number_genera"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "a": []} if "a" in sample else dict(sample)),
("single-step", {**sample, "a": sample.get("a", [])[:1]} if isinstance(sample.get("a"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "392-random_number_genera"))
Browser JavaScript companion
// Page 392 browser-side experiment: Random number generation cautions
const pageExample392 = {"a":86,"b":30,"n":62,"mod":101,"residues":[2,3,2],"moduli":[3,5,7],"page_marker":"392-random_number_genera"};
function summarizePage392(sample = pageExample392) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Random number generation cautions",
kind: "number_theory",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage392());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Random number generation cautions.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 392.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for random number generation cautions, then point to the line of code that preserves it.
Page 393 / 561Chapter 26: Number Theory and Combinatorics
FFT and convolution intuition
Page-local deep read
Mental model for FFT and convolution intuition: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 393, the goal is not memorizing fft and convolution intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: FFT and convolution intuition is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for FFT and convolution intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as often logarithmic or sieve-like time and varies space in the common model, then revisit the bound when the input representation changes.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 393: FFT and convolution intuition
EXAMPLE = {'page': 393, 'topic': 'FFT and convolution intuition', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for FFT and convolution intuition.', 'sample_input': {'a': 87, 'b': 31, 'n': 63, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for FFT and convolution intuition', 'watch_for': 'The invariant that makes FFT and convolution intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='393-fft_and_convolutio-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def fft_and_convolution_intuition_p393(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return fft_and_convolution_intuition_p393(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "FFT and convolution intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of FFT and convolution intuition, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 393 curation harness: FFT and convolution intuition
EXAMPLE_KIND = "number_theory"
EXAMPLE_TITLE = "FFT and convolution intuition"
SAMPLE = {
"a": 87,
"b": 31,
"n": 63,
"mod": 101,
"residues": [
2,
3,
2
],
"moduli": [
3,
5,
7
],
"page_marker": "393-fft_and_convolution_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "a",
"marker": sample.get("page_marker", "393-fft_and_convolution_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "a": []} if "a" in sample else dict(sample)),
("single-step", {**sample, "a": sample.get("a", [])[:1]} if isinstance(sample.get("a"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "393-fft_and_convolution_"))
Browser JavaScript companion
// Page 393 browser-side experiment: FFT and convolution intuition
const pageExample393 = {"a":87,"b":31,"n":63,"mod":101,"residues":[2,3,2],"moduli":[3,5,7],"page_marker":"393-fft_and_convolution_"};
function summarizePage393(sample = pageExample393) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "FFT and convolution intuition",
kind: "number_theory",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage393());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by FFT and convolution intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 393.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 394 / 561Chapter 26: Number Theory and Combinatorics
Number theory implementation traps
Page-local deep read
Mental model for Number theory implementation traps: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 394, the goal is not memorizing number theory implementation traps; it is recognizing the representation, the safe transition, and the stopping condition inside the Number Theory and Combinatorics chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Number theory implementation traps is one small tool in the larger Number Theory and Combinatorics toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Number theory implementation traps before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: overflow and modulus mistakes. Make this risk visible in tests and in code comments.
Common pitfall: Modulo arithmetic changes division; you need inverses under the right conditions, not ordinary division.
# Page 394: Number theory implementation traps
EXAMPLE = {'page': 394, 'topic': 'Number theory implementation traps', 'chapter': 'Number Theory and Combinatorics', 'kind': 'number_theory', 'scenario': 'Run a concrete number theory miniature for Number theory implementation traps.', 'sample_input': {'a': 88, 'b': 32, 'n': 64, 'mod': 101, 'residues': [2, 3, 2], 'moduli': [3, 5, 7]}, 'expected_output': 'Inspectable result for Number theory implementation traps', 'watch_for': 'The invariant that makes Number theory implementation traps safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the number theory example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='394-number_theory_impl-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def number_theory_implementation_traps_p394(a, b):
trace = []
while b:
trace.append((a, b, a % b)); a, b = b, a % b
return {'gcd': abs(a), 'trace': trace}
def run_example(example=EXAMPLE):
d=example['sample_input']; return number_theory_implementation_traps_p394(d['a'], d['b'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track a, b, n, mod before reading the answer.
Common trap
Do not memorize the label "Number theory implementation traps" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Number theory implementation traps, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 394 curation harness: Number theory implementation traps
EXAMPLE_KIND = "number_theory"
EXAMPLE_TITLE = "Number theory implementation traps"
SAMPLE = {
"a": 88,
"b": 32,
"n": 64,
"mod": 101,
"residues": [
2,
3,
2
],
"moduli": [
3,
5,
7
],
"page_marker": "394-number_theory_implem"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "a",
"marker": sample.get("page_marker", "394-number_theory_implem"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "a": []} if "a" in sample else dict(sample)),
("single-step", {**sample, "a": sample.get("a", [])[:1]} if isinstance(sample.get("a"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "394-number_theory_implem"))
Browser JavaScript companion
// Page 394 browser-side experiment: Number theory implementation traps
const pageExample394 = {"a":88,"b":32,"n":64,"mod":101,"residues":[2,3,2],"moduli":[3,5,7],"page_marker":"394-number_theory_implem"};
function summarizePage394(sample = pageExample394) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Number theory implementation traps",
kind: "number_theory",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage394());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['a'], then compare it with the first line produced by Number theory implementation traps.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the number theory invariant described in the code comments and return a stable, inspectable result for page 394.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 395 / 561Chapter 27: Computational Geometry
Points, vectors, and orientation
Page-local deep read
Mental model for Points, vectors, and orientation: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 395, the goal is not memorizing points, vectors, and orientation; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Points, vectors, and orientation is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Points, vectors, and orientation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 27: Computational Geometry
function cross(o, a, b) { return (a[0]-o[0])*(b[1]-o[1]) - (a[1]-o[1])*(b[0]-o[0]); }
function orientation(a, b, c) { const x = cross(a,b,c); return x > 0 ? 'left' : x < 0 ? 'right' : 'collinear'; }
console.log(orientation([0,0], [2,0], [1,1]));
Chapter anchor: This page is the Chapter 27 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Computational Geometry.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: precision errors. Make this risk visible in tests and in code comments.
Common pitfall: Floating-point comparisons near zero can flip orientation tests and destroy an otherwise correct algorithm.
# Page 395: Points, vectors, and orientation
EXAMPLE = {'page': 395, 'topic': 'Points, vectors, and orientation', 'chapter': 'Computational Geometry', 'kind': 'orientation', 'scenario': 'Run a concrete orientation miniature for Points, vectors, and orientation.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Points, vectors, and orientation', 'watch_for': 'The invariant that makes Points, vectors, and orientation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the orientation example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='395-points_vectors_and-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(a, b, c):
return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def points_vectors_and_orientation_p395(a, b, c):
value = cross(a,b,c)
return 'left' if value > 0 else 'right' if value < 0 else 'collinear'
def run_example(example=EXAMPLE):
d=example['sample_input']; return points_vectors_and_orientation_p395(d['a'], d['b'], d['c'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Points, vectors, and orientation, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 395 curation harness: Points, vectors, and orientation
EXAMPLE_KIND = "orientation"
EXAMPLE_TITLE = "Points, vectors, and orientation"
SAMPLE = {
"points": [
[
0,
0
],
[
2,
1
],
[
1,
3
],
[
3,
3
],
[
4,
0
],
[
2,
2
]
],
"a": [
0,
0
],
"b": [
4,
0
],
"c": [
2,
3
],
"d": [
2,
-1
],
"page_marker": "395-points_vectors_and_o"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "points",
"marker": sample.get("page_marker", "395-points_vectors_and_o"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "points": []} if "points" in sample else dict(sample)),
("single-step", {**sample, "points": sample.get("points", [])[:1]} if isinstance(sample.get("points"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "395-points_vectors_and_o"))
Browser JavaScript companion
// Page 395 browser-side experiment: Points, vectors, and orientation
const pageExample395 = {"points":[[0,0],[2,1],[1,3],[3,3],[4,0],[2,2]],"a":[0,0],"b":[4,0],"c":[2,3],"d":[2,-1],"page_marker":"395-points_vectors_and_o"};
function summarizePage395(sample = pageExample395) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Points, vectors, and orientation",
kind: "orientation",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage395());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Points, vectors, and orientation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the orientation invariant described in the code comments and return a stable, inspectable result for page 395.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement points, vectors, and orientation twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 396 / 561Chapter 27: Computational Geometry
Line segment intersection
Page-local deep read
Mental model for Line segment intersection: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 396, the goal is not memorizing line segment intersection; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Line segment intersection is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Line segment intersection before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: precision errors. Make this risk visible in tests and in code comments.
Common pitfall: Floating-point comparisons near zero can flip orientation tests and destroy an otherwise correct algorithm.
# Page 396: Line segment intersection
EXAMPLE = {'page': 396, 'topic': 'Line segment intersection', 'chapter': 'Computational Geometry', 'kind': 'segment_intersection', 'scenario': 'Run a concrete segment intersection miniature for Line segment intersection.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Line segment intersection', 'watch_for': 'The invariant that makes Line segment intersection safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the segment intersection example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='396-line_segment_inter-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def orient(a,b,c):
return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def line_segment_intersection_p396(a,b,c,d):
return orient(a,b,c) * orient(a,b,d) <= 0 and orient(c,d,a) * orient(c,d,b) <= 0
def run_example(example=EXAMPLE):
d=example['sample_input']; return line_segment_intersection_p396(d['a'], d['b'], d['c'], d['d'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Line segment intersection, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Line segment intersection.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the segment intersection invariant described in the code comments and return a stable, inspectable result for page 396.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for line segment intersection and explain what each one stresses.
Page 397 / 561Chapter 27: Computational Geometry
Polygon area
Page-local deep read
Mental model for Polygon area: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 397, the goal is not memorizing polygon area; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Polygon area is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Polygon area before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: precision errors. Make this risk visible in tests and in code comments.
Common pitfall: Floating-point comparisons near zero can flip orientation tests and destroy an otherwise correct algorithm.
# Page 397: Polygon area
EXAMPLE = {'page': 397, 'topic': 'Polygon area', 'chapter': 'Computational Geometry', 'kind': 'polygon_area', 'scenario': 'Run a concrete polygon area miniature for Polygon area.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Polygon area', 'watch_for': 'The invariant that makes Polygon area safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the polygon area example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='397-polygon_area-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def polygon_area_p397(points):
twice = 0
for (x1,y1),(x2,y2) in zip(points, points[1:]+points[:1]):
twice += x1*y2 - x2*y1
return abs(twice) / 2
def run_example(example=EXAMPLE):
return polygon_area_p397([(0,0),(4,0),(4,3),(0,3)])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Polygon area, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Polygon area.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the polygon area invariant described in the code comments and return a stable, inspectable result for page 397.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for polygon area, then point to the line of code that preserves it.
Page 398 / 561Chapter 27: Computational Geometry
Point in polygon
Page-local deep read
Mental model for Point in polygon: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 398, the goal is not memorizing point in polygon; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Point in polygon is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Point in polygon before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Point in polygon whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: precision errors. Make this risk visible in tests and in code comments.
Common pitfall: Floating-point comparisons near zero can flip orientation tests and destroy an otherwise correct algorithm.
# Page 398: Point in polygon
EXAMPLE = {'page': 398, 'topic': 'Point in polygon', 'chapter': 'Computational Geometry', 'kind': 'point_in_polygon', 'scenario': 'Run a concrete point in polygon miniature for Point in polygon.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Point in polygon', 'watch_for': 'The invariant that makes Point in polygon safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the point in polygon example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='398-point_in_polygon-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def point_in_polygon_p398(point, polygon):
x, y = point; inside = False
for (x1,y1),(x2,y2) in zip(polygon, polygon[1:]+polygon[:1]):
crosses = (y1 > y) != (y2 > y)
if crosses and x < (x2-x1)*(y-y1)/(y2-y1) + x1: inside = not inside
return inside
def run_example(example=EXAMPLE):
return point_in_polygon_p398((2,2), [(0,0),(4,0),(4,4),(0,4)])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Point in polygon, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 398 curation harness: Point in polygon
EXAMPLE_KIND = "point_in_polygon"
EXAMPLE_TITLE = "Point in polygon"
SAMPLE = {
"points": [
[
0,
0
],
[
2,
1
],
[
1,
3
],
[
3,
3
],
[
4,
0
],
[
2,
2
]
],
"a": [
0,
0
],
"b": [
4,
0
],
"c": [
2,
3
],
"d": [
2,
-1
],
"page_marker": "398-point_in_polygon"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "points",
"marker": sample.get("page_marker", "398-point_in_polygon"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "points": []} if "points" in sample else dict(sample)),
("single-step", {**sample, "points": sample.get("points", [])[:1]} if isinstance(sample.get("points"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "398-point_in_polygon"))
Browser JavaScript companion
// Page 398 browser-side experiment: Point in polygon
const pageExample398 = {"points":[[0,0],[2,1],[1,3],[3,3],[4,0],[2,2]],"a":[0,0],"b":[4,0],"c":[2,3],"d":[2,-1],"page_marker":"398-point_in_polygon"};
function summarizePage398(sample = pageExample398) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Point in polygon",
kind: "point_in_polygon",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage398());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Point in polygon.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the point in polygon invariant described in the code comments and return a stable, inspectable result for page 398.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 399 / 561Chapter 27: Computational Geometry
Convex hull Graham scan
Page-local deep read
Mental model for Convex hull Graham scan: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 399, the goal is not memorizing convex hull graham scan; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Convex hull Graham scan is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Convex hull Graham scan before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 399: Convex hull Graham scan
EXAMPLE = {'page': 399, 'topic': 'Convex hull Graham scan', 'chapter': 'Computational Geometry', 'kind': 'convex_hull', 'scenario': 'Run a concrete convex hull miniature for Convex hull Graham scan.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Convex hull Graham scan', 'watch_for': 'The invariant that makes Convex hull Graham scan safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the convex hull example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='399-convex_hull_graham-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(o,a,b): return (a[0]-o[0])*(b[1]-o[1])-(a[1]-o[1])*(b[0]-o[0])
def convex_hull_graham_scan_p399(points):
pts = sorted(set(points))
lower=[]
for p in pts:
while len(lower)>=2 and cross(lower[-2], lower[-1], p) <= 0: lower.pop()
lower.append(p)
upper=[]
for p in reversed(pts):
while len(upper)>=2 and cross(upper[-2], upper[-1], p) <= 0: upper.pop()
upper.append(p)
return lower[:-1] + upper[:-1]
def run_example(example=EXAMPLE):
return convex_hull_graham_scan_p399(example['sample_input']['points'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Convex Hull Lab
Random points are sorted and wrapped by a monotonic-chain hull.
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Convex hull Graham scan, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 399 curation harness: Convex hull Graham scan
EXAMPLE_KIND = "convex_hull"
EXAMPLE_TITLE = "Convex hull Graham scan"
SAMPLE = {
"points": [
[
0,
0
],
[
2,
1
],
[
1,
3
],
[
3,
3
],
[
4,
0
],
[
2,
2
]
],
"a": [
0,
0
],
"b": [
4,
0
],
"c": [
2,
3
],
"d": [
2,
-1
],
"page_marker": "399-convex_hull_graham_s"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "points",
"marker": sample.get("page_marker", "399-convex_hull_graham_s"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "points": []} if "points" in sample else dict(sample)),
("single-step", {**sample, "points": sample.get("points", [])[:1]} if isinstance(sample.get("points"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "399-convex_hull_graham_s"))
Browser JavaScript companion
// Page 399 browser-side experiment: Convex hull Graham scan
const pageExample399 = {"points":[[0,0],[2,1],[1,3],[3,3],[4,0],[2,2]],"a":[0,0],"b":[4,0],"c":[2,3],"d":[2,-1],"page_marker":"399-convex_hull_graham_s"};
function summarizePage399(sample = pageExample399) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Convex hull Graham scan",
kind: "convex_hull",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage399());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Convex hull Graham scan.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the convex hull invariant described in the code comments and return a stable, inspectable result for page 399.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 400 / 561Chapter 27: Computational Geometry
Convex hull monotonic chain
Page-local deep read
Mental model for Convex hull monotonic chain: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 400, the goal is not memorizing convex hull monotonic chain; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Convex hull monotonic chain is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Convex hull monotonic chain before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 400: Convex hull monotonic chain
EXAMPLE = {'page': 400, 'topic': 'Convex hull monotonic chain', 'chapter': 'Computational Geometry', 'kind': 'convex_hull', 'scenario': 'Run a concrete convex hull miniature for Convex hull monotonic chain.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Convex hull monotonic chain', 'watch_for': 'The invariant that makes Convex hull monotonic chain safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the convex hull example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='400-convex_hull_monoto-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(o,a,b): return (a[0]-o[0])*(b[1]-o[1])-(a[1]-o[1])*(b[0]-o[0])
def convex_hull_monotonic_chain_p400(points):
pts = sorted(set(points))
lower=[]
for p in pts:
while len(lower)>=2 and cross(lower[-2], lower[-1], p) <= 0: lower.pop()
lower.append(p)
upper=[]
for p in reversed(pts):
while len(upper)>=2 and cross(upper[-2], upper[-1], p) <= 0: upper.pop()
upper.append(p)
return lower[:-1] + upper[:-1]
def run_example(example=EXAMPLE):
return convex_hull_monotonic_chain_p400(example['sample_input']['points'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Convex hull monotonic chain, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Convex hull monotonic chain.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the convex hull invariant described in the code comments and return a stable, inspectable result for page 400.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement convex hull monotonic chain twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 401 / 561Chapter 27: Computational Geometry
Rotating calipers
Page-local deep read
Mental model for Rotating calipers: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 401, the goal is not memorizing rotating calipers; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rotating calipers is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rotating calipers before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: precision errors. Make this risk visible in tests and in code comments.
Common pitfall: Floating-point comparisons near zero can flip orientation tests and destroy an otherwise correct algorithm.
# Page 401: Rotating calipers
EXAMPLE = {'page': 401, 'topic': 'Rotating calipers', 'chapter': 'Computational Geometry', 'kind': 'geometry', 'scenario': 'Run a concrete geometry miniature for Rotating calipers.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Rotating calipers', 'watch_for': 'The invariant that makes Rotating calipers safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the geometry example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='401-rotating_calipers-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(a, b, c):
return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def rotating_calipers_p401(a, b, c):
value = cross(a,b,c)
return 'left' if value > 0 else 'right' if value < 0 else 'collinear'
def run_example(example=EXAMPLE):
d=example['sample_input']; return rotating_calipers_p401(d['a'], d['b'], d['c'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Do not memorize the label "Rotating calipers" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit coordinates, orientation signs, degeneracy checks, and the final geometric relation.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Rotating calipers.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the geometry invariant described in the code comments and return a stable, inspectable result for page 401.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for rotating calipers and explain what each one stresses.
Page 402 / 561Chapter 27: Computational Geometry
Closest pair of points
Page-local deep read
Mental model for Closest pair of points: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 402, the goal is not memorizing closest pair of points; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Closest pair of points is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Closest pair of points before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 402: Closest pair of points
EXAMPLE = {'page': 402, 'topic': 'Closest pair of points', 'chapter': 'Computational Geometry', 'kind': 'closest_pair', 'scenario': 'Run a concrete closest pair miniature for Closest pair of points.', 'sample_input': {'values': [15, 26, 37, 8, 19, 30, 1], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Closest pair of points', 'watch_for': 'The invariant that makes Closest pair of points safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the closest pair example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='402-closest_pair_of_po-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from math import hypot
def closest_pair_of_points_p402(points):
best = (float('inf'), None)
for i, a in enumerate(points):
for b in points[i+1:]:
d = hypot(a[0]-b[0], a[1]-b[1])
if d < best[0]: best = (d, (a, b))
return best
def run_example(example=EXAMPLE):
return closest_pair_of_points_p402(example['sample_input'].get('points', [(0,0),(2,1),(1,1)]))
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Closest pair of points, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 402 curation harness: Closest pair of points
EXAMPLE_KIND = "closest_pair"
EXAMPLE_TITLE = "Closest pair of points"
SAMPLE = {
"values": [
15,
26,
37,
8,
19,
30,
1
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "402-closest_pair_of_poin"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "402-closest_pair_of_poin"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "402-closest_pair_of_poin"))
Browser JavaScript companion
// Page 402 browser-side experiment: Closest pair of points
const pageExample402 = {"values":[15,26,37,8,19,30,1],"steps":["read","update","verify"],"page_marker":"402-closest_pair_of_poin"};
function summarizePage402(sample = pageExample402) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Closest pair of points",
kind: "closest_pair",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage402());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Closest pair of points.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the closest pair invariant described in the code comments and return a stable, inspectable result for page 402.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for closest pair of points, then point to the line of code that preserves it.
Page 403 / 561Chapter 27: Computational Geometry
Sweep line
Page-local deep read
Mental model for Sweep line: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 403, the goal is not memorizing sweep line; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sweep line is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sweep line before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 403: Sweep line
EXAMPLE = {'page': 403, 'topic': 'Sweep line', 'chapter': 'Computational Geometry', 'kind': 'geometry', 'scenario': 'Run a concrete geometry miniature for Sweep line.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Sweep line', 'watch_for': 'The invariant that makes Sweep line safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the geometry example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='403-sweep_line-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(a, b, c):
return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def sweep_line_p403(a, b, c):
value = cross(a,b,c)
return 'left' if value > 0 else 'right' if value < 0 else 'collinear'
def run_example(example=EXAMPLE):
d=example['sample_input']; return sweep_line_p403(d['a'], d['b'], d['c'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Do not memorize the label "Sweep line" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit coordinates, orientation signs, degeneracy checks, and the final geometric relation.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Sweep line.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the geometry invariant described in the code comments and return a stable, inspectable result for page 403.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 404 / 561Chapter 27: Computational Geometry
Rectangle union area
Page-local deep read
Mental model for Rectangle union area: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 404, the goal is not memorizing rectangle union area; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rectangle union area is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rectangle union area before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: precision errors. Make this risk visible in tests and in code comments.
Common pitfall: Floating-point comparisons near zero can flip orientation tests and destroy an otherwise correct algorithm.
# Page 404: Rectangle union area
EXAMPLE = {'page': 404, 'topic': 'Rectangle union area', 'chapter': 'Computational Geometry', 'kind': 'dsu', 'scenario': 'Run a concrete dsu miniature for Rectangle union area.', 'sample_input': {'values': [29, 40, 11, 22, 33, 4, 15], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Rectangle union area', 'watch_for': 'The invariant that makes Rectangle union area safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the dsu example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='404-rectangle_union_ar-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
class DSU:
def __init__(self, n): self.parent=list(range(n)); self.size=[1]*n
def find(self, x):
while self.parent[x] != x:
self.parent[x] = self.parent[self.parent[x]]; x = self.parent[x]
return x
def union(self, a, b):
ra, rb = self.find(a), self.find(b)
if ra == rb: return False
if self.size[ra] < self.size[rb]: ra, rb = rb, ra
self.parent[rb] = ra; self.size[ra] += self.size[rb]; return True
def rectangle_union_area_p404(n, edges):
dsu = DSU(n); accepted=[]
for edge in edges:
if dsu.union(*edge): accepted.append(edge)
return accepted, [dsu.find(i) for i in range(n)]
def run_example(example=EXAMPLE):
return rectangle_union_area_p404(5, example['sample_input']['edges'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Rectangle union area" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Rectangle union area, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 404 curation harness: Rectangle union area
EXAMPLE_KIND = "dsu"
EXAMPLE_TITLE = "Rectangle union area"
SAMPLE = {
"values": [
29,
40,
11,
22,
33,
4,
15
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "404-rectangle_union_area"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "404-rectangle_union_area"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "404-rectangle_union_area"))
Browser JavaScript companion
// Page 404 browser-side experiment: Rectangle union area
const pageExample404 = {"values":[29,40,11,22,33,4,15],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"404-rectangle_union_area"};
function summarizePage404(sample = pageExample404) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Rectangle union area",
kind: "dsu",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage404());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Rectangle union area.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the dsu invariant described in the code comments and return a stable, inspectable result for page 404.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 405 / 561Chapter 27: Computational Geometry
Half-plane intuition
Page-local deep read
Mental model for Half-plane intuition: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 405, the goal is not memorizing half-plane intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Half-plane intuition is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Half-plane intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: precision errors. Make this risk visible in tests and in code comments.
Common pitfall: Floating-point comparisons near zero can flip orientation tests and destroy an otherwise correct algorithm.
# Page 405: Half-plane intuition
EXAMPLE = {'page': 405, 'topic': 'Half-plane intuition', 'chapter': 'Computational Geometry', 'kind': 'geometry', 'scenario': 'Run a concrete geometry miniature for Half-plane intuition.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Half-plane intuition', 'watch_for': 'The invariant that makes Half-plane intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the geometry example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='405-half_plane_intuiti-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(a, b, c):
return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def half_plane_intuition_p405(a, b, c):
value = cross(a,b,c)
return 'left' if value > 0 else 'right' if value < 0 else 'collinear'
def run_example(example=EXAMPLE):
d=example['sample_input']; return half_plane_intuition_p405(d['a'], d['b'], d['c'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Do not memorize the label "Half-plane intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit coordinates, orientation signs, degeneracy checks, and the final geometric relation.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Half-plane intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the geometry invariant described in the code comments and return a stable, inspectable result for page 405.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement half-plane intuition twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 406 / 561Chapter 27: Computational Geometry
Voronoi and Delaunay intuition
Page-local deep read
Mental model for Voronoi and Delaunay intuition: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 406, the goal is not memorizing voronoi and delaunay intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Voronoi and Delaunay intuition is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Voronoi and Delaunay intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: precision errors. Make this risk visible in tests and in code comments.
Common pitfall: Floating-point comparisons near zero can flip orientation tests and destroy an otherwise correct algorithm.
# Page 406: Voronoi and Delaunay intuition
EXAMPLE = {'page': 406, 'topic': 'Voronoi and Delaunay intuition', 'chapter': 'Computational Geometry', 'kind': 'geometry', 'scenario': 'Run a concrete geometry miniature for Voronoi and Delaunay intuition.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Voronoi and Delaunay intuition', 'watch_for': 'The invariant that makes Voronoi and Delaunay intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the geometry example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='406-voronoi_and_delaun-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(a, b, c):
return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def voronoi_and_delaunay_intuition_p406(a, b, c):
value = cross(a,b,c)
return 'left' if value > 0 else 'right' if value < 0 else 'collinear'
def run_example(example=EXAMPLE):
d=example['sample_input']; return voronoi_and_delaunay_intuition_p406(d['a'], d['b'], d['c'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Do not memorize the label "Voronoi and Delaunay intuition" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit coordinates, orientation signs, degeneracy checks, and the final geometric relation.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 406 curation harness: Voronoi and Delaunay intuition
EXAMPLE_KIND = "geometry"
EXAMPLE_TITLE = "Voronoi and Delaunay intuition"
SAMPLE = {
"points": [
[
0,
0
],
[
2,
1
],
[
1,
3
],
[
3,
3
],
[
4,
0
],
[
2,
2
]
],
"a": [
0,
0
],
"b": [
4,
0
],
"c": [
2,
3
],
"d": [
2,
-1
],
"page_marker": "406-voronoi_and_delaunay"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "points",
"marker": sample.get("page_marker", "406-voronoi_and_delaunay"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "points": []} if "points" in sample else dict(sample)),
("single-step", {**sample, "points": sample.get("points", [])[:1]} if isinstance(sample.get("points"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "406-voronoi_and_delaunay"))
Browser JavaScript companion
// Page 406 browser-side experiment: Voronoi and Delaunay intuition
const pageExample406 = {"points":[[0,0],[2,1],[1,3],[3,3],[4,0],[2,2]],"a":[0,0],"b":[4,0],"c":[2,3],"d":[2,-1],"page_marker":"406-voronoi_and_delaunay"};
function summarizePage406(sample = pageExample406) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Voronoi and Delaunay intuition",
kind: "geometry",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage406());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Voronoi and Delaunay intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the geometry invariant described in the code comments and return a stable, inspectable result for page 406.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for voronoi and delaunay intuition and explain what each one stresses.
Page 407 / 561Chapter 27: Computational Geometry
Geometry precision
Page-local deep read
Mental model for Geometry precision: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 407, the goal is not memorizing geometry precision; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Geometry precision is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Geometry precision before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: precision errors. Make this risk visible in tests and in code comments.
Common pitfall: Floating-point comparisons near zero can flip orientation tests and destroy an otherwise correct algorithm.
# Page 407: Geometry precision
EXAMPLE = {'page': 407, 'topic': 'Geometry precision', 'chapter': 'Computational Geometry', 'kind': 'geometry', 'scenario': 'Run a concrete geometry miniature for Geometry precision.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Geometry precision', 'watch_for': 'The invariant that makes Geometry precision safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the geometry example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='407-geometry_precision-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(a, b, c):
return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def geometry_precision_p407(a, b, c):
value = cross(a,b,c)
return 'left' if value > 0 else 'right' if value < 0 else 'collinear'
def run_example(example=EXAMPLE):
d=example['sample_input']; return geometry_precision_p407(d['a'], d['b'], d['c'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Do not memorize the label "Geometry precision" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit coordinates, orientation signs, degeneracy checks, and the final geometric relation.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Geometry precision.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the geometry invariant described in the code comments and return a stable, inspectable result for page 407.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for geometry precision, then point to the line of code that preserves it.
Page 408 / 561Chapter 27: Computational Geometry
Integer geometry
Page-local deep read
Mental model for Integer geometry: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 408, the goal is not memorizing integer geometry; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Integer geometry is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Integer geometry before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Integer geometry whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: precision errors. Make this risk visible in tests and in code comments.
Common pitfall: Floating-point comparisons near zero can flip orientation tests and destroy an otherwise correct algorithm.
# Page 408: Integer geometry
EXAMPLE = {'page': 408, 'topic': 'Integer geometry', 'chapter': 'Computational Geometry', 'kind': 'geometry', 'scenario': 'Run a concrete geometry miniature for Integer geometry.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Integer geometry', 'watch_for': 'The invariant that makes Integer geometry safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the geometry example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='408-integer_geometry-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(a, b, c):
return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def integer_geometry_p408(a, b, c):
value = cross(a,b,c)
return 'left' if value > 0 else 'right' if value < 0 else 'collinear'
def run_example(example=EXAMPLE):
d=example['sample_input']; return integer_geometry_p408(d['a'], d['b'], d['c'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Do not memorize the label "Integer geometry" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit coordinates, orientation signs, degeneracy checks, and the final geometric relation.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Integer geometry.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the geometry invariant described in the code comments and return a stable, inspectable result for page 408.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 409 / 561Chapter 27: Computational Geometry
Spatial indexing
Page-local deep read
Mental model for Spatial indexing: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 409, the goal is not memorizing spatial indexing; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Spatial indexing is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Spatial indexing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 409: Spatial indexing
EXAMPLE = {'page': 409, 'topic': 'Spatial indexing', 'chapter': 'Computational Geometry', 'kind': 'geometry', 'scenario': 'Run a concrete geometry miniature for Spatial indexing.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Spatial indexing', 'watch_for': 'The invariant that makes Spatial indexing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the geometry example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='409-spatial_indexing-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(a, b, c):
return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def spatial_indexing_p409(a, b, c):
value = cross(a,b,c)
return 'left' if value > 0 else 'right' if value < 0 else 'collinear'
def run_example(example=EXAMPLE):
d=example['sample_input']; return spatial_indexing_p409(d['a'], d['b'], d['c'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Do not memorize the label "Spatial indexing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit coordinates, orientation signs, degeneracy checks, and the final geometric relation.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Spatial indexing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the geometry invariant described in the code comments and return a stable, inspectable result for page 409.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 410 / 561Chapter 27: Computational Geometry
Geometry practice lab
Page-local deep read
Mental model for Geometry practice lab: Treat points as vectors and decisions as orientation tests. The important beginner move is to draw the sign of the cross product before trusting the code.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 410, the goal is not memorizing geometry practice lab; it is recognizing the representation, the safe transition, and the stopping condition inside the Computational Geometry chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Geometry practice lab is one small tool in the larger Computational Geometry toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Geometry practice lab before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 410: Geometry practice lab
EXAMPLE = {'page': 410, 'topic': 'Geometry practice lab', 'chapter': 'Computational Geometry', 'kind': 'geometry', 'scenario': 'Run a concrete geometry miniature for Geometry practice lab.', 'sample_input': {'points': [(0, 0), (2, 1), (1, 3), (3, 3), (4, 0), (2, 2)], 'a': (0, 0), 'b': (4, 0), 'c': (2, 3), 'd': (2, -1)}, 'expected_output': 'Inspectable result for Geometry practice lab', 'watch_for': 'The invariant that makes Geometry practice lab safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the geometry example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='410-geometry_practice_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def cross(a, b, c):
return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def geometry_practice_lab_p410(a, b, c):
value = cross(a,b,c)
return 'left' if value > 0 else 'right' if value < 0 else 'collinear'
def run_example(example=EXAMPLE):
d=example['sample_input']; return geometry_practice_lab_p410(d['a'], d['b'], d['c'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track points, a, b, c before reading the answer.
Common trap
Do not memorize the label "Geometry practice lab" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit coordinates, orientation signs, degeneracy checks, and the final geometric relation.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 410 curation harness: Geometry practice lab
EXAMPLE_KIND = "geometry"
EXAMPLE_TITLE = "Geometry practice lab"
SAMPLE = {
"points": [
[
0,
0
],
[
2,
1
],
[
1,
3
],
[
3,
3
],
[
4,
0
],
[
2,
2
]
],
"a": [
0,
0
],
"b": [
4,
0
],
"c": [
2,
3
],
"d": [
2,
-1
],
"page_marker": "410-geometry_practice_la"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "points",
"marker": sample.get("page_marker", "410-geometry_practice_la"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "points": []} if "points" in sample else dict(sample)),
("single-step", {**sample, "points": sample.get("points", [])[:1]} if isinstance(sample.get("points"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "410-geometry_practice_la"))
Browser JavaScript companion
// Page 410 browser-side experiment: Geometry practice lab
const pageExample410 = {"points":[[0,0],[2,1],[1,3],[3,3],[4,0],[2,2]],"a":[0,0],"b":[4,0],"c":[2,3],"d":[2,-1],"page_marker":"410-geometry_practice_la"};
function summarizePage410(sample = pageExample410) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Geometry practice lab",
kind: "geometry",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage410());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['points'], then compare it with the first line produced by Geometry practice lab.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the geometry invariant described in the code comments and return a stable, inspectable result for page 410.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement geometry practice lab twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 411 / 561Chapter 28: Randomized, Approximation, and Streaming
Randomized algorithms
Page-local deep read
Mental model for Randomized algorithms: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 411, the goal is not memorizing randomized algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Randomized algorithms is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Randomized algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 28: Randomized, Approximation, and Streaming
function reservoir(stream, k) {
const sample = [];
stream.forEach((item, i) => { if (i < k) sample.push(item); else { const j = Math.floor(Math.random() * (i + 1)); if (j < k) sample[j] = item; } });
return sample;
}
console.log(reservoir([1,2,3,4,5,6,7,8,9], 3));
Chapter anchor: This page is the Chapter 28 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Randomized, Approximation, and Streaming.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 411: Randomized algorithms
EXAMPLE = {'page': 411, 'topic': 'Randomized algorithms', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Randomized algorithms.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 411}, 'expected_output': 'Inspectable result for Randomized algorithms', 'watch_for': 'The invariant that makes Randomized algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='411-randomized_algorit-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def randomized_algorithms_p411(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return randomized_algorithms_p411(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Randomized algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Randomized algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 411.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for randomized algorithms and explain what each one stresses.
Page 412 / 561Chapter 28: Randomized, Approximation, and Streaming
Las Vegas versus Monte Carlo
Page-local deep read
Mental model for Las Vegas versus Monte Carlo: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 412, the goal is not memorizing las vegas versus monte carlo; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Las Vegas versus Monte Carlo is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Las Vegas versus Monte Carlo before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 412: Las Vegas versus Monte Carlo
EXAMPLE = {'page': 412, 'topic': 'Las Vegas versus Monte Carlo', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Las Vegas versus Monte Carlo.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 412}, 'expected_output': 'Inspectable result for Las Vegas versus Monte Carlo', 'watch_for': 'The invariant that makes Las Vegas versus Monte Carlo safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='412-las_vegas_versus_m-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def las_vegas_versus_monte_carlo_p412(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return las_vegas_versus_monte_carlo_p412(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Las Vegas versus Monte Carlo, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 412 curation harness: Las Vegas versus Monte Carlo
EXAMPLE_KIND = "random_stream"
EXAMPLE_TITLE = "Las Vegas versus Monte Carlo"
SAMPLE = {
"stream": [
5,
1,
9,
2,
6,
5,
3,
5,
8,
9
],
"k": 3,
"seed": 412,
"page_marker": "412-las_vegas_versus_mon"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "stream",
"marker": sample.get("page_marker", "412-las_vegas_versus_mon"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "stream": []} if "stream" in sample else dict(sample)),
("single-step", {**sample, "stream": sample.get("stream", [])[:1]} if isinstance(sample.get("stream"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "412-las_vegas_versus_mon"))
Browser JavaScript companion
// Page 412 browser-side experiment: Las Vegas versus Monte Carlo
const pageExample412 = {"stream":[5,1,9,2,6,5,3,5,8,9],"k":3,"seed":412,"page_marker":"412-las_vegas_versus_mon"};
function summarizePage412(sample = pageExample412) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Las Vegas versus Monte Carlo",
kind: "random_stream",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage412());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Las Vegas versus Monte Carlo.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 412.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for las vegas versus monte carlo, then point to the line of code that preserves it.
Page 413 / 561Chapter 28: Randomized, Approximation, and Streaming
Randomized quicksort
Page-local deep read
Mental model for Randomized quicksort: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 413, the goal is not memorizing randomized quicksort; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Randomized quicksort is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Randomized quicksort before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as goal-dependent time and often sublinear memory space in the common model, then revisit the bound when the input representation changes.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 413: Randomized quicksort
EXAMPLE = {'page': 413, 'topic': 'Randomized quicksort', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for Randomized quicksort.', 'sample_input': {'values': [12, 23, 34, 5, 16, 27, 38], 'records': [{'name': 'A', 'score': 12}, {'name': 'B', 'score': 23}, {'name': 'C', 'score': 34}]}, 'expected_output': 'Inspectable result for Randomized quicksort', 'watch_for': 'The invariant that makes Randomized quicksort safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='413-randomized_quickso-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def randomized_quicksort_p413(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return randomized_quicksort_p413(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "Randomized quicksort" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Randomized quicksort.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 413.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 414 / 561Chapter 28: Randomized, Approximation, and Streaming
Reservoir sampling
Page-local deep read
Mental model for Reservoir sampling: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 414, the goal is not memorizing reservoir sampling; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Reservoir sampling is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Reservoir sampling before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 414: Reservoir sampling
EXAMPLE = {'page': 414, 'topic': 'Reservoir sampling', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'reservoir', 'scenario': 'Run a concrete reservoir miniature for Reservoir sampling.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 414}, 'expected_output': 'Inspectable result for Reservoir sampling', 'watch_for': 'The invariant that makes Reservoir sampling safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the reservoir example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='414-reservoir_sampling-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def reservoir_sampling_p414(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return reservoir_sampling_p414(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Reservoir sampling, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Reservoir sampling.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the reservoir invariant described in the code comments and return a stable, inspectable result for page 414.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 415 / 561Chapter 28: Randomized, Approximation, and Streaming
Skip lists
Page-local deep read
Mental model for Skip lists: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 415, the goal is not memorizing skip lists; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Skip lists is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Skip lists before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 415: Skip lists
EXAMPLE = {'page': 415, 'topic': 'Skip lists', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'balanced_tree', 'scenario': 'Run a concrete balanced tree miniature for Skip lists.', 'sample_input': {'values': [26, 37, 8, 19, 30, 1, 12], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Skip lists', 'watch_for': 'The invariant that makes Skip lists safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the balanced tree example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='415-skip_lists-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def skip_lists_p415(sorted_values):
if not sorted_values: return None
mid = len(sorted_values)//2
return {'key': sorted_values[mid], 'left': skip_lists_p415(sorted_values[:mid]), 'right': skip_lists_p415(sorted_values[mid+1:])}
def inorder(node):
return [] if node is None else inorder(node['left']) + [node['key']] + inorder(node['right'])
def run_example(example=EXAMPLE):
vals=sorted(set(example['sample_input']['values']))
root=skip_lists_p415(vals); return inorder(root)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Skip lists" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Skip lists.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the balanced tree invariant described in the code comments and return a stable, inspectable result for page 415.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement skip lists twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 416 / 561Chapter 28: Randomized, Approximation, and Streaming
Hashing with randomness
Page-local deep read
Mental model for Hashing with randomness: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 416, the goal is not memorizing hashing with randomness; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Hashing with randomness is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Hashing with randomness before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Hashing with randomness" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Hashing with randomness, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 416 curation harness: Hashing with randomness
EXAMPLE_KIND = "hashing"
EXAMPLE_TITLE = "Hashing with randomness"
SAMPLE = {
"values": [
33,
4,
15,
26,
37,
8,
19
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "416-hashing_with_randomn"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "416-hashing_with_randomn"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "416-hashing_with_randomn"))
Browser JavaScript companion
// Page 416 browser-side experiment: Hashing with randomness
const pageExample416 = {"values":[33,4,15,26,37,8,19],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"416-hashing_with_randomn"};
function summarizePage416(sample = pageExample416) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Hashing with randomness",
kind: "hashing",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage416());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Hashing with randomness.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 416.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for hashing with randomness and explain what each one stresses.
Page 417 / 561Chapter 28: Randomized, Approximation, and Streaming
MinHash
Page-local deep read
Mental model for MinHash: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 417, the goal is not memorizing minhash; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: MinHash is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for MinHash before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "MinHash" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of MinHash, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by MinHash.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 417.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for minhash, then point to the line of code that preserves it.
Page 418 / 561Chapter 28: Randomized, Approximation, and Streaming
Bloom filters revisited
Page-local deep read
Mental model for Bloom filters revisited: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 418, the goal is not memorizing bloom filters revisited; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bloom filters revisited is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bloom filters revisited before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Bloom filters revisited whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: collisions / false positives. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Bloom filters revisited" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Bloom filters revisited, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Bloom filters revisited.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 418.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 419 / 561Chapter 28: Randomized, Approximation, and Streaming
Count-min sketch
Page-local deep read
Mental model for Count-min sketch: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 419, the goal is not memorizing count-min sketch; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Count-min sketch is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Count-min sketch before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 419: Count-min sketch
EXAMPLE = {'page': 419, 'topic': 'Count-min sketch', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'count_min', 'scenario': 'Run a concrete count min miniature for Count-min sketch.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 419}, 'expected_output': 'Inspectable result for Count-min sketch', 'watch_for': 'The invariant that makes Count-min sketch safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the count min example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='419-count_min_sketch-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def count_min_sketch_p419(stream, width=8, depth=3):
table = [[0]*width for _ in range(depth)]
for x in stream:
for row in range(depth): table[row][hash((x,row)) % width] += 1
return {x: min(table[row][hash((x,row)) % width] for row in range(depth)) for x in set(stream)}
def run_example(example=EXAMPLE):
return count_min_sketch_p419(example['sample_input']['stream'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Count-min sketch, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Count-min sketch.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the count min invariant described in the code comments and return a stable, inspectable result for page 419.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 420 / 561Chapter 28: Randomized, Approximation, and Streaming
HyperLogLog intuition
Page-local deep read
Mental model for HyperLogLog intuition: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 420, the goal is not memorizing hyperloglog intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: HyperLogLog intuition is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for HyperLogLog intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 420: HyperLogLog intuition
EXAMPLE = {'page': 420, 'topic': 'HyperLogLog intuition', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'hyperloglog', 'scenario': 'Run a concrete hyperloglog miniature for HyperLogLog intuition.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 420}, 'expected_output': 'Inspectable result for HyperLogLog intuition', 'watch_for': 'The invariant that makes HyperLogLog intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the hyperloglog example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='420-hyperloglog_intuit-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def rho(x):
bits = bin(abs(hash(x)))[2:] or '0'
return len(bits) - len(bits.rstrip('0')) + 1
def hyperloglog_intuition_p420(stream, buckets=8):
registers = [0] * buckets
for item in stream:
h = abs(hash(item)); bucket = h % buckets
registers[bucket] = max(registers[bucket], rho((item, bucket)))
harmonic = sum(2 ** -r for r in registers)
return round(0.7213 / (1 + 1.079/buckets) * buckets * buckets / harmonic)
def run_example(example=EXAMPLE):
return hyperloglog_intuition_p420(example['sample_input']['stream'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of HyperLogLog intuition, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by HyperLogLog intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hyperloglog invariant described in the code comments and return a stable, inspectable result for page 420.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement hyperloglog intuition twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 421 / 561Chapter 28: Randomized, Approximation, and Streaming
Approximation ratios
Page-local deep read
Mental model for Approximation ratios: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 421, the goal is not memorizing approximation ratios; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Approximation ratios is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Approximation ratios before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 421: Approximation ratios
EXAMPLE = {'page': 421, 'topic': 'Approximation ratios', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Approximation ratios.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 421}, 'expected_output': 'Inspectable result for Approximation ratios', 'watch_for': 'The invariant that makes Approximation ratios safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='421-approximation_rati-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def approximation_ratios_p421(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return approximation_ratios_p421(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Approximation ratios, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Approximation ratios.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 421.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for approximation ratios and explain what each one stresses.
Page 422 / 561Chapter 28: Randomized, Approximation, and Streaming
Vertex cover 2-approximation
Page-local deep read
Mental model for Vertex cover 2-approximation: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 422, the goal is not memorizing vertex cover 2-approximation; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Vertex cover 2-approximation is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Vertex cover 2-approximation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 422: Vertex cover 2-approximation
EXAMPLE = {'page': 422, 'topic': 'Vertex cover 2-approximation', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Vertex cover 2-approximation.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 422}, 'expected_output': 'Inspectable result for Vertex cover 2-approximation', 'watch_for': 'The invariant that makes Vertex cover 2-approximation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='422-vertex_cover_2_app-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def vertex_cover_2_approximation_p422(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return vertex_cover_2_approximation_p422(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Vertex cover 2-approximation, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Vertex cover 2-approximation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 422.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for vertex cover 2-approximation, then point to the line of code that preserves it.
Page 423 / 561Chapter 28: Randomized, Approximation, and Streaming
Set cover greedy approximation
Page-local deep read
Mental model for Set cover greedy approximation: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 423, the goal is not memorizing set cover greedy approximation; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Set cover greedy approximation is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Set cover greedy approximation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as goal-dependent time and often sublinear memory space in the common model, then revisit the bound when the input representation changes.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 423: Set cover greedy approximation
EXAMPLE = {'page': 423, 'topic': 'Set cover greedy approximation', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Set cover greedy approximation.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 423}, 'expected_output': 'Inspectable result for Set cover greedy approximation', 'watch_for': 'The invariant that makes Set cover greedy approximation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='423-set_cover_greedy_a-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def set_cover_greedy_approximation_p423(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return set_cover_greedy_approximation_p423(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Set cover greedy approximation, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Set cover greedy approximation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 423.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 424 / 561Chapter 28: Randomized, Approximation, and Streaming
Metric TSP approximation
Page-local deep read
Mental model for Metric TSP approximation: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 424, the goal is not memorizing metric tsp approximation; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Metric TSP approximation is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Metric TSP approximation before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 424: Metric TSP approximation
EXAMPLE = {'page': 424, 'topic': 'Metric TSP approximation', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Metric TSP approximation.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 424}, 'expected_output': 'Inspectable result for Metric TSP approximation', 'watch_for': 'The invariant that makes Metric TSP approximation safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='424-metric_tsp_approxi-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def metric_tsp_approximation_p424(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return metric_tsp_approximation_p424(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Metric TSP approximation, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Metric TSP approximation.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 424.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 425 / 561Chapter 28: Randomized, Approximation, and Streaming
Local search
Page-local deep read
Mental model for Local search: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 425, the goal is not memorizing local search; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Local search is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Local search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 425: Local search
EXAMPLE = {'page': 425, 'topic': 'Local search', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Local search.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 425}, 'expected_output': 'Inspectable result for Local search', 'watch_for': 'The invariant that makes Local search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='425-local_search-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def local_search_p425(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return local_search_p425(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Local search, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Local search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 425.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement local search twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 426 / 561Chapter 28: Randomized, Approximation, and Streaming
Streaming model
Page-local deep read
Mental model for Streaming model: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 426, the goal is not memorizing streaming model; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Streaming model is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Streaming model before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 426: Streaming model
EXAMPLE = {'page': 426, 'topic': 'Streaming model', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Streaming model.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 426}, 'expected_output': 'Inspectable result for Streaming model', 'watch_for': 'The invariant that makes Streaming model safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='426-streaming_model-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def streaming_model_p426(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return streaming_model_p426(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Streaming model, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Streaming model.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 426.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for streaming model and explain what each one stresses.
Page 427 / 561Chapter 28: Randomized, Approximation, and Streaming
Sliding-window streams
Page-local deep read
Mental model for Sliding-window streams: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 427, the goal is not memorizing sliding-window streams; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sliding-window streams is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sliding-window streams before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 427: Sliding-window streams
EXAMPLE = {'page': 427, 'topic': 'Sliding-window streams', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Sliding-window streams.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 427}, 'expected_output': 'Inspectable result for Sliding-window streams', 'watch_for': 'The invariant that makes Sliding-window streams safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='427-sliding_window_str-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def sliding_window_streams_p427(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return sliding_window_streams_p427(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Sliding-window streams, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Sliding-window streams.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 427.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for sliding-window streams, then point to the line of code that preserves it.
Page 428 / 561Chapter 28: Randomized, Approximation, and Streaming
Sampling error
Page-local deep read
Mental model for Sampling error: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 428, the goal is not memorizing sampling error; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Sampling error is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Sampling error before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Sampling error whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: probability assumptions. Make this risk visible in tests and in code comments.
Common pitfall: A randomized or approximate algorithm still needs a contract: success probability, error bound, and input assumptions.
# Page 428: Sampling error
EXAMPLE = {'page': 428, 'topic': 'Sampling error', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Sampling error.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 428}, 'expected_output': 'Inspectable result for Sampling error', 'watch_for': 'The invariant that makes Sampling error safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='428-sampling_error-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def sampling_error_p428(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return sampling_error_p428(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Sampling error, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Sampling error.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 428.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 429 / 561Chapter 28: Randomized, Approximation, and Streaming
Probabilistic testing
Page-local deep read
Mental model for Probabilistic testing: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 429, the goal is not memorizing probabilistic testing; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Probabilistic testing is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Probabilistic testing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 429: Probabilistic testing
EXAMPLE = {'page': 429, 'topic': 'Probabilistic testing', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for Probabilistic testing.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 429}, 'expected_output': 'Inspectable result for Probabilistic testing', 'watch_for': 'The invariant that makes Probabilistic testing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='429-probabilistic_test-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def probabilistic_testing_p429(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return probabilistic_testing_p429(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Probabilistic testing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by Probabilistic testing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 429.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 430 / 561Chapter 28: Randomized, Approximation, and Streaming
When approximate is enough
Page-local deep read
Mental model for When approximate is enough: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 430, the goal is not memorizing when approximate is enough; it is recognizing the representation, the safe transition, and the stopping condition inside the Randomized, Approximation, and Streaming chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: When approximate is enough is one small tool in the larger Randomized, Approximation, and Streaming toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for When approximate is enough before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 430: When approximate is enough
EXAMPLE = {'page': 430, 'topic': 'When approximate is enough', 'chapter': 'Randomized, Approximation, and Streaming', 'kind': 'random_stream', 'scenario': 'Run a concrete random stream miniature for When approximate is enough.', 'sample_input': {'stream': [5, 1, 9, 2, 6, 5, 3, 5, 8, 9], 'k': 3, 'seed': 430}, 'expected_output': 'Inspectable result for When approximate is enough', 'watch_for': 'The invariant that makes When approximate is enough safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the random stream example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='430-when_approximate_i-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import random
def when_approximate_is_enough_p430(stream, k, seed=0):
rng = random.Random(seed); sample = []
for i, item in enumerate(stream, 1):
if i <= k: sample.append(item)
else:
j = rng.randrange(i)
if j < k: sample[j] = item
return sample
def run_example(example=EXAMPLE):
d=example['sample_input']; return when_approximate_is_enough_p430(d['stream'], d['k'], d['seed'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track stream, k, seed before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of When approximate is enough, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 430 curation harness: When approximate is enough
EXAMPLE_KIND = "random_stream"
EXAMPLE_TITLE = "When approximate is enough"
SAMPLE = {
"stream": [
5,
1,
9,
2,
6,
5,
3,
5,
8,
9
],
"k": 3,
"seed": 430,
"page_marker": "430-when_approximate_is_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "stream",
"marker": sample.get("page_marker", "430-when_approximate_is_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "stream": []} if "stream" in sample else dict(sample)),
("single-step", {**sample, "stream": sample.get("stream", [])[:1]} if isinstance(sample.get("stream"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "430-when_approximate_is_"))
Browser JavaScript companion
// Page 430 browser-side experiment: When approximate is enough
const pageExample430 = {"stream":[5,1,9,2,6,5,3,5,8,9],"k":3,"seed":430,"page_marker":"430-when_approximate_is_"};
function summarizePage430(sample = pageExample430) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "When approximate is enough",
kind: "random_stream",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage430());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['stream'], then compare it with the first line produced by When approximate is enough.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the random stream invariant described in the code comments and return a stable, inspectable result for page 430.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement when approximate is enough twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 431 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Parallel algorithm model
Page-local deep read
Mental model for Parallel algorithm model: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 431, the goal is not memorizing parallel algorithm model; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Parallel algorithm model is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Parallel algorithm model before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
This is a chapter-level anchor example. Read it alongside the page-specific labs lower down.
def prefix_scan(values: list[int]) -> list[int]:
out = [0] * len(values)
running = 0
for i, value in enumerate(values):
running += value
out[i] = running
return out
blocks = [5, 1, 4, 2, 3]
print(prefix_scan(blocks))
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 29: Parallel, Distributed, and External-Memory Algorithms
function prefixScan(values) {
const out = []; let running = 0;
for (const x of values) { running += x; out.push(running); }
return out;
}
console.log(prefixScan([5, 1, 4, 2, 3]));
Chapter anchor: This page is the Chapter 29 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Parallel, Distributed, and External-Memory Algorithms.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 431: Parallel algorithm model
EXAMPLE = {'page': 431, 'topic': 'Parallel algorithm model', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Parallel algorithm model.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [18, 29, 40, 11, 22, 33, 4], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Parallel algorithm model', 'watch_for': 'The invariant that makes Parallel algorithm model safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='431-parallel_algorithm-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def parallel_algorithm_model_p431(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return parallel_algorithm_model_p431(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Parallel algorithm model, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Parallel algorithm model.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 431.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for parallel algorithm model and explain what each one stresses.
Page 432 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Work and span
Page-local deep read
Mental model for Work and span: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 432, the goal is not memorizing work and span; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Work and span is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Work and span before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 432: Work and span
EXAMPLE = {'page': 432, 'topic': 'Work and span', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Work and span.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [25, 36, 7, 18, 29, 40, 11], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Work and span', 'watch_for': 'The invariant that makes Work and span safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='432-work_and_span-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def work_and_span_p432(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return work_and_span_p432(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Work and span, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 432 curation harness: Work and span
EXAMPLE_KIND = "parallel"
EXAMPLE_TITLE = "Work and span"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"perform transition",
"check output"
],
"values": [
25,
36,
7,
18,
29,
40,
11
],
"sizes": [
4,
8,
16,
32
],
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "432-work_and_span"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "432-work_and_span"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "432-work_and_span"))
Browser JavaScript companion
// Page 432 browser-side experiment: Work and span
const pageExample432 = {"steps":["read input","state invariant","perform transition","check output"],"values":[25,36,7,18,29,40,11],"sizes":[4,8,16,32],"requests":["A","B","A","C","D","A"],"page_marker":"432-work_and_span"};
function summarizePage432(sample = pageExample432) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Work and span",
kind: "parallel",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage432());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Work and span.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 432.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for work and span, then point to the line of code that preserves it.
Page 433 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Parallel prefix scan
Page-local deep read
Mental model for Parallel prefix scan: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 433, the goal is not memorizing parallel prefix scan; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Parallel prefix scan is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Parallel prefix scan before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as work, span, I/O, messages time and model-dependent space in the common model, then revisit the bound when the input representation changes.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 433: Parallel prefix scan
EXAMPLE = {'page': 433, 'topic': 'Parallel prefix scan', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Parallel prefix scan.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [32, 3, 14, 25, 36, 7, 18], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Parallel prefix scan', 'watch_for': 'The invariant that makes Parallel prefix scan safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='433-parallel_prefix_sc-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def parallel_prefix_scan_p433(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return parallel_prefix_scan_p433(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Parallel prefix scan, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Parallel prefix scan.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 433.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 434 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
MapReduce patterns
Page-local deep read
Mental model for MapReduce patterns: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 434, the goal is not memorizing mapreduce patterns; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: MapReduce patterns is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for MapReduce patterns before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 434: MapReduce patterns
EXAMPLE = {'page': 434, 'topic': 'MapReduce patterns', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for MapReduce patterns.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [39, 10, 21, 32, 3, 14, 25], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for MapReduce patterns', 'watch_for': 'The invariant that makes MapReduce patterns safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='434-mapreduce_patterns-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def mapreduce_patterns_p434(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return mapreduce_patterns_p434(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of MapReduce patterns, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by MapReduce patterns.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 434.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 435 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Distributed consensus intuition
Page-local deep read
Mental model for Distributed consensus intuition: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 435, the goal is not memorizing distributed consensus intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Distributed consensus intuition is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Distributed consensus intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 435: Distributed consensus intuition
EXAMPLE = {'page': 435, 'topic': 'Distributed consensus intuition', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Distributed consensus intuition.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [6, 17, 28, 39, 10, 21, 32], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Distributed consensus intuition', 'watch_for': 'The invariant that makes Distributed consensus intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='435-distributed_consen-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def distributed_consensus_intuition_p435(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return distributed_consensus_intuition_p435(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Distributed consensus intuition, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Distributed consensus intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 435.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement distributed consensus intuition twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 436 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Leader election
Page-local deep read
Mental model for Leader election: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 436, the goal is not memorizing leader election; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Leader election is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Leader election before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 436: Leader election
EXAMPLE = {'page': 436, 'topic': 'Leader election', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Leader election.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [13, 24, 35, 6, 17, 28, 39], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Leader election', 'watch_for': 'The invariant that makes Leader election safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='436-leader_election-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def leader_election_p436(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return leader_election_p436(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Leader election, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Leader election.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 436.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for leader election and explain what each one stresses.
Page 437 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Gossip algorithms
Page-local deep read
Mental model for Gossip algorithms: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 437, the goal is not memorizing gossip algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Gossip algorithms is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Gossip algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 437: Gossip algorithms
EXAMPLE = {'page': 437, 'topic': 'Gossip algorithms', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Gossip algorithms.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [20, 31, 2, 13, 24, 35, 6], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Gossip algorithms', 'watch_for': 'The invariant that makes Gossip algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='437-gossip_algorithms-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def gossip_algorithms_p437(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return gossip_algorithms_p437(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Gossip algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Gossip algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 437.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for gossip algorithms, then point to the line of code that preserves it.
Page 438 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Bulk synchronous processing
Page-local deep read
Mental model for Bulk synchronous processing: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 438, the goal is not memorizing bulk synchronous processing; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Bulk synchronous processing is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Bulk synchronous processing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Bulk synchronous processing whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 438: Bulk synchronous processing
EXAMPLE = {'page': 438, 'topic': 'Bulk synchronous processing', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Bulk synchronous processing.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [27, 38, 9, 20, 31, 2, 13], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Bulk synchronous processing', 'watch_for': 'The invariant that makes Bulk synchronous processing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='438-bulk_synchronous_p-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def bulk_synchronous_processing_p438(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return bulk_synchronous_processing_p438(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Bulk synchronous processing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Bulk synchronous processing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 438.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 439 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
External-memory model
Page-local deep read
Mental model for External-memory model: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 439, the goal is not memorizing external-memory model; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: External-memory model is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for External-memory model before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of External-memory model, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by External-memory model.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 439.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 440 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Cache-oblivious algorithms
Page-local deep read
Mental model for Cache-oblivious algorithms: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 440, the goal is not memorizing cache-oblivious algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Cache-oblivious algorithms is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Cache-oblivious algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Cache-oblivious algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Cache-oblivious algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 440.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement cache-oblivious algorithms twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 441 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
B-tree external sorting
Page-local deep read
Mental model for B-tree external sorting: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 441, the goal is not memorizing b-tree external sorting; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: B-tree external sorting is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for B-tree external sorting before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: stability and comparator. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 441: B-tree external sorting
EXAMPLE = {'page': 441, 'topic': 'B-tree external sorting', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'sort_pattern', 'scenario': 'Run a concrete sort pattern miniature for B-tree external sorting.', 'sample_input': {'values': [8, 19, 30, 1, 12, 23, 34], 'records': [{'name': 'A', 'score': 8}, {'name': 'B', 'score': 19}, {'name': 'C', 'score': 30}]}, 'expected_output': 'Inspectable result for B-tree external sorting', 'watch_for': 'The invariant that makes B-tree external sorting safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the sort pattern example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='441-b_tree_external_so-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def b_tree_external_sorting_p441(values):
values = list(values); trace = []
for i in range(1, len(values)):
key, j = values[i], i - 1
while j >= 0 and values[j] > key:
values[j + 1] = values[j]; j -= 1
values[j + 1] = key
trace.append(values.copy())
return {'sorted': values, 'trace': trace}
def run_example(example=EXAMPLE):
return b_tree_external_sorting_p441(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, records before reading the answer.
Common trap
Do not memorize the label "B-tree external sorting" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by B-tree external sorting.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the sort pattern invariant described in the code comments and return a stable, inspectable result for page 441.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for b-tree external sorting and explain what each one stresses.
Page 442 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Parallel graph traversal
Page-local deep read
Mental model for Parallel graph traversal: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 442, the goal is not memorizing parallel graph traversal; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Parallel graph traversal is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Parallel graph traversal before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 442: Parallel graph traversal
EXAMPLE = {'page': 442, 'topic': 'Parallel graph traversal', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Parallel graph traversal.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [15, 26, 37, 8, 19, 30, 1], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Parallel graph traversal', 'watch_for': 'The invariant that makes Parallel graph traversal safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='442-parallel_graph_tra-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def parallel_graph_traversal_p442(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return parallel_graph_traversal_p442(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Parallel graph traversal, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Parallel graph traversal.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 442.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for parallel graph traversal, then point to the line of code that preserves it.
Page 443 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
GPU-friendly algorithms
Page-local deep read
Mental model for GPU-friendly algorithms: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 443, the goal is not memorizing gpu-friendly algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: GPU-friendly algorithms is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for GPU-friendly algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as work, span, I/O, messages time and model-dependent space in the common model, then revisit the bound when the input representation changes.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 443: GPU-friendly algorithms
EXAMPLE = {'page': 443, 'topic': 'GPU-friendly algorithms', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for GPU-friendly algorithms.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [22, 33, 4, 15, 26, 37, 8], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for GPU-friendly algorithms', 'watch_for': 'The invariant that makes GPU-friendly algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='443-gpu_friendly_algor-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def gpu_friendly_algorithms_p443(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return gpu_friendly_algorithms_p443(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of GPU-friendly algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by GPU-friendly algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 443.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 444 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Synchronization costs
Page-local deep read
Mental model for Synchronization costs: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 444, the goal is not memorizing synchronization costs; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Synchronization costs is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Synchronization costs before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 444: Synchronization costs
EXAMPLE = {'page': 444, 'topic': 'Synchronization costs', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Synchronization costs.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [29, 40, 11, 22, 33, 4, 15], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Synchronization costs', 'watch_for': 'The invariant that makes Synchronization costs safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='444-synchronization_co-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def synchronization_costs_p444(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return synchronization_costs_p444(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Synchronization costs, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Synchronization costs.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 444.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 445 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Load balancing
Page-local deep read
Mental model for Load balancing: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 445, the goal is not memorizing load balancing; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Load balancing is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Load balancing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 445: Load balancing
EXAMPLE = {'page': 445, 'topic': 'Load balancing', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Load balancing.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [36, 7, 18, 29, 40, 11, 22], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Load balancing', 'watch_for': 'The invariant that makes Load balancing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='445-load_balancing-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def load_balancing_p445(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return load_balancing_p445(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Load balancing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Load balancing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 445.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement load balancing twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 446 / 561Chapter 29: Parallel, Distributed, and External-Memory Algorithms
Parallel algorithm debugging
Page-local deep read
Mental model for Parallel algorithm debugging: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 446, the goal is not memorizing parallel algorithm debugging; it is recognizing the representation, the safe transition, and the stopping condition inside the Parallel, Distributed, and External-Memory Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Parallel algorithm debugging is one small tool in the larger Parallel, Distributed, and External-Memory Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Parallel algorithm debugging before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: communication bottlenecks. Make this risk visible in tests and in code comments.
Common pitfall: Parallelizing a bad sequential algorithm can preserve the bottleneck while adding coordination overhead.
# Page 446: Parallel algorithm debugging
EXAMPLE = {'page': 446, 'topic': 'Parallel algorithm debugging', 'chapter': 'Parallel, Distributed, and External-Memory Algorithms', 'kind': 'parallel', 'scenario': 'Run a concrete parallel miniature for Parallel algorithm debugging.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [3, 14, 25, 36, 7, 18, 29], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Parallel algorithm debugging', 'watch_for': 'The invariant that makes Parallel algorithm debugging safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the parallel example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='446-parallel_algorithm-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def parallel_algorithm_debugging_p446(values):
partial = list(values)
step = 1; rounds = []
while step < len(partial):
for i in range(step, len(partial)):
partial[i] += partial[i-step]
rounds.append(partial.copy()); step *= 2
return rounds[-1] if rounds else partial
def run_example(example=EXAMPLE):
return parallel_algorithm_debugging_p446(example['sample_input']['values'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Parallel algorithm debugging, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Parallel algorithm debugging.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the parallel invariant described in the code comments and return a stable, inspectable result for page 446.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for parallel algorithm debugging and explain what each one stresses.
Page 447 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
LRU and LFU caches
Page-local deep read
Mental model for LRU and LFU caches: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 447, the goal is not memorizing lru and lfu caches; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: LRU and LFU caches is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for LRU and LFU caches before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
class LRUCache {
constructor(capacity) { this.capacity = capacity; this.map = new Map(); }
get(key) { if (!this.map.has(key)) return null; const value = this.map.get(key); this.map.delete(key); this.map.set(key, value); return value; }
put(key, value) { if (this.map.has(key)) this.map.delete(key); this.map.set(key, value); if (this.map.size > this.capacity) this.map.delete(this.map.keys().next().value); }
}
const c = new LRUCache(2); c.put('A',1); c.put('B',2); c.get('A'); c.put('C',3); console.log([...c.map]);
Chapter anchor: This page is the Chapter 30 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Systems, Databases, Compression, Crypto, and AI Algorithms.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of LRU and LFU caches, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 447 curation harness: LRU and LFU caches
EXAMPLE_KIND = "lru_cache_impl"
EXAMPLE_TITLE = "LRU and LFU caches"
SAMPLE = {
"values": [
10,
21,
32,
3,
14,
25,
36
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "447-lru_and_lfu_caches"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "447-lru_and_lfu_caches"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "447-lru_and_lfu_caches"))
Browser JavaScript companion
// Page 447 browser-side experiment: LRU and LFU caches
const pageExample447 = {"values":[10,21,32,3,14,25,36],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"447-lru_and_lfu_caches"};
function summarizePage447(sample = pageExample447) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "LRU and LFU caches",
kind: "lru_cache_impl",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage447());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by LRU and LFU caches.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the lru cache impl invariant described in the code comments and return a stable, inspectable result for page 447.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for lru and lfu caches, then point to the line of code that preserves it.
Page 448 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Garbage collection tracing
Page-local deep read
Mental model for Garbage collection tracing: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 448, the goal is not memorizing garbage collection tracing; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Garbage collection tracing is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Garbage collection tracing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Look for Garbage collection tracing whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 448: Garbage collection tracing
EXAMPLE = {'page': 448, 'topic': 'Garbage collection tracing', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Garbage collection tracing.', 'sample_input': {'values': [17, 28, 39, 10, 21, 32, 3], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Garbage collection tracing', 'watch_for': 'The invariant that makes Garbage collection tracing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='448-garbage_collection-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def garbage_collection_tracing_p448(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return garbage_collection_tracing_p448(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Garbage collection tracing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Garbage collection tracing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 448.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 449 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Memory allocation free lists
Page-local deep read
Mental model for Memory allocation free lists: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 449, the goal is not memorizing memory allocation free lists; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Memory allocation free lists is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Memory allocation free lists before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Memory allocation free lists, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Memory allocation free lists.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 449.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 450 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Scheduling algorithms
Page-local deep read
Mental model for Scheduling algorithms: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 450, the goal is not memorizing scheduling algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Scheduling algorithms is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Scheduling algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 450: Scheduling algorithms
EXAMPLE = {'page': 450, 'topic': 'Scheduling algorithms', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Scheduling algorithms.', 'sample_input': {'values': [31, 2, 13, 24, 35, 6, 17], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Scheduling algorithms', 'watch_for': 'The invariant that makes Scheduling algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='450-scheduling_algorit-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def scheduling_algorithms_p450(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return scheduling_algorithms_p450(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Scheduling algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Scheduling algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 450.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement scheduling algorithms twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 451 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Rate limiting algorithms
Page-local deep read
Mental model for Rate limiting algorithms: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 451, the goal is not memorizing rate limiting algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Rate limiting algorithms is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Rate limiting algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 451: Rate limiting algorithms
EXAMPLE = {'page': 451, 'topic': 'Rate limiting algorithms', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'rate_limiter', 'scenario': 'Run a concrete rate limiter miniature for Rate limiting algorithms.', 'sample_input': {'values': [38, 9, 20, 31, 2, 13, 24], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Rate limiting algorithms', 'watch_for': 'The invariant that makes Rate limiting algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the rate limiter example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='451-rate_limiting_algo-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def rate_limiting_algorithms_p451(timestamps, window, limit):
allowed = []
for i, t in enumerate(timestamps):
count = sum(1 for x in timestamps[:i] if t - window < x <= t)
allowed.append(count < limit)
return allowed
def run_example(example=EXAMPLE):
return rate_limiting_algorithms_p451([0,1,2,4,7,8,9], 5, 3)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Rate limiting algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Rate limiting algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the rate limiter invariant described in the code comments and return a stable, inspectable result for page 451.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for rate limiting algorithms and explain what each one stresses.
Page 452 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Consistent hashing
Page-local deep read
Mental model for Consistent hashing: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 452, the goal is not memorizing consistent hashing; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Consistent hashing is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Consistent hashing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 452: Consistent hashing
EXAMPLE = {'page': 452, 'topic': 'Consistent hashing', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'consistent_hashing', 'scenario': 'Run a concrete consistent hashing miniature for Consistent hashing.', 'sample_input': {'values': [5, 16, 27, 38, 9, 20, 31], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Consistent hashing', 'watch_for': 'The invariant that makes Consistent hashing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the consistent hashing example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='452-consistent_hashing-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def consistent_hashing_p452(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return consistent_hashing_p452(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Do not memorize the label "Consistent hashing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Consistent hashing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Consistent hashing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the consistent hashing invariant described in the code comments and return a stable, inspectable result for page 452.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for consistent hashing, then point to the line of code that preserves it.
Page 453 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
B-tree indexes
Page-local deep read
Mental model for B-tree indexes: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 453, the goal is not memorizing b-tree indexes; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: B-tree indexes is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for B-tree indexes before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 453: B-tree indexes
EXAMPLE = {'page': 453, 'topic': 'B-tree indexes', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'balanced_tree', 'scenario': 'Run a concrete balanced tree miniature for B-tree indexes.', 'sample_input': {'values': [12, 23, 34, 5, 16, 27, 38], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for B-tree indexes', 'watch_for': 'The invariant that makes B-tree indexes safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the balanced tree example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='453-b_tree_indexes-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def b_tree_indexes_p453(sorted_values):
if not sorted_values: return None
mid = len(sorted_values)//2
return {'key': sorted_values[mid], 'left': b_tree_indexes_p453(sorted_values[:mid]), 'right': b_tree_indexes_p453(sorted_values[mid+1:])}
def inorder(node):
return [] if node is None else inorder(node['left']) + [node['key']] + inorder(node['right'])
def run_example(example=EXAMPLE):
vals=sorted(set(example['sample_input']['values']))
root=b_tree_indexes_p453(vals); return inorder(root)
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "B-tree indexes" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by B-tree indexes.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the balanced tree invariant described in the code comments and return a stable, inspectable result for page 453.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 454 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
LSM trees
Page-local deep read
Mental model for LSM trees: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 454, the goal is not memorizing lsm trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: LSM trees is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for LSM trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 454: LSM trees
EXAMPLE = {'page': 454, 'topic': 'LSM trees', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for LSM trees.', 'sample_input': {'values': [19, 30, 1, 12, 23, 34, 5], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for LSM trees', 'watch_for': 'The invariant that makes LSM trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='454-lsm_trees-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def lsm_trees_p454(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return lsm_trees_p454(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of LSM trees, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by LSM trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 454.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 455 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Query planning
Page-local deep read
Mental model for Query planning: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 455, the goal is not memorizing query planning; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Query planning is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Query planning before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 455: Query planning
EXAMPLE = {'page': 455, 'topic': 'Query planning', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Query planning.', 'sample_input': {'values': [26, 37, 8, 19, 30, 1, 12], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Query planning', 'watch_for': 'The invariant that makes Query planning safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='455-query_planning-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def query_planning_p455(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return query_planning_p455(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Query planning, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Query planning.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 455.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement query planning twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 456 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Join algorithms
Page-local deep read
Mental model for Join algorithms: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 456, the goal is not memorizing join algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Join algorithms is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Join algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 456: Join algorithms
EXAMPLE = {'page': 456, 'topic': 'Join algorithms', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Join algorithms.', 'sample_input': {'values': [33, 4, 15, 26, 37, 8, 19], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Join algorithms', 'watch_for': 'The invariant that makes Join algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='456-join_algorithms-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def join_algorithms_p456(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return join_algorithms_p456(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Join algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Join algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 456.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for join algorithms and explain what each one stresses.
Page 457 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Transaction scheduling
Page-local deep read
Mental model for Transaction scheduling: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 457, the goal is not memorizing transaction scheduling; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Transaction scheduling is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Transaction scheduling before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 457: Transaction scheduling
EXAMPLE = {'page': 457, 'topic': 'Transaction scheduling', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Transaction scheduling.', 'sample_input': {'values': [40, 11, 22, 33, 4, 15, 26], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Transaction scheduling', 'watch_for': 'The invariant that makes Transaction scheduling safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='457-transaction_schedu-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def transaction_scheduling_p457(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return transaction_scheduling_p457(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Transaction scheduling, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Transaction scheduling.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 457.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for transaction scheduling, then point to the line of code that preserves it.
Page 458 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Deadlock detection
Page-local deep read
Mental model for Deadlock detection: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 458, the goal is not memorizing deadlock detection; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Deadlock detection is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Deadlock detection before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Look for Deadlock detection whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 458: Deadlock detection
EXAMPLE = {'page': 458, 'topic': 'Deadlock detection', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Deadlock detection.', 'sample_input': {'values': [7, 18, 29, 40, 11, 22, 33], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Deadlock detection', 'watch_for': 'The invariant that makes Deadlock detection safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='458-deadlock_detection-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def deadlock_detection_p458(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return deadlock_detection_p458(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Deadlock detection, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Deadlock detection.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 458.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 459 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Page replacement
Page-local deep read
Mental model for Page replacement: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 459, the goal is not memorizing page replacement; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Page replacement is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Page replacement before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 459: Page replacement
EXAMPLE = {'page': 459, 'topic': 'Page replacement', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Page replacement.', 'sample_input': {'values': [14, 25, 36, 7, 18, 29, 40], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Page replacement', 'watch_for': 'The invariant that makes Page replacement safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='459-page_replacement-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def page_replacement_p459(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return page_replacement_p459(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Page replacement, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Page replacement.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 459.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 460 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Huffman coding
Page-local deep read
Mental model for Huffman coding: Treat the algorithm as making one irreversible local choice. The important beginner move is to justify why an optimal solution can be reshaped to include that choice.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 460, the goal is not memorizing huffman coding; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Huffman coding is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Huffman coding before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 460: Huffman coding
EXAMPLE = {'page': 460, 'topic': 'Huffman coding', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'huffman', 'scenario': 'Run a concrete huffman miniature for Huffman coding.', 'sample_input': {'intervals': [(0, 3), (1, 2), (3, 5), (4, 7), (5, 9)], 'weights': {'a': 5, 'b': 9, 'c': 12, 'd': 13, 'e': 16, 'f': 45}, 'jobs': [('A', 2, 100), ('B', 1, 19), ('C', 2, 27), ('D', 1, 25)]}, 'expected_output': 'Inspectable result for Huffman coding', 'watch_for': 'The invariant that makes Huffman coding safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the huffman example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='460-huffman_coding-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
import heapq
def huffman_coding_p460(weights):
heap = [(w, symbol) for symbol, w in weights.items()]
heapq.heapify(heap)
while len(heap) > 1:
w1, a = heapq.heappop(heap); w2, b = heapq.heappop(heap)
heapq.heappush(heap, (w1+w2, (a,b)))
return heap[0][1]
def run_example(example=EXAMPLE):
return huffman_coding_p460(example['sample_input']['weights'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track intervals, weights, jobs before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Huffman coding, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['intervals'], then compare it with the first line produced by Huffman coding.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the huffman invariant described in the code comments and return a stable, inspectable result for page 460.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement huffman coding twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 461 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Arithmetic coding intuition
Page-local deep read
Mental model for Arithmetic coding intuition: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 461, the goal is not memorizing arithmetic coding intuition; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Arithmetic coding intuition is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Arithmetic coding intuition before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 461: Arithmetic coding intuition
EXAMPLE = {'page': 461, 'topic': 'Arithmetic coding intuition', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Arithmetic coding intuition.', 'sample_input': {'values': [28, 39, 10, 21, 32, 3, 14], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Arithmetic coding intuition', 'watch_for': 'The invariant that makes Arithmetic coding intuition safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='461-arithmetic_coding_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def arithmetic_coding_intuition_p461(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return arithmetic_coding_intuition_p461(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Arithmetic coding intuition, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Arithmetic coding intuition.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 461.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for arithmetic coding intuition and explain what each one stresses.
Page 462 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
LZ77 and LZ78
Page-local deep read
Mental model for LZ77 and LZ78: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 462, the goal is not memorizing lz77 and lz78; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: LZ77 and LZ78 is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for LZ77 and LZ78 before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 462: LZ77 and LZ78
EXAMPLE = {'page': 462, 'topic': 'LZ77 and LZ78', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for LZ77 and LZ78.', 'sample_input': {'values': [35, 6, 17, 28, 39, 10, 21], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for LZ77 and LZ78', 'watch_for': 'The invariant that makes LZ77 and LZ78 safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='462-lz77_and_lz78-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def lz77_and_lz78_p462(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return lz77_and_lz78_p462(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of LZ77 and LZ78, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 462 curation harness: LZ77 and LZ78
EXAMPLE_KIND = "systems_ai"
EXAMPLE_TITLE = "LZ77 and LZ78"
SAMPLE = {
"values": [
35,
6,
17,
28,
39,
10,
21
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "462-lz77_and_lz78"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "462-lz77_and_lz78"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "462-lz77_and_lz78"))
Browser JavaScript companion
// Page 462 browser-side experiment: LZ77 and LZ78
const pageExample462 = {"values":[35,6,17,28,39,10,21],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"462-lz77_and_lz78"};
function summarizePage462(sample = pageExample462) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "LZ77 and LZ78",
kind: "systems_ai",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage462());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by LZ77 and LZ78.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 462.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for lz77 and lz78, then point to the line of code that preserves it.
Page 463 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Run-length encoding systems
Page-local deep read
Mental model for Run-length encoding systems: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 463, the goal is not memorizing run-length encoding systems; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Run-length encoding systems is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Run-length encoding systems before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 463: Run-length encoding systems
EXAMPLE = {'page': 463, 'topic': 'Run-length encoding systems', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'string_alg', 'scenario': 'Run a concrete string alg miniature for Run-length encoding systems.', 'sample_input': {'text': 'abracadabra', 'pattern': 'abra', 'words': ['he', 'she', 'his', 'hers']}, 'expected_output': 'Inspectable result for Run-length encoding systems', 'watch_for': 'The invariant that makes Run-length encoding systems safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the string alg example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='463-run_length_encodin-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def prefix_function(pattern):
pi = [0] * len(pattern)
for i in range(1, len(pattern)):
j = pi[i-1]
while j and pattern[i] != pattern[j]: j = pi[j-1]
if pattern[i] == pattern[j]: j += 1
pi[i] = j
return pi
def run_length_encoding_systems_p463(text, pattern):
pi, j, hits = prefix_function(pattern), 0, []
for i, ch in enumerate(text):
while j and ch != pattern[j]: j = pi[j-1]
if ch == pattern[j]: j += 1
if j == len(pattern): hits.append(i-j+1); j = pi[j-1]
return hits
def run_example(example=EXAMPLE):
d=example['sample_input']; return run_length_encoding_systems_p463(d['text'], d['pattern'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track text, pattern, words before reading the answer.
Common trap
Do not memorize the label "Run-length encoding systems" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 463 curation harness: Run-length encoding systems
EXAMPLE_KIND = "string_alg"
EXAMPLE_TITLE = "Run-length encoding systems"
SAMPLE = {
"text": "abracadabra",
"pattern": "abra",
"words": [
"he",
"she",
"his",
"hers"
],
"page_marker": "463-run_length_encoding_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "text",
"marker": sample.get("page_marker", "463-run_length_encoding_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "text": []} if "text" in sample else dict(sample)),
("single-step", {**sample, "text": sample.get("text", [])[:1]} if isinstance(sample.get("text"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "463-run_length_encoding_"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['text'], then compare it with the first line produced by Run-length encoding systems.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the string alg invariant described in the code comments and return a stable, inspectable result for page 463.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 464 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Checksum algorithms
Page-local deep read
Mental model for Checksum algorithms: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 464, the goal is not memorizing checksum algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Checksum algorithms is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Checksum algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 464: Checksum algorithms
EXAMPLE = {'page': 464, 'topic': 'Checksum algorithms', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Checksum algorithms.', 'sample_input': {'values': [9, 20, 31, 2, 13, 24, 35], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Checksum algorithms', 'watch_for': 'The invariant that makes Checksum algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='464-checksum_algorithm-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def checksum_algorithms_p464(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return checksum_algorithms_p464(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Checksum algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Checksum algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 464.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 465 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Error-correcting codes
Page-local deep read
Mental model for Error-correcting codes: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 465, the goal is not memorizing error-correcting codes; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Error-correcting codes is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Error-correcting codes before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 465: Error-correcting codes
EXAMPLE = {'page': 465, 'topic': 'Error-correcting codes', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Error-correcting codes.', 'sample_input': {'values': [16, 27, 38, 9, 20, 31, 2], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Error-correcting codes', 'watch_for': 'The invariant that makes Error-correcting codes safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='465-error_correcting_c-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def error_correcting_codes_p465(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return error_correcting_codes_p465(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Error-correcting codes, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Error-correcting codes.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 465.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement error-correcting codes twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 466 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Public-key cryptography model
Page-local deep read
Mental model for Public-key cryptography model: Treat the input as vertices plus relationships. The important beginner move is to name which vertices are already settled, which are merely discovered, and which edge is responsible for each state change.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 466, the goal is not memorizing public-key cryptography model; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Public-key cryptography model is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Public-key cryptography model before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 466: Public-key cryptography model
EXAMPLE = {'page': 466, 'topic': 'Public-key cryptography model', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Public-key cryptography model.', 'sample_input': {'values': [23, 34, 5, 16, 27, 38, 9], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Public-key cryptography model', 'watch_for': 'The invariant that makes Public-key cryptography model safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='466-public_key_cryptog-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def public_key_cryptography_model_p466(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return public_key_cryptography_model_p466(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Public-key cryptography model, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Public-key cryptography model.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 466.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for public-key cryptography model and explain what each one stresses.
Page 467 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
RSA algorithm outline
Page-local deep read
Mental model for RSA algorithm outline: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 467, the goal is not memorizing rsa algorithm outline; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: RSA algorithm outline is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for RSA algorithm outline before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 467: RSA algorithm outline
EXAMPLE = {'page': 467, 'topic': 'RSA algorithm outline', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for RSA algorithm outline.', 'sample_input': {'values': [30, 1, 12, 23, 34, 5, 16], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for RSA algorithm outline', 'watch_for': 'The invariant that makes RSA algorithm outline safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='467-rsa_algorithm_outl-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def rsa_algorithm_outline_p467(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return rsa_algorithm_outline_p467(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of RSA algorithm outline, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by RSA algorithm outline.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 467.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for rsa algorithm outline, then point to the line of code that preserves it.
Page 468 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Diffie-Hellman key exchange
Page-local deep read
Mental model for Diffie-Hellman key exchange: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 468, the goal is not memorizing diffie-hellman key exchange; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Diffie-Hellman key exchange is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Diffie-Hellman key exchange before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Look for Diffie-Hellman key exchange whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 468: Diffie-Hellman key exchange
EXAMPLE = {'page': 468, 'topic': 'Diffie-Hellman key exchange', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Diffie-Hellman key exchange.', 'sample_input': {'values': [37, 8, 19, 30, 1, 12, 23], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Diffie-Hellman key exchange', 'watch_for': 'The invariant that makes Diffie-Hellman key exchange safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='468-diffie_hellman_key-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def diffie_hellman_key_exchange_p468(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return diffie_hellman_key_exchange_p468(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Diffie-Hellman key exchange, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Diffie-Hellman key exchange.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 468.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 469 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Hash functions in security
Page-local deep read
Mental model for Hash functions in security: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 469, the goal is not memorizing hash functions in security; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Hash functions in security is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Hash functions in security before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Hash functions in security" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Hash functions in security, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 469 curation harness: Hash functions in security
EXAMPLE_KIND = "hashing"
EXAMPLE_TITLE = "Hash functions in security"
SAMPLE = {
"values": [
4,
15,
26,
37,
8,
19,
30
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "469-hash_functions_in_se"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "469-hash_functions_in_se"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "469-hash_functions_in_se"))
Browser JavaScript companion
// Page 469 browser-side experiment: Hash functions in security
const pageExample469 = {"values":[4,15,26,37,8,19,30],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"469-hash_functions_in_se"};
function summarizePage469(sample = pageExample469) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Hash functions in security",
kind: "hashing",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage469());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Hash functions in security.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 469.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 470 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Merkle trees
Page-local deep read
Mental model for Merkle trees: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 470, the goal is not memorizing merkle trees; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Merkle trees is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Merkle trees before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 470: Merkle trees
EXAMPLE = {'page': 470, 'topic': 'Merkle trees', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Merkle trees.', 'sample_input': {'values': [11, 22, 33, 4, 15, 26, 37], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Merkle trees', 'watch_for': 'The invariant that makes Merkle trees safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='470-merkle_trees-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def merkle_trees_p470(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return merkle_trees_p470(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Merkle trees, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Merkle trees.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 470.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement merkle trees twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 471 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Digital signatures
Page-local deep read
Mental model for Digital signatures: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 471, the goal is not memorizing digital signatures; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Digital signatures is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Digital signatures before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 471: Digital signatures
EXAMPLE = {'page': 471, 'topic': 'Digital signatures', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Digital signatures.', 'sample_input': {'values': [18, 29, 40, 11, 22, 33, 4], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Digital signatures', 'watch_for': 'The invariant that makes Digital signatures safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='471-digital_signatures-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def digital_signatures_p471(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return digital_signatures_p471(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Digital signatures, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Digital signatures.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 471.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for digital signatures and explain what each one stresses.
Page 472 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Secure comparison caveats
Page-local deep read
Mental model for Secure comparison caveats: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 472, the goal is not memorizing secure comparison caveats; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Secure comparison caveats is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Secure comparison caveats before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 472: Secure comparison caveats
EXAMPLE = {'page': 472, 'topic': 'Secure comparison caveats', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Secure comparison caveats.', 'sample_input': {'values': [25, 36, 7, 18, 29, 40, 11], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Secure comparison caveats', 'watch_for': 'The invariant that makes Secure comparison caveats safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='472-secure_comparison_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def secure_comparison_caveats_p472(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return secure_comparison_caveats_p472(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Secure comparison caveats, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Secure comparison caveats.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 472.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for secure comparison caveats, then point to the line of code that preserves it.
Page 473 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
A* in AI planning
Page-local deep read
Mental model for A* in AI planning: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 473, the goal is not memorizing a* in ai planning; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: A* in AI planning is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for A* in AI planning before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 473: A* in AI planning
EXAMPLE = {'page': 473, 'topic': 'A* in AI planning', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for A* in AI planning.', 'sample_input': {'values': [32, 3, 14, 25, 36, 7, 18], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for A* in AI planning', 'watch_for': 'The invariant that makes A* in AI planning safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='473-a_in_ai_planning-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def a_in_ai_planning_p473(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return a_in_ai_planning_p473(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of A* in AI planning, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 473 curation harness: A* in AI planning
EXAMPLE_KIND = "systems_ai"
EXAMPLE_TITLE = "A* in AI planning"
SAMPLE = {
"values": [
32,
3,
14,
25,
36,
7,
18
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "473-a_in_ai_planning"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "473-a_in_ai_planning"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "473-a_in_ai_planning"))
Browser JavaScript companion
// Page 473 browser-side experiment: A* in AI planning
const pageExample473 = {"values":[32,3,14,25,36,7,18],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"473-a_in_ai_planning"};
function summarizePage473(sample = pageExample473) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "A* in AI planning",
kind: "systems_ai",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage473());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by A* in AI planning.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 473.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 474 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Minimax
Page-local deep read
Mental model for Minimax: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 474, the goal is not memorizing minimax; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Minimax is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Minimax before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 474: Minimax
EXAMPLE = {'page': 474, 'topic': 'Minimax', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'minimax', 'scenario': 'Run a concrete minimax miniature for Minimax.', 'sample_input': {'values': [39, 10, 21, 32, 3, 14, 25], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Minimax', 'watch_for': 'The invariant that makes Minimax safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the minimax example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='474-minimax-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def minimax_p474(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return minimax_p474(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Minimax, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Minimax.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the minimax invariant described in the code comments and return a stable, inspectable result for page 474.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 475 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Alpha-beta pruning revisited
Page-local deep read
Mental model for Alpha-beta pruning revisited: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 475, the goal is not memorizing alpha-beta pruning revisited; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Alpha-beta pruning revisited is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Alpha-beta pruning revisited before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 475: Alpha-beta pruning revisited
EXAMPLE = {'page': 475, 'topic': 'Alpha-beta pruning revisited', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'prune_search', 'scenario': 'Run a concrete prune search miniature for Alpha-beta pruning revisited.', 'sample_input': {'values': [6, 17, 28, 39, 10, 21, 32], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Alpha-beta pruning revisited', 'watch_for': 'The invariant that makes Alpha-beta pruning revisited safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the prune search example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='475-alpha_beta_pruning-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def alpha_beta_pruning_revisited_p475(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return alpha_beta_pruning_revisited_p475(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Do not memorize the label "Alpha-beta pruning revisited" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Alpha-beta pruning revisited.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the prune search invariant described in the code comments and return a stable, inspectable result for page 475.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement alpha-beta pruning revisited twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 476 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Monte Carlo tree search
Page-local deep read
Mental model for Monte Carlo tree search: Treat every node as the root of a smaller problem. The important beginner move is to define the result returned by one subtree before combining children.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 476, the goal is not memorizing monte carlo tree search; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Monte Carlo tree search is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Monte Carlo tree search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 476: Monte Carlo tree search
EXAMPLE = {'page': 476, 'topic': 'Monte Carlo tree search', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'mcts', 'scenario': 'Run a concrete mcts miniature for Monte Carlo tree search.', 'sample_input': {'values': [13, 24, 35, 6, 17, 28, 39], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Monte Carlo tree search', 'watch_for': 'The invariant that makes Monte Carlo tree search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the mcts example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='476-monte_carlo_tree_s-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def monte_carlo_tree_search_p476(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return monte_carlo_tree_search_p476(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Monte Carlo tree search, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 476 curation harness: Monte Carlo tree search
EXAMPLE_KIND = "mcts"
EXAMPLE_TITLE = "Monte Carlo tree search"
SAMPLE = {
"values": [
13,
24,
35,
6,
17,
28,
39
],
"steps": [
"read",
"update",
"verify"
],
"page_marker": "476-monte_carlo_tree_sea"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "476-monte_carlo_tree_sea"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "476-monte_carlo_tree_sea"))
Browser JavaScript companion
// Page 476 browser-side experiment: Monte Carlo tree search
const pageExample476 = {"values":[13,24,35,6,17,28,39],"steps":["read","update","verify"],"page_marker":"476-monte_carlo_tree_sea"};
function summarizePage476(sample = pageExample476) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Monte Carlo tree search",
kind: "mcts",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage476());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Monte Carlo tree search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the mcts invariant described in the code comments and return a stable, inspectable result for page 476.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for monte carlo tree search and explain what each one stresses.
Page 477 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Gradient descent
Page-local deep read
Mental model for Gradient descent: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 477, the goal is not memorizing gradient descent; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Gradient descent is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Gradient descent before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 477: Gradient descent
EXAMPLE = {'page': 477, 'topic': 'Gradient descent', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'gradient_descent', 'scenario': 'Run a concrete gradient descent miniature for Gradient descent.', 'sample_input': {'values': [20, 31, 2, 13, 24, 35, 6], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Gradient descent', 'watch_for': 'The invariant that makes Gradient descent safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the gradient descent example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='477-gradient_descent-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def loss_grad(x): return 2 * (x - 3)
def gradient_descent_p477(start=0.0, lr=0.2, steps=10):
x = start; trace = []
for _ in range(steps):
x -= lr * loss_grad(x); trace.append(round(x, 4))
return trace
def run_example(example=EXAMPLE):
return gradient_descent_p477()
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Gradient descent, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Gradient descent.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the gradient descent invariant described in the code comments and return a stable, inspectable result for page 477.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for gradient descent, then point to the line of code that preserves it.
Page 478 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Dynamic programming in reinforcement learning
Page-local deep read
Mental model for Dynamic programming in reinforcement learning: Treat the problem as a table of smaller questions. The important beginner move is to state exactly what one cell means before writing the transition.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 478, the goal is not memorizing dynamic programming in reinforcement learning; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Dynamic programming in reinforcement learning is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Dynamic programming in reinforcement learning before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Look for Dynamic programming in reinforcement learning whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: state definition. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 478: Dynamic programming in reinforcement learning
EXAMPLE = {'page': 478, 'topic': 'Dynamic programming in reinforcement learning', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Dynamic programming in reinforcement learning.', 'sample_input': {'values': [27, 38, 9, 20, 31, 2, 13], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Dynamic programming in reinforcement learning', 'watch_for': 'The invariant that makes Dynamic programming in reinforcement learning safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='478-dynamic_programmin-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def dynamic_programming_in_reinforcement_learning_p478(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return dynamic_programming_in_reinforcement_learning_p478(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Dynamic programming in reinforcement learning, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 478 curation harness: Dynamic programming in reinforcement learning
EXAMPLE_KIND = "systems_ai"
EXAMPLE_TITLE = "Dynamic programming in reinforcement learning"
SAMPLE = {
"values": [
27,
38,
9,
20,
31,
2,
13
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "478-dynamic_programming_"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "478-dynamic_programming_"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "478-dynamic_programming_"))
Browser JavaScript companion
// Page 478 browser-side experiment: Dynamic programming in reinforcement learning
const pageExample478 = {"values":[27,38,9,20,31,2,13],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"478-dynamic_programming_"};
function summarizePage478(sample = pageExample478) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Dynamic programming in reinforcement learning",
kind: "systems_ai",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage478());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Dynamic programming in reinforcement learning.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 478.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 479 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Viterbi algorithm
Page-local deep read
Mental model for Viterbi algorithm: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 479, the goal is not memorizing viterbi algorithm; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Viterbi algorithm is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Viterbi algorithm before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 479: Viterbi algorithm
EXAMPLE = {'page': 479, 'topic': 'Viterbi algorithm', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'viterbi', 'scenario': 'Run a concrete viterbi miniature for Viterbi algorithm.', 'sample_input': {'values': [34, 5, 16, 27, 38, 9, 20], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for Viterbi algorithm', 'watch_for': 'The invariant that makes Viterbi algorithm safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the viterbi example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='479-viterbi_algorithm-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def viterbi_algorithm_p479(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return viterbi_algorithm_p479(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Viterbi algorithm, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Viterbi algorithm.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the viterbi invariant described in the code comments and return a stable, inspectable result for page 479.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 480 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Beam search
Page-local deep read
Mental model for Beam search: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 480, the goal is not memorizing beam search; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Beam search is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Beam search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 480: Beam search
EXAMPLE = {'page': 480, 'topic': 'Beam search', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Beam search.', 'sample_input': {'values': [1, 12, 23, 34, 5, 16, 27], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Beam search', 'watch_for': 'The invariant that makes Beam search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='480-beam_search-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def beam_search_p480(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return beam_search_p480(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Beam search, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Beam search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 480.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement beam search twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 481 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
k-means clustering
Page-local deep read
Mental model for k-means clustering: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 481, the goal is not memorizing k-means clustering; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: k-means clustering is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for k-means clustering before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 481: k-means clustering
EXAMPLE = {'page': 481, 'topic': 'k-means clustering', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'kmeans', 'scenario': 'Run a concrete kmeans miniature for k-means clustering.', 'sample_input': {'values': [8, 19, 30, 1, 12, 23, 34], 'steps': ['read', 'update', 'verify']}, 'expected_output': 'Inspectable result for k-means clustering', 'watch_for': 'The invariant that makes k-means clustering safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the kmeans example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='481-k_means_clustering-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def k_means_clustering_p481(points, centers):
clusters = {c: [] for c in centers}
for p in points:
c = min(centers, key=lambda q: (p[0]-q[0])**2 + (p[1]-q[1])**2)
clusters[c].append(p)
return {c: (sum(x for x,_ in pts)/len(pts), sum(y for _,y in pts)/len(pts)) for c, pts in clusters.items() if pts}
def run_example(example=EXAMPLE):
return k_means_clustering_p481([(0,0),(1,0),(9,9),(10,9)], [(0,0),(10,10)])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, steps before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of k-means clustering, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by k-means clustering.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the kmeans invariant described in the code comments and return a stable, inspectable result for page 481.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for k-means clustering and explain what each one stresses.
Page 482 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Nearest-neighbor search
Page-local deep read
Mental model for Nearest-neighbor search: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 482, the goal is not memorizing nearest-neighbor search; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Nearest-neighbor search is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Nearest-neighbor search before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
# Page 482: Nearest-neighbor search
EXAMPLE = {'page': 482, 'topic': 'Nearest-neighbor search', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Nearest-neighbor search.', 'sample_input': {'values': [15, 26, 37, 8, 19, 30, 1], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Nearest-neighbor search', 'watch_for': 'The invariant that makes Nearest-neighbor search safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='482-nearest_neighbor_s-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def nearest_neighbor_search_p482(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return nearest_neighbor_search_p482(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Nearest-neighbor search, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Nearest-neighbor search.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 482.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for nearest-neighbor search, then point to the line of code that preserves it.
Page 483 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Locality-sensitive hashing
Page-local deep read
Mental model for Locality-sensitive hashing: Treat the table as a mapping from keys to storage locations. The important beginner move is to make collision behavior explicit instead of assuming a perfect hash.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 483, the goal is not memorizing locality-sensitive hashing; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Locality-sensitive hashing is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Locality-sensitive hashing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Track values, items, edges, tree before reading the answer.
Common trap
Do not memorize the label "Locality-sensitive hashing" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Locality-sensitive hashing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Locality-sensitive hashing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the hashing invariant described in the code comments and return a stable, inspectable result for page 483.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 484 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Genetic algorithms
Page-local deep read
Mental model for Genetic algorithms: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 484, the goal is not memorizing genetic algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Genetic algorithms is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Genetic algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 484: Genetic algorithms
EXAMPLE = {'page': 484, 'topic': 'Genetic algorithms', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Genetic algorithms.', 'sample_input': {'values': [29, 40, 11, 22, 33, 4, 15], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Genetic algorithms', 'watch_for': 'The invariant that makes Genetic algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='484-genetic_algorithms-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def genetic_algorithms_p484(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return genetic_algorithms_p484(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Genetic algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Genetic algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 484.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 485 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Simulated annealing
Page-local deep read
Mental model for Simulated annealing: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 485, the goal is not memorizing simulated annealing; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Simulated annealing is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Simulated annealing before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 485: Simulated annealing
EXAMPLE = {'page': 485, 'topic': 'Simulated annealing', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Simulated annealing.', 'sample_input': {'values': [36, 7, 18, 29, 40, 11, 22], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Simulated annealing', 'watch_for': 'The invariant that makes Simulated annealing safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='485-simulated_annealin-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def simulated_annealing_p485(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return simulated_annealing_p485(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Simulated annealing, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Simulated annealing.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 485.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement simulated annealing twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 486 / 561Chapter 30: Systems, Databases, Compression, Crypto, and AI Algorithms
Ethical and safety notes for algorithms
Page-local deep read
Mental model for Ethical and safety notes for algorithms: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 486, the goal is not memorizing ethical and safety notes for algorithms; it is recognizing the representation, the safe transition, and the stopping condition inside the Systems, Databases, Compression, Crypto, and AI Algorithms chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Ethical and safety notes for algorithms is one small tool in the larger Systems, Databases, Compression, Crypto, and AI Algorithms toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Ethical and safety notes for algorithms before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Use these topics to connect classical algorithms with storage engines, operating systems, compression formats, security protocols, and intelligent search.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: ignoring operational constraints. Make this risk visible in tests and in code comments.
Common pitfall: A theoretically efficient algorithm may be unusable if it leaks secrets, thrashes cache, or violates consistency assumptions.
# Page 486: Ethical and safety notes for algorithms
EXAMPLE = {'page': 486, 'topic': 'Ethical and safety notes for algorithms', 'chapter': 'Systems, Databases, Compression, Crypto, and AI Algorithms', 'kind': 'systems_ai', 'scenario': 'Run a concrete systems ai miniature for Ethical and safety notes for algorithms.', 'sample_input': {'values': [3, 14, 25, 36, 7, 18, 29], 'items': ['red', 'blue', 'red', 'green', 'blue', 'red'], 'edges': [(0, 1), (1, 2), (3, 4), (2, 4)], 'tree': {'A': ['B', 'C'], 'B': ['D', 'E'], 'C': ['F']}, 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Ethical and safety notes for algorithms', 'watch_for': 'The invariant that makes Ethical and safety notes for algorithms safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the systems ai example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='486-ethical_and_safety-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
from collections import OrderedDict
def ethical_and_safety_notes_for_algorithms_p486(requests, capacity=3):
cache, events = OrderedDict(), []
for key in requests:
hit = key in cache
if hit: cache.move_to_end(key)
else:
if len(cache) == capacity: events.append(('evict', cache.popitem(last=False)[0]))
cache[key] = True
events.append(('hit' if hit else 'miss', key, list(cache)))
return events
def run_example(example=EXAMPLE):
return ethical_and_safety_notes_for_algorithms_p486(example['sample_input']['requests'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track values, items, edges, tree before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Ethical and safety notes for algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 486 curation harness: Ethical and safety notes for algorithms
EXAMPLE_KIND = "systems_ai"
EXAMPLE_TITLE = "Ethical and safety notes for algorithms"
SAMPLE = {
"values": [
3,
14,
25,
36,
7,
18,
29
],
"items": [
"red",
"blue",
"red",
"green",
"blue",
"red"
],
"edges": [
[
0,
1
],
[
1,
2
],
[
3,
4
],
[
2,
4
]
],
"tree": {
"A": [
"B",
"C"
],
"B": [
"D",
"E"
],
"C": [
"F"
]
},
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "486-ethical_and_safety_n"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "486-ethical_and_safety_n"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "486-ethical_and_safety_n"))
Browser JavaScript companion
// Page 486 browser-side experiment: Ethical and safety notes for algorithms
const pageExample486 = {"values":[3,14,25,36,7,18,29],"items":["red","blue","red","green","blue","red"],"edges":[[0,1],[1,2],[3,4],[2,4]],"tree":{"A":["B","C"],"B":["D","E"],"C":["F"]},"requests":["A","B","A","C","D","A"],"page_marker":"486-ethical_and_safety_n"};
function summarizePage486(sample = pageExample486) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Ethical and safety notes for algorithms",
kind: "systems_ai",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage486());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['values'], then compare it with the first line produced by Ethical and safety notes for algorithms.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the systems ai invariant described in the code comments and return a stable, inspectable result for page 486.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for ethical and safety notes for algorithms and explain what each one stresses.
Page 487 / 561Chapter 31: Practice Projects and Reference
Project 1: algorithm visualizer
Page-local deep read
Mental model for Project 1: algorithm visualizer: Treat the text as positions and partial matches. The important beginner move is to avoid rescanning characters that the invariant already ruled out.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 487, the goal is not memorizing project 1: algorithm visualizer; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Project 1: algorithm visualizer is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Project 1: algorithm visualizer before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A second-language version for learners who want to compare Python-style logic with browser-friendly JavaScript.
// Chapter 31: Practice Projects and Reference
function buildReviewPlan(donePages, weakTopics) {
const counts = new Map(); weakTopics.forEach(t => counts.set(t, (counts.get(t) ?? 0) + 1));
return { doneCount: donePages.length, focusTopics: [...counts].sort((a,b)=>b[1]-a[1]).slice(0,3) };
}
console.log(buildReviewPlan([1,2,3,40,79], ['graphs','dp','graphs','tries']));
Chapter anchor: This page is the Chapter 31 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Practice Projects and Reference.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: unclear scope. Make this risk visible in tests and in code comments.
Common pitfall: A project without tests and metrics becomes a demo, not a learning instrument.
# Page 487: Project 1: algorithm visualizer
EXAMPLE = {'page': 487, 'topic': 'Project 1: algorithm visualizer', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Project 1: algorithm visualizer.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [10, 21, 32, 3, 14, 25, 36], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Project 1: algorithm visualizer', 'watch_for': 'The invariant that makes Project 1: algorithm visualizer safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='487-project_1_algorith-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def project_1_algorithm_visualizer_p487(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return project_1_algorithm_visualizer_p487(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Project 1: algorithm visualizer, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Project 1: algorithm visualizer.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 487.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for project 1: algorithm visualizer, then point to the line of code that preserves it.
Page 488 / 561Chapter 31: Practice Projects and Reference
Project 2: personal search engine
Page-local deep read
Mental model for Project 2: personal search engine: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 488, the goal is not memorizing project 2: personal search engine; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Project 2: personal search engine is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Project 2: personal search engine before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Project 2: personal search engine whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: unclear scope. Make this risk visible in tests and in code comments.
Common pitfall: A project without tests and metrics becomes a demo, not a learning instrument.
# Page 488: Project 2: personal search engine
EXAMPLE = {'page': 488, 'topic': 'Project 2: personal search engine', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Project 2: personal search engine.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [17, 28, 39, 10, 21, 32, 3], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Project 2: personal search engine', 'watch_for': 'The invariant that makes Project 2: personal search engine safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='488-project_2_personal-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def project_2_personal_search_engine_p488(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return project_2_personal_search_engine_p488(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Project 2: personal search engine, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Project 2: personal search engine.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 488.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 489 / 561Chapter 31: Practice Projects and Reference
Project 3: route planner
Page-local deep read
Mental model for Project 3: route planner: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 489, the goal is not memorizing project 3: route planner; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Project 3: route planner is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Project 3: route planner before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 489: Project 3: route planner
EXAMPLE = {'page': 489, 'topic': 'Project 3: route planner', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Project 3: route planner.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [24, 35, 6, 17, 28, 39, 10], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Project 3: route planner', 'watch_for': 'The invariant that makes Project 3: route planner safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='489-project_3_route_pl-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def project_3_route_planner_p489(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return project_3_route_planner_p489(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Project 3: route planner, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Project 3: route planner.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 489.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 490 / 561Chapter 31: Practice Projects and Reference
Project 4: constraint solver
Page-local deep read
Mental model for Project 4: constraint solver: Treat the algorithm as a decision tree. The important beginner move is to separate choose, check, recurse, and undo so failed branches do not contaminate later branches.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 490, the goal is not memorizing project 4: constraint solver; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Project 4: constraint solver is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Project 4: constraint solver before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Track items, n, target, grid before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the decision tree prefix, pruning rule, undo step, and first three leaves visited.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['items'], then compare it with the first line produced by Project 4: constraint solver.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the backtracking invariant described in the code comments and return a stable, inspectable result for page 490.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement project 4: constraint solver twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 491 / 561Chapter 31: Practice Projects and Reference
Project 5: compression playground
Page-local deep read
Mental model for Project 5: compression playground: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 491, the goal is not memorizing project 5: compression playground; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Project 5: compression playground is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Project 5: compression playground before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Start with the smallest representation that preserves the invariant; extra fields should pay for themselves by reducing transition cost or simplifying proof.
Key risk: unclear scope. Make this risk visible in tests and in code comments.
Common pitfall: A project without tests and metrics becomes a demo, not a learning instrument.
# Page 491: Project 5: compression playground
EXAMPLE = {'page': 491, 'topic': 'Project 5: compression playground', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Project 5: compression playground.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [38, 9, 20, 31, 2, 13, 24], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Project 5: compression playground', 'watch_for': 'The invariant that makes Project 5: compression playground safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='491-project_5_compress-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def project_5_compression_playground_p491(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return project_5_compression_playground_p491(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Project 5: compression playground, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Project 5: compression playground.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 491.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for project 5: compression playground and explain what each one stresses.
Page 492 / 561Chapter 31: Practice Projects and Reference
Project 6: streaming dashboard
Page-local deep read
Mental model for Project 6: streaming dashboard: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 492, the goal is not memorizing project 6: streaming dashboard; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Project 6: streaming dashboard is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Project 6: streaming dashboard before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 492: Project 6: streaming dashboard
EXAMPLE = {'page': 492, 'topic': 'Project 6: streaming dashboard', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Project 6: streaming dashboard.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [5, 16, 27, 38, 9, 20, 31], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Project 6: streaming dashboard', 'watch_for': 'The invariant that makes Project 6: streaming dashboard safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='492-project_6_streamin-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def project_6_streaming_dashboard_p492(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return project_6_streaming_dashboard_p492(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Project 6: streaming dashboard, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Project 6: streaming dashboard.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 492.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for project 6: streaming dashboard, then point to the line of code that preserves it.
Page 493 / 561Chapter 31: Practice Projects and Reference
Project 7: database index simulator
Page-local deep read
Mental model for Project 7: database index simulator: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 493, the goal is not memorizing project 7: database index simulator; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Project 7: database index simulator is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Project 7: database index simulator before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Budget the cost as project-dependent time and project-dependent space in the common model, then revisit the bound when the input representation changes.
Key risk: unclear scope. Make this risk visible in tests and in code comments.
Common pitfall: A project without tests and metrics becomes a demo, not a learning instrument.
# Page 493: Project 7: database index simulator
EXAMPLE = {'page': 493, 'topic': 'Project 7: database index simulator', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Project 7: database index simulator.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [12, 23, 34, 5, 16, 27, 38], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Project 7: database index simulator', 'watch_for': 'The invariant that makes Project 7: database index simulator safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='493-project_7_database-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def project_7_database_index_simulator_p493(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return project_7_database_index_simulator_p493(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Project 7: database index simulator, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Project 7: database index simulator.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 493.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 494 / 561Chapter 31: Practice Projects and Reference
Project 8: graph analytics notebook
Page-local deep read
Mental model for Project 8: graph analytics notebook: Treat the language feature as part of the algorithm contract. The important beginner move is to read the library behavior before relying on performance or ordering.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 494, the goal is not memorizing project 8: graph analytics notebook; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Project 8: graph analytics notebook is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Project 8: graph analytics notebook before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Test the empty input, one-element input, duplicates, already-solved input, reverse input, disconnected components, and maximum-size input where relevant.
Key risk: unclear scope. Make this risk visible in tests and in code comments.
Common pitfall: A project without tests and metrics becomes a demo, not a learning instrument.
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Project 8: graph analytics notebook, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Project 8: graph analytics notebook.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 494.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 495 / 561Chapter 31: Practice Projects and Reference
Interview pattern checklist
Page-local deep read
Mental model for Interview pattern checklist: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 495, the goal is not memorizing interview pattern checklist; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Interview pattern checklist is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Interview pattern checklist before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
A proof usually follows the implementation structure: initialization establishes the invariant, each step preserves it, and termination converts it into the postcondition.
Key risk: unclear scope. Make this risk visible in tests and in code comments.
Common pitfall: A project without tests and metrics becomes a demo, not a learning instrument.
# Page 495: Interview pattern checklist
EXAMPLE = {'page': 495, 'topic': 'Interview pattern checklist', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Interview pattern checklist.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [26, 37, 8, 19, 30, 1, 12], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Interview pattern checklist', 'watch_for': 'The invariant that makes Interview pattern checklist safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='495-interview_pattern_-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def interview_pattern_checklist_p495(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return interview_pattern_checklist_p495(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Interview pattern checklist, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Interview pattern checklist.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 495.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Implement interview pattern checklist twice: a direct version and an optimized version. Generate random small inputs and compare them.
Page 496 / 561Chapter 31: Practice Projects and Reference
Complexity cheat sheet
Page-local deep read
Mental model for Complexity cheat sheet: Treat the formula or bound as a compact model of growth. The important beginner move is to connect each symbol to an input-size quantity.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 496, the goal is not memorizing complexity cheat sheet; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Complexity cheat sheet is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Complexity cheat sheet before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Log the state that defines progress, not every variable. For graph algorithms this is usually frontier/visited; for DP it is the current state and dependencies.
Key risk: unclear scope. Make this risk visible in tests and in code comments.
Common pitfall: A project without tests and metrics becomes a demo, not a learning instrument.
# Page 496: Complexity cheat sheet
EXAMPLE = {'page': 496, 'topic': 'Complexity cheat sheet', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Complexity cheat sheet.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [33, 4, 15, 26, 37, 8, 19], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Complexity cheat sheet', 'watch_for': 'The invariant that makes Complexity cheat sheet safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='496-complexity_cheat_s-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def complexity_cheat_sheet_p496(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return complexity_cheat_sheet_p496(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Complexity cheat sheet, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Complexity cheat sheet.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 496.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Create three adversarial inputs for complexity cheat sheet and explain what each one stresses.
Page 497 / 561Chapter 31: Practice Projects and Reference
Data structure selection table
Page-local deep read
Mental model for Data structure selection table: Treat the algorithm as repeatedly shrinking the unsorted region. The important beginner move is to know what portion is already ordered and whether equal keys keep their original order.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 497, the goal is not memorizing data structure selection table; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Data structure selection table is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Data structure selection table before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Optimize only after naming the bottleneck. Replacing a scan with a heap, hash table, prefix summary, or monotone structure should change a measurable line in the cost model.
Key risk: unclear scope. Make this risk visible in tests and in code comments.
Common pitfall: A project without tests and metrics becomes a demo, not a learning instrument.
# Page 497: Data structure selection table
EXAMPLE = {'page': 497, 'topic': 'Data structure selection table', 'chapter': 'Practice Projects and Reference', 'kind': 'trace', 'scenario': 'Run a concrete trace miniature for Data structure selection table.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [40, 11, 22, 33, 4, 15, 26], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Data structure selection table', 'watch_for': 'The invariant that makes Data structure selection table safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the trace example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='497-data_structure_sel-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def data_structure_selection_table_p497(steps):
state = {'representation': None, 'invariant': None, 'done': False}
trace = []
for step in steps:
if 'input' in step: state['representation'] = 'chosen from input contract'
if 'invariant' in step: state['invariant'] = 'preserved after each transition'
if 'output' in step or 'check' in step: state['done'] = True
trace.append((step, dict(state)))
return trace
def run_example(example=EXAMPLE):
return data_structure_selection_table_p497(example['sample_input']['steps'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Data structure selection table, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Data structure selection table.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the trace invariant described in the code comments and return a stable, inspectable result for page 497.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Write a loop invariant or recursive invariant for data structure selection table, then point to the line of code that preserves it.
Page 498 / 561Chapter 31: Practice Projects and Reference
Proof template reference
Page-local deep read
Mental model for Proof template reference: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 498, the goal is not memorizing proof template reference; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Proof template reference is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Proof template reference before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
Look for Proof template reference whenever data has structure: order, hierarchy, graph connectivity, repeated subproblems, locality, or constraints that rule out most candidates.
Key risk: unclear scope. Make this risk visible in tests and in code comments.
Common pitfall: A project without tests and metrics becomes a demo, not a learning instrument.
# Page 498: Proof template reference
EXAMPLE = {'page': 498, 'topic': 'Proof template reference', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Proof template reference.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [7, 18, 29, 40, 11, 22, 33], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Proof template reference', 'watch_for': 'The invariant that makes Proof template reference safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='498-proof_template_ref-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def proof_template_reference_p498(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return proof_template_reference_p498(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Proof template reference, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Proof template reference.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 498.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Measure the running time on input sizes 10, 100, 1,000, and 10,000 if feasible. Plot the growth shape.
Page 499 / 561Chapter 31: Practice Projects and Reference
Testing checklist
Page-local deep read
Mental model for Testing checklist: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 499, the goal is not memorizing testing checklist; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Testing checklist is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Testing checklist before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 499: Testing checklist
EXAMPLE = {'page': 499, 'topic': 'Testing checklist', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Testing checklist.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [14, 25, 36, 7, 18, 29, 40], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Testing checklist', 'watch_for': 'The invariant that makes Testing checklist safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='499-testing_checklist-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def testing_checklist_p499(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return testing_checklist_p499(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Testing checklist, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Data-flow question
Which part of EXAMPLE should you inspect first on this page?
Start with EXAMPLE['sample_input']['steps'], then compare it with the first line produced by Testing checklist.
2. Invariant question
What does the miniature for this page need to preserve?
It must preserve the project invariant described in the code comments and return a stable, inspectable result for page 499.
3. Experiment question
What is the smallest useful modification to try?
Change the page marker or one small field in the sample input, rerun run_example(), and identify the first changed output line.
Practice task
Change one assumption in the problem model and redesign the algorithm under the new constraint.
Page 500 / 561Chapter 31: Practice Projects and Reference
Final 30-day study plan
Page-local deep read
Mental model for Final 30-day study plan: Treat the search space as candidates that can be safely discarded. The important beginner move is to write the predicate that remains true after each step.
What to trace: Start with the smallest sample on this page and write down the first three states before touching the code. On page 500, the goal is not memorizing final 30-day study plan; it is recognizing the representation, the safe transition, and the stopping condition inside the Practice Projects and Reference chapter.
Beginner checkpoint: After running the lab, change one input field and predict whether the answer, the cost, or only the trace changes. If you cannot predict that, go to the targeted reading links below before continuing.
Plain English: Final 30-day study plan is one small tool in the larger Practice Projects and Reference toolbox. Read the page as a contract: what information is stored, what changes each step, what stays true, and what output proves the idea worked.
Name the input and output for Final 30-day study plan before looking at the code.
Run the tiny lab once, then change exactly one input value and predict the first changed line.
Read one linked explanation below, then return and explain the invariant in your own words.
# Page 500: Final 30-day study plan
EXAMPLE = {'page': 500, 'topic': 'Final 30-day study plan', 'chapter': 'Practice Projects and Reference', 'kind': 'project', 'scenario': 'Run a concrete project miniature for Final 30-day study plan.', 'sample_input': {'steps': ['read input', 'state invariant', 'perform transition', 'check output'], 'values': [21, 32, 3, 14, 25, 36, 7], 'sizes': [4, 8, 16, 32], 'requests': ['A', 'B', 'A', 'C', 'D', 'A']}, 'expected_output': 'Inspectable result for Final 30-day study plan', 'watch_for': 'The invariant that makes Final 30-day study plan safe is checked before the next transition.', 'try_next': 'Change the sample input and predict which line in the project example changes first.', 'docs': []}
SECOND_EXAMPLE = dict(EXAMPLE, sample_input=dict(EXAMPLE['sample_input'], page_marker='500-final_30_day_study-variant'))
EDGE_CASES = ['empty input', 'single item', 'duplicate-heavy input', 'boundary-size input']
def final_30_day_study_plan_p500(tasks):
plan = []
for day, task in enumerate(tasks, 1):
plan.append({'day': day, 'task': task, 'done_definition': 'working demo plus tests'})
return plan
def run_example(example=EXAMPLE):
return final_30_day_study_plan_p500(['build baseline', 'add tests', 'visualize state', 'write notes'])
def run_edge_cases():
return {'topic': EXAMPLE['topic'], 'edge_cases': EDGE_CASES, 'second_marker': SECOND_EXAMPLE['sample_input'].get('page_marker')}
Final Study Planner
Check completed chapters; your progress stays in local storage in this browser.
Manual review notes for students
What to inspect first
Track steps, values, sizes, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Final 30-day study plan, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 500 curation harness: Final 30-day study plan
EXAMPLE_KIND = "project"
EXAMPLE_TITLE = "Final 30-day study plan"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"perform transition",
"check output"
],
"values": [
21,
32,
3,
14,
25,
36,
7
],
"sizes": [
4,
8,
16,
32
],
"requests": [
"A",
"B",
"A",
"C",
"D",
"A"
],
"page_marker": "500-final_30_day_study_p"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "500-final_30_day_study_p"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "500-final_30_day_study_p"))
Browser JavaScript companion
// Page 500 browser-side experiment: Final 30-day study plan
const pageExample500 = {"steps":["read input","state invariant","perform transition","check output"],"values":[21,32,3,14,25,36,7],"sizes":[4,8,16,32],"requests":["A","B","A","C","D","A"],"page_marker":"500-final_30_day_study_p"};
function summarizePage500(sample = pageExample500) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Final 30-day study plan",
kind: "project",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage500());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
End-of-course reflection and next steps
Use this final page to choose your next loop: revisit weak chapters, implement one project, or compare your code with the linked official documentation. Do not continue by rereading only; continue by changing examples and running tests.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Absolute beginner setup: how algorithms feel is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page is the Chapter 32 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Beginner Foundations Bootcamp.
# Page 501: Absolute beginner setup: how algorithms feel
def absolute_beginner_setup_how_algorithms_feel_p501(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(absolute_beginner_setup_how_algorithms_feel_p501(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Absolute beginner setup: how algorithms feel, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 501 curation harness: Absolute beginner setup: how algorithms feel
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "Absolute beginner setup: how algorithms feel"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
16,
23,
30,
6,
13,
20,
27
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "501-trace"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "501-trace"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "501-trace"))
Browser JavaScript companion
// Page 501 browser-side experiment: Absolute beginner setup: how algorithms feel
const pageExample501 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[16,23,30,6,13,20,27],"requests":["try","predict","run","reflect"],"page_marker":"501-trace"};
function summarizePage501(sample = pageExample501) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Absolute beginner setup: how algorithms feel",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage501());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Variables, state, and tracing tables is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
# Page 502: Variables, state, and tracing tables
def variables_state_and_tracing_tables_p502(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(variables_state_and_tracing_tables_p502(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Variables, state, and tracing tables, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 502 curation harness: Variables, state, and tracing tables
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "Variables, state, and tracing tables"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
19,
26,
2,
9,
16,
23,
30
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "502-trace"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "502-trace"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "502-trace"))
Browser JavaScript companion
// Page 502 browser-side experiment: Variables, state, and tracing tables
const pageExample502 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[19,26,2,9,16,23,30],"requests":["try","predict","run","reflect"],"page_marker":"502-trace"};
function summarizePage502(sample = pageExample502) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Variables, state, and tracing tables",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage502());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Lists, arrays, and indexes by hand is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
# Page 503: Lists, arrays, and indexes by hand
def lists_arrays_and_indexes_by_hand_p503(values):
trace = []
data = list(values)
for index, value in enumerate(data):
trace.append({'index': index, 'value': value, 'prefix': data[:index+1]})
return trace
print(lists_arrays_and_indexes_by_hand_p503([7, 2, 5, 1])[:3])
Manual review notes for students
What to inspect first
Track values, target, sizes before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 503 curation harness: Lists, arrays, and indexes by hand
EXAMPLE_KIND = "array_pattern"
EXAMPLE_TITLE = "Lists, arrays, and indexes by hand"
SAMPLE = {
"values": [
22,
29,
5,
12,
19,
26,
2
],
"target": 19,
"sizes": [
4,
8,
16,
32,
64
],
"page_marker": "503-array_pattern"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "503-array_pattern"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "503-array_pattern"))
Browser JavaScript companion
// Page 503 browser-side experiment: Lists, arrays, and indexes by hand
const pageExample503 = {"values":[22,29,5,12,19,26,2],"target":19,"sizes":[4,8,16,32,64],"page_marker":"503-array_pattern"};
function summarizePage503(sample = pageExample503) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Lists, arrays, and indexes by hand",
kind: "array_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage503());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with values. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Conditions, loops, and termination is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
# Page 504: Conditions, loops, and termination
def conditions_loops_and_termination_p504(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(conditions_loops_and_termination_p504(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Conditions, loops, and termination, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 504 curation harness: Conditions, loops, and termination
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "Conditions, loops, and termination"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
25,
1,
8,
15,
22,
29,
5
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "504-trace"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "504-trace"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "504-trace"))
Browser JavaScript companion
// Page 504 browser-side experiment: Conditions, loops, and termination
const pageExample504 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[25,1,8,15,22,29,5],"requests":["try","predict","run","reflect"],"page_marker":"504-trace"};
function summarizePage504(sample = pageExample504) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Conditions, loops, and termination",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage504());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Functions, contracts, and tests is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
# Page 505: Functions, contracts, and tests
def functions_contracts_and_tests_p505(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(functions_contracts_and_tests_p505(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Functions, contracts, and tests, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 505 curation harness: Functions, contracts, and tests
EXAMPLE_KIND = "project"
EXAMPLE_TITLE = "Functions, contracts, and tests"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
28,
4,
11,
18,
25,
1,
8
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "505-project"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "505-project"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "505-project"))
Browser JavaScript companion
// Page 505 browser-side experiment: Functions, contracts, and tests
const pageExample505 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[28,4,11,18,25,1,8],"requests":["try","predict","run","reflect"],"page_marker":"505-project"};
function summarizePage505(sample = pageExample505) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Functions, contracts, and tests",
kind: "project",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage505());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Reading Python errors without panic is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
# Page 506: Reading Python errors without panic
def reading_python_errors_without_panic_p506(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(reading_python_errors_without_panic_p506(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Reading Python errors without panic, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 506 curation harness: Reading Python errors without panic
EXAMPLE_KIND = "python_tooling"
EXAMPLE_TITLE = "Reading Python errors without panic"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
31,
7,
14,
21,
28,
4,
11
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "506-python_tooling"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "506-python_tooling"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "506-python_tooling"))
Browser JavaScript companion
// Page 506 browser-side experiment: Reading Python errors without panic
const pageExample506 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[31,7,14,21,28,4,11],"requests":["try","predict","run","reflect"],"page_marker":"506-python_tooling"};
function summarizePage506(sample = pageExample506) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Reading Python errors without panic",
kind: "python_tooling",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage506());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Reading JavaScript examples in the browser is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
// Page 507: Reading JavaScript examples in the browser
function reading_javascript_examples_in_the_browserP507(values) {
const trace = [];
const copy = [...values].sort((a, b) => a - b);
for (let i = 0; i < copy.length; i++) {
trace.push({ index: i, value: copy[i], prefix: copy.slice(0, i + 1) });
}
return trace;
}
console.log(reading_javascript_examples_in_the_browserP507([7, 2, 5, 1]));
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Reading JavaScript examples in the browser, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 507 curation harness: Reading JavaScript examples in the browser
EXAMPLE_KIND = "javascript_tooling"
EXAMPLE_TITLE = "Reading JavaScript examples in the browser"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
3,
10,
17,
24,
31,
7,
14
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "507-javascript_tooling"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "507-javascript_tooling"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "507-javascript_tooling"))
Browser JavaScript companion
// Page 507 browser-side experiment: Reading JavaScript examples in the browser
const pageExample507 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[3,10,17,24,31,7,14],"requests":["try","predict","run","reflect"],"page_marker":"507-javascript_tooling"};
function summarizePage507(sample = pageExample507) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Reading JavaScript examples in the browser",
kind: "javascript_tooling",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage507());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: From story problem to input/output is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
# Page 508: From story problem to input/output
def from_story_problem_to_input_output_p508(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(from_story_problem_to_input_output_p508(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of From story problem to input/output, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 508 curation harness: From story problem to input/output
EXAMPLE_KIND = "trace"
EXAMPLE_TITLE = "From story problem to input/output"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
6,
13,
20,
27,
3,
10,
17
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "508-trace"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "508-trace"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "508-trace"))
Browser JavaScript companion
// Page 508 browser-side experiment: From story problem to input/output
const pageExample508 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[6,13,20,27,3,10,17],"requests":["try","predict","run","reflect"],"page_marker":"508-trace"};
function summarizePage508(sample = pageExample508) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "From story problem to input/output",
kind: "trace",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage508());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Drawing invariants with boxes and arrows is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
# Page 509: Drawing invariants with boxes and arrows
def drawing_invariants_with_boxes_and_arrows_p509(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(drawing_invariants_with_boxes_and_arrows_p509(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Drawing invariants with boxes and arrows, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 509 curation harness: Drawing invariants with boxes and arrows
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Drawing invariants with boxes and arrows"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
9,
16,
23,
30,
6,
13,
20
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "509-proof"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "509-proof"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "509-proof"))
Browser JavaScript companion
// Page 509 browser-side experiment: Drawing invariants with boxes and arrows
const pageExample509 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[9,16,23,30,6,13,20],"requests":["try","predict","run","reflect"],"page_marker":"509-proof"};
function summarizePage509(sample = pageExample509) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Drawing invariants with boxes and arrows",
kind: "proof",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage509());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Debugging tiny algorithms is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
# Page 510: Debugging tiny algorithms
def debugging_tiny_algorithms_p510(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(debugging_tiny_algorithms_p510(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Debugging tiny algorithms, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: How to practice without copying is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
# Page 511: How to practice without copying
def how_to_practice_without_copying_p511(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(how_to_practice_without_copying_p511(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of How to practice without copying, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 511 curation harness: How to practice without copying
EXAMPLE_KIND = "project"
EXAMPLE_TITLE = "How to practice without copying"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
15,
22,
29,
5,
12,
19,
26
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "511-project"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "511-project"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "511-project"))
Browser JavaScript companion
// Page 511 browser-side experiment: How to practice without copying
const pageExample511 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[15,22,29,5,12,19,26],"requests":["try","predict","run","reflect"],"page_marker":"511-project"};
function summarizePage511(sample = pageExample511) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "How to practice without copying",
kind: "project",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage511());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Beginner milestone project: trace visualizer is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 32. For the chapter-wide textbook implementation and custom diagram, jump to page 501.
# Page 512: Beginner milestone project: trace visualizer
def beginner_milestone_project_trace_visualizer_p512(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(beginner_milestone_project_trace_visualizer_p512(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Beginner milestone project: trace visualizer, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 513 / 561Chapter 33: Visual Algorithm Atlas
Array scan visual anatomy
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Array scan visual anatomy is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page is the Chapter 33 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Visual Algorithm Atlas.
# Page 513: Array scan visual anatomy
def array_scan_visual_anatomy_p513(values):
trace = []
data = list(values)
for index, value in enumerate(data):
trace.append({'index': index, 'value': value, 'prefix': data[:index+1]})
return trace
print(array_scan_visual_anatomy_p513([7, 2, 5, 1])[:3])
Manual review notes for students
What to inspect first
Track values, target, sizes before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with values. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 514 / 561Chapter 33: Visual Algorithm Atlas
Binary search timeline
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Binary search timeline is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 514: Binary search timeline
def binary_search_timeline_p514(values, target):
lo, hi, log = 0, len(values), []
while lo < hi:
mid = (lo + hi) // 2
log.append((lo, mid, hi, values[mid]))
if values[mid] < target:
lo = mid + 1
else:
hi = mid
return {'index': lo, 'found': lo < len(values) and values[lo] == target, 'trace': log}
print(binary_search_timeline_p514([1, 4, 6, 9, 13], 9))
Manual review notes for students
What to inspect first
Track values, target, sizes before reading the answer.
Common trap
Do not memorize the label "Binary search timeline" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with values. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 515 / 561Chapter 33: Visual Algorithm Atlas
Sorting as repeated local repairs
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Sorting as repeated local repairs is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 515: Sorting as repeated local repairs
def sorting_as_repeated_local_repairs_p515(values):
trace = []
data = list(values)
for index, value in enumerate(data):
trace.append({'index': index, 'value': value, 'prefix': data[:index+1]})
return trace
print(sorting_as_repeated_local_repairs_p515([7, 2, 5, 1])[:3])
Manual review notes for students
What to inspect first
Track values, target, sizes before reading the answer.
Common trap
Do not memorize the label "Sorting as repeated local repairs" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 515 curation harness: Sorting as repeated local repairs
EXAMPLE_KIND = "sort_pattern"
EXAMPLE_TITLE = "Sorting as repeated local repairs"
SAMPLE = {
"values": [
27,
3,
10,
17,
24,
31,
7
],
"target": 17,
"sizes": [
4,
8,
16,
32,
64
],
"page_marker": "515-sort_pattern"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "515-sort_pattern"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "515-sort_pattern"))
Browser JavaScript companion
// Page 515 browser-side experiment: Sorting as repeated local repairs
const pageExample515 = {"values":[27,3,10,17,24,31,7],"target":17,"sizes":[4,8,16,32,64],"page_marker":"515-sort_pattern"};
function summarizePage515(sample = pageExample515) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Sorting as repeated local repairs",
kind: "sort_pattern",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage515());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with values. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 516 / 561Chapter 33: Visual Algorithm Atlas
Recursion stack storyboard
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Recursion stack storyboard is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 516: Recursion stack storyboard
def recursion_stack_storyboard_p516(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(recursion_stack_storyboard_p516(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Recursion stack storyboard, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 517 / 561Chapter 33: Visual Algorithm Atlas
Queue frontier for BFS
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Queue frontier for BFS is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 517: Queue frontier for BFS
from collections import deque
def queue_frontier_for_bfs_p517(graph, start):
queue = deque([start])
seen = {start}
order = []
while queue:
node = queue.popleft()
order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt)
queue.append(nxt)
return order
sample = {'A': ['B', 'C'], 'B': ['D'], 'C': ['D'], 'D': []}
print(queue_frontier_for_bfs_p517(sample, 'A'))
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Queue frontier for BFS" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 517 curation harness: Queue frontier for BFS
EXAMPLE_KIND = "graph"
EXAMPLE_TITLE = "Queue frontier for BFS"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
]
],
"start": "A",
"goal": "F",
"page_marker": "517-graph"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "517-graph"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "517-graph"))
Browser JavaScript companion
// Page 517 browser-side experiment: Queue frontier for BFS
const pageExample517 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3]],"start":"A","goal":"F","page_marker":"517-graph"};
function summarizePage517(sample = pageExample517) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Queue frontier for BFS",
kind: "graph",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage517());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with graph. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 518 / 561Chapter 33: Visual Algorithm Atlas
DFS call-tree map
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: DFS call-tree map is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 518: DFS call-tree map
from collections import deque
def dfs_call_tree_map_p518(graph, start):
queue = deque([start])
seen = {start}
order = []
while queue:
node = queue.popleft()
order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt)
queue.append(nxt)
return order
sample = {'A': ['B', 'C'], 'B': ['D'], 'C': ['D'], 'D': []}
print(dfs_call_tree_map_p518(sample, 'A'))
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "DFS call-tree map" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with graph. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 519 / 561Chapter 33: Visual Algorithm Atlas
Heap tree and array mirror
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Heap tree and array mirror is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 519: Heap tree and array mirror
import heapq
def heap_tree_and_array_mirror_p519(values):
heap = list(values)
heapq.heapify(heap)
return [heapq.heappop(heap) for _ in range(len(heap))]
print(heap_tree_and_array_mirror_p519([8, 3, 5, 1]))
Manual review notes for students
What to inspect first
Track values, requests before reading the answer.
Common trap
Do not memorize the label "Heap tree and array mirror" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Heap tree and array mirror, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 519 curation harness: Heap tree and array mirror
EXAMPLE_KIND = "heap"
EXAMPLE_TITLE = "Heap tree and array mirror"
SAMPLE = {
"values": [
8,
15,
22,
29,
5,
12,
19
],
"requests": [
"push",
"push",
"pop",
"push",
"pop"
],
"page_marker": "519-heap"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "519-heap"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "519-heap"))
Browser JavaScript companion
// Page 519 browser-side experiment: Heap tree and array mirror
const pageExample519 = {"values":[8,15,22,29,5,12,19],"requests":["push","push","pop","push","pop"],"page_marker":"519-heap"};
function summarizePage519(sample = pageExample519) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Heap tree and array mirror",
kind: "heap",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage519());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with values. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 520 / 561Chapter 33: Visual Algorithm Atlas
Hash table collision storyboard
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Hash table collision storyboard is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
Do not memorize the label "Hash table collision storyboard" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Hash table collision storyboard, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with items. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 521 / 561Chapter 33: Visual Algorithm Atlas
DP table dependency arrows
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: DP table dependency arrows is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 521: DP table dependency arrows
from functools import cache
@cache
def dp_table_dependency_arrows_p521(n):
if n <= 1:
return 1
return dp_table_dependency_arrows_p521(n - 1) + dp_table_dependency_arrows_p521(n - 2)
print([dp_table_dependency_arrows_p521(i) for i in range(8)])
Manual review notes for students
What to inspect first
Track n, states before reading the answer.
Common trap
Do not memorize the label "DP table dependency arrows" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 521 curation harness: DP table dependency arrows
EXAMPLE_KIND = "dp"
EXAMPLE_TITLE = "DP table dependency arrows"
SAMPLE = {
"n": 8,
"states": [
"base",
"subproblem",
"transition",
"answer"
],
"page_marker": "521-dp"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "521-dp"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "521-dp"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with n. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 522 / 561Chapter 33: Visual Algorithm Atlas
Greedy exchange visual proof
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Greedy exchange visual proof is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 522: Greedy exchange visual proof
def greedy_exchange_visual_proof_p522(intervals):
chosen = []
end = float('-inf')
for start, finish in sorted(intervals, key=lambda x: x[1]):
if start >= end:
chosen.append((start, finish))
end = finish
return chosen
print(greedy_exchange_visual_proof_p522([(0, 3), (1, 2), (3, 5), (4, 7)]))
Manual review notes for students
What to inspect first
Track intervals before reading the answer.
Common trap
Do not memorize the label "Greedy exchange visual proof" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the local choice rule, exchange argument, counterexample attempt, and chosen items in order.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with intervals. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 523 / 561Chapter 33: Visual Algorithm Atlas
Shortest-path relaxation storyboard
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Shortest-path relaxation storyboard is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 523: Shortest-path relaxation storyboard
from collections import deque
def shortest_path_relaxation_storyboard_p523(graph, start):
queue = deque([start])
seen = {start}
order = []
while queue:
node = queue.popleft()
order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt)
queue.append(nxt)
return order
sample = {'A': ['B', 'C'], 'B': ['D'], 'C': ['D'], 'D': []}
print(shortest_path_relaxation_storyboard_p523(sample, 'A'))
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with graph. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 524 / 561Chapter 33: Visual Algorithm Atlas
Union-find forest compression
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Union-find forest compression is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 524: Union-find forest compression
def union_find_forest_compression_p524(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(union_find_forest_compression_p524(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Do not memorize the label "Union-find forest compression" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a short explanation of Union-find forest compression, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 525 / 561Chapter 33: Visual Algorithm Atlas
String matching alignment board
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: String matching alignment board is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 525: String matching alignment board
def string_matching_alignment_board_p525(text, pattern):
hits = []
for i in range(len(text) - len(pattern) + 1):
if text[i:i+len(pattern)] == pattern:
hits.append(i)
return hits
print(string_matching_alignment_board_p525('abracadabra', 'abra'))
Manual review notes for students
What to inspect first
Track text, pattern before reading the answer.
Common trap
Do not memorize the label "String matching alignment board" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 525 curation harness: String matching alignment board
EXAMPLE_KIND = "string"
EXAMPLE_TITLE = "String matching alignment board"
SAMPLE = {
"text": "abracadabra",
"pattern": "abra",
"page_marker": "525-string"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "text",
"marker": sample.get("page_marker", "525-string"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "text": []} if "text" in sample else dict(sample)),
("single-step", {**sample, "text": sample.get("text", [])[:1]} if isinstance(sample.get("text"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "525-string"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with text. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 526 / 561Chapter 33: Visual Algorithm Atlas
Geometry orientation compass
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Geometry orientation compass is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
Do not memorize the label "Geometry orientation compass" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit coordinates, orientation signs, degeneracy checks, and the final geometric relation.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with a. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 527 / 561Chapter 33: Visual Algorithm Atlas
Complexity curves playground
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Complexity curves playground is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 527: Complexity curves playground
def complexity_curves_playground_p527(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(complexity_curves_playground_p527(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track values, target, sizes before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Complexity curves playground, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with values. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 528 / 561Chapter 33: Visual Algorithm Atlas
Visual atlas review challenge
Boss battle: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Visual atlas review challenge is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 33. For the chapter-wide textbook implementation and custom diagram, jump to page 513.
# Page 528: Visual atlas review challenge
def visual_atlas_review_challenge_p528(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(visual_atlas_review_challenge_p528(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Visual atlas review challenge, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 529 / 561Chapter 34: Interactive Practice Tracks
Track A: first algorithms in Python
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track A: first algorithms in Python is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page is the Chapter 34 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Interactive Practice Tracks.
# Page 529: Track A: first algorithms in Python
def track_a_first_algorithms_in_python_p529(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(track_a_first_algorithms_in_python_p529(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Track A: first algorithms in Python, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 529 curation harness: Track A: first algorithms in Python
EXAMPLE_KIND = "python_tooling"
EXAMPLE_TITLE = "Track A: first algorithms in Python"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
7,
14,
21,
28,
4,
11,
18
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "529-python_tooling"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "529-python_tooling"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "529-python_tooling"))
Browser JavaScript companion
// Page 529 browser-side experiment: Track A: first algorithms in Python
const pageExample529 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[7,14,21,28,4,11,18],"requests":["try","predict","run","reflect"],"page_marker":"529-python_tooling"};
function summarizePage529(sample = pageExample529) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Track A: first algorithms in Python",
kind: "python_tooling",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage529());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 530 / 561Chapter 34: Interactive Practice Tracks
Track B: first algorithms in JavaScript
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track B: first algorithms in JavaScript is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
// Page 530: Track B: first algorithms in JavaScript
function track_b_first_algorithms_in_javascriptP530(values) {
const trace = [];
const copy = [...values].sort((a, b) => a - b);
for (let i = 0; i < copy.length; i++) {
trace.push({ index: i, value: copy[i], prefix: copy.slice(0, i + 1) });
}
return trace;
}
console.log(track_b_first_algorithms_in_javascriptP530([7, 2, 5, 1]));
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Track B: first algorithms in JavaScript, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 530 curation harness: Track B: first algorithms in JavaScript
EXAMPLE_KIND = "javascript_tooling"
EXAMPLE_TITLE = "Track B: first algorithms in JavaScript"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
10,
17,
24,
31,
7,
14,
21
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "530-javascript_tooling"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "530-javascript_tooling"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "530-javascript_tooling"))
Browser JavaScript companion
// Page 530 browser-side experiment: Track B: first algorithms in JavaScript
const pageExample530 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[10,17,24,31,7,14,21],"requests":["try","predict","run","reflect"],"page_marker":"530-javascript_tooling"};
function summarizePage530(sample = pageExample530) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Track B: first algorithms in JavaScript",
kind: "javascript_tooling",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage530());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 531 / 561Chapter 34: Interactive Practice Tracks
Track C: math confidence
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track C: math confidence is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
# Page 531: Track C: math confidence
def track_c_math_confidence_p531(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(track_c_math_confidence_p531(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track values, target, sizes before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Track C: math confidence, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 531 curation harness: Track C: math confidence
EXAMPLE_KIND = "math"
EXAMPLE_TITLE = "Track C: math confidence"
SAMPLE = {
"values": [
13,
20,
27,
3,
10,
17,
24
],
"target": 17,
"sizes": [
4,
8,
16,
32,
64
],
"page_marker": "531-math"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "531-math"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "531-math"))
Browser JavaScript companion
// Page 531 browser-side experiment: Track C: math confidence
const pageExample531 = {"values":[13,20,27,3,10,17,24],"target":17,"sizes":[4,8,16,32,64],"page_marker":"531-math"};
function summarizePage531(sample = pageExample531) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Track C: math confidence",
kind: "math",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage531());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with values. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 532 / 561Chapter 34: Interactive Practice Tracks
Track D: graphs without fear
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track D: graphs without fear is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
# Page 532: Track D: graphs without fear
from collections import deque
def track_d_graphs_without_fear_p532(graph, start):
queue = deque([start])
seen = {start}
order = []
while queue:
node = queue.popleft()
order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt)
queue.append(nxt)
return order
sample = {'A': ['B', 'C'], 'B': ['D'], 'C': ['D'], 'D': []}
print(track_d_graphs_without_fear_p532(sample, 'A'))
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Do not memorize the label "Track D: graphs without fear" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 532 curation harness: Track D: graphs without fear
EXAMPLE_KIND = "graph"
EXAMPLE_TITLE = "Track D: graphs without fear"
SAMPLE = {
"graph": {
"A": [
"B",
"C"
],
"B": [
"D"
],
"C": [
"D",
"E"
],
"D": [
"F"
],
"E": [
"F"
],
"F": []
},
"weighted_edges": [
[
"A",
"B",
2
],
[
"A",
"C",
5
],
[
"B",
"D",
1
],
[
"C",
"D",
2
],
[
"D",
"F",
3
]
],
"start": "A",
"goal": "F",
"page_marker": "532-graph"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "graph",
"marker": sample.get("page_marker", "532-graph"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "graph": []} if "graph" in sample else dict(sample)),
("single-step", {**sample, "graph": sample.get("graph", [])[:1]} if isinstance(sample.get("graph"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "532-graph"))
Browser JavaScript companion
// Page 532 browser-side experiment: Track D: graphs without fear
const pageExample532 = {"graph":{"A":["B","C"],"B":["D"],"C":["D","E"],"D":["F"],"E":["F"],"F":[]},"weighted_edges":[["A","B",2],["A","C",5],["B","D",1],["C","D",2],["D","F",3]],"start":"A","goal":"F","page_marker":"532-graph"};
function summarizePage532(sample = pageExample532) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Track D: graphs without fear",
kind: "graph",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage532());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with graph. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 533 / 561Chapter 34: Interactive Practice Tracks
Track E: dynamic programming slowly
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track E: dynamic programming slowly is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
# Page 533: Track E: dynamic programming slowly
from functools import cache
@cache
def track_e_dynamic_programming_slowly_p533(n):
if n <= 1:
return 1
return track_e_dynamic_programming_slowly_p533(n - 1) + track_e_dynamic_programming_slowly_p533(n - 2)
print([track_e_dynamic_programming_slowly_p533(i) for i in range(8)])
Manual review notes for students
What to inspect first
Track n, states before reading the answer.
Common trap
Do not memorize the label "Track E: dynamic programming slowly" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the state definition, transition formula, table fill order, base cases, and one table row by hand.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 533 curation harness: Track E: dynamic programming slowly
EXAMPLE_KIND = "dp"
EXAMPLE_TITLE = "Track E: dynamic programming slowly"
SAMPLE = {
"n": 8,
"states": [
"base",
"subproblem",
"transition",
"answer"
],
"page_marker": "533-dp"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "n",
"marker": sample.get("page_marker", "533-dp"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "n": []} if "n" in sample else dict(sample)),
("single-step", {**sample, "n": sample.get("n", [])[:1]} if isinstance(sample.get("n"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "533-dp"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with n. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 534 / 561Chapter 34: Interactive Practice Tracks
Track F: interview pattern practice
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track F: interview pattern practice is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
# Page 534: Track F: interview pattern practice
def track_f_interview_pattern_practice_p534(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(track_f_interview_pattern_practice_p534(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Track F: interview pattern practice, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 535 / 561Chapter 34: Interactive Practice Tracks
Track G: project-first learning
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track G: project-first learning is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
# Page 535: Track G: project-first learning
def track_g_project_first_learning_p535(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(track_g_project_first_learning_p535(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Track G: project-first learning, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 536 / 561Chapter 34: Interactive Practice Tracks
Track H: testing and verification
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track H: testing and verification is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
# Page 536: Track H: testing and verification
def track_h_testing_and_verification_p536(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(track_h_testing_and_verification_p536(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Track H: testing and verification, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 536 curation harness: Track H: testing and verification
EXAMPLE_KIND = "testing"
EXAMPLE_TITLE = "Track H: testing and verification"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
28,
4,
11,
18,
25,
1,
8
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "536-testing"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "536-testing"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "536-testing"))
Browser JavaScript companion
// Page 536 browser-side experiment: Track H: testing and verification
const pageExample536 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[28,4,11,18,25,1,8],"requests":["try","predict","run","reflect"],"page_marker":"536-testing"};
function summarizePage536(sample = pageExample536) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Track H: testing and verification",
kind: "testing",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage536());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 537 / 561Chapter 34: Interactive Practice Tracks
Track I: reading research-style notes
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track I: reading research-style notes is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
# Page 537: Track I: reading research-style notes
def track_i_reading_research_style_notes_p537(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(track_i_reading_research_style_notes_p537(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Track I: reading research-style notes, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 538 / 561Chapter 34: Interactive Practice Tracks
Track J: accessibility and inclusive teaching
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track J: accessibility and inclusive teaching is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
# Page 538: Track J: accessibility and inclusive teaching
def track_j_accessibility_and_inclusive_teaching_p538(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(track_j_accessibility_and_inclusive_teaching_p538(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Track J: accessibility and inclusive teaching, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 538 curation harness: Track J: accessibility and inclusive teaching
EXAMPLE_KIND = "accessibility"
EXAMPLE_TITLE = "Track J: accessibility and inclusive teaching"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
3,
10,
17,
24,
31,
7,
14
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "538-accessibility"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "538-accessibility"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "538-accessibility"))
Browser JavaScript companion
// Page 538 browser-side experiment: Track J: accessibility and inclusive teaching
const pageExample538 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[3,10,17,24,31,7,14],"requests":["try","predict","run","reflect"],"page_marker":"538-accessibility"};
function summarizePage538(sample = pageExample538) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Track J: accessibility and inclusive teaching",
kind: "accessibility",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage538());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 539 / 561Chapter 34: Interactive Practice Tracks
Track K: collaborative study groups
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Track K: collaborative study groups is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
# Page 539: Track K: collaborative study groups
def track_k_collaborative_study_groups_p539(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(track_k_collaborative_study_groups_p539(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Track K: collaborative study groups, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 539 curation harness: Track K: collaborative study groups
EXAMPLE_KIND = "project"
EXAMPLE_TITLE = "Track K: collaborative study groups"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
6,
13,
20,
27,
3,
10,
17
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "539-project"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "539-project"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "539-project"))
Browser JavaScript companion
// Page 539 browser-side experiment: Track K: collaborative study groups
const pageExample539 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[6,13,20,27,3,10,17],"requests":["try","predict","run","reflect"],"page_marker":"539-project"};
function summarizePage539(sample = pageExample539) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Track K: collaborative study groups",
kind: "project",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage539());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 540 / 561Chapter 34: Interactive Practice Tracks
Practice track checkpoint exam
Boss battle: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Practice track checkpoint exam is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 34. For the chapter-wide textbook implementation and custom diagram, jump to page 529.
# Page 540: Practice track checkpoint exam
def practice_track_checkpoint_exam_p540(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(practice_track_checkpoint_exam_p540(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Practice track checkpoint exam, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 541 / 561Chapter 35: Publishing and Maintainer Guide
GitHub Pages publishing overview
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: GitHub Pages publishing overview is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page is the Chapter 35 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Publishing and Maintainer Guide.
# Page 541: GitHub Pages publishing overview
def github_pages_publishing_overview_p541(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(github_pages_publishing_overview_p541(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of GitHub Pages publishing overview, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 542 / 561Chapter 35: Publishing and Maintainer Guide
Repository layout for a static course
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Repository layout for a static course is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 35. For the chapter-wide textbook implementation and custom diagram, jump to page 541.
# Page 542: Repository layout for a static course
def repository_layout_for_a_static_course_p542(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(repository_layout_for_a_static_course_p542(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Repository layout for a static course, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 542 curation harness: Repository layout for a static course
EXAMPLE_KIND = "publish"
EXAMPLE_TITLE = "Repository layout for a static course"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
15,
22,
29,
5,
12,
19,
26
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "542-publish"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "542-publish"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "542-publish"))
Browser JavaScript companion
// Page 542 browser-side experiment: Repository layout for a static course
const pageExample542 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[15,22,29,5,12,19,26],"requests":["try","predict","run","reflect"],"page_marker":"542-publish"};
function summarizePage542(sample = pageExample542) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Repository layout for a static course",
kind: "publish",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage542());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 543 / 561Chapter 35: Publishing and Maintainer Guide
Accessibility checklist for lessons
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Accessibility checklist for lessons is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 35. For the chapter-wide textbook implementation and custom diagram, jump to page 541.
# Page 543: Accessibility checklist for lessons
def accessibility_checklist_for_lessons_p543(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(accessibility_checklist_for_lessons_p543(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Accessibility checklist for lessons, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 543 curation harness: Accessibility checklist for lessons
EXAMPLE_KIND = "accessibility"
EXAMPLE_TITLE = "Accessibility checklist for lessons"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
18,
25,
1,
8,
15,
22,
29
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "543-accessibility"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "543-accessibility"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "543-accessibility"))
Browser JavaScript companion
// Page 543 browser-side experiment: Accessibility checklist for lessons
const pageExample543 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[18,25,1,8,15,22,29],"requests":["try","predict","run","reflect"],"page_marker":"543-accessibility"};
function summarizePage543(sample = pageExample543) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Accessibility checklist for lessons",
kind: "accessibility",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage543());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 544 / 561Chapter 35: Publishing and Maintainer Guide
Performance checklist for one-file HTML
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Performance checklist for one-file HTML is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 35. For the chapter-wide textbook implementation and custom diagram, jump to page 541.
# Page 544: Performance checklist for one-file HTML
def performance_checklist_for_one_file_html_p544(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(performance_checklist_for_one_file_html_p544(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Performance checklist for one-file HTML, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 544 curation harness: Performance checklist for one-file HTML
EXAMPLE_KIND = "publish"
EXAMPLE_TITLE = "Performance checklist for one-file HTML"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
21,
28,
4,
11,
18,
25,
1
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "544-publish"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "544-publish"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "544-publish"))
Browser JavaScript companion
// Page 544 browser-side experiment: Performance checklist for one-file HTML
const pageExample544 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[21,28,4,11,18,25,1],"requests":["try","predict","run","reflect"],"page_marker":"544-publish"};
function summarizePage544(sample = pageExample544) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Performance checklist for one-file HTML",
kind: "publish",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage544());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 545 / 561Chapter 35: Publishing and Maintainer Guide
Link citation and source hygiene
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Link citation and source hygiene is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 35. For the chapter-wide textbook implementation and custom diagram, jump to page 541.
# Page 545: Link citation and source hygiene
def link_citation_and_source_hygiene_p545(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(link_citation_and_source_hygiene_p545(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Link citation and source hygiene, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 545 curation harness: Link citation and source hygiene
EXAMPLE_KIND = "publish"
EXAMPLE_TITLE = "Link citation and source hygiene"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
24,
31,
7,
14,
21,
28,
4
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "545-publish"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "545-publish"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "545-publish"))
Browser JavaScript companion
// Page 545 browser-side experiment: Link citation and source hygiene
const pageExample545 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[24,31,7,14,21,28,4],"requests":["try","predict","run","reflect"],"page_marker":"545-publish"};
function summarizePage545(sample = pageExample545) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Link citation and source hygiene",
kind: "publish",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage545());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 546 / 561Chapter 35: Publishing and Maintainer Guide
Diagram review and visual QA
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Diagram review and visual QA is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 35. For the chapter-wide textbook implementation and custom diagram, jump to page 541.
# Page 546: Diagram review and visual QA
def diagram_review_and_visual_qa_p546(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(diagram_review_and_visual_qa_p546(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Diagram review and visual QA, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 546 curation harness: Diagram review and visual QA
EXAMPLE_KIND = "publish"
EXAMPLE_TITLE = "Diagram review and visual QA"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
27,
3,
10,
17,
24,
31,
7
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "546-publish"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "546-publish"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "546-publish"))
Browser JavaScript companion
// Page 546 browser-side experiment: Diagram review and visual QA
const pageExample546 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[27,3,10,17,24,31,7],"requests":["try","predict","run","reflect"],"page_marker":"546-publish"};
function summarizePage546(sample = pageExample546) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Diagram review and visual QA",
kind: "publish",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage546());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 547 / 561Chapter 35: Publishing and Maintainer Guide
Versioning, releases, and changelog
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Versioning, releases, and changelog is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 35. For the chapter-wide textbook implementation and custom diagram, jump to page 541.
# Page 547: Versioning, releases, and changelog
def versioning_releases_and_changelog_p547(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(versioning_releases_and_changelog_p547(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Versioning, releases, and changelog, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 547 curation harness: Versioning, releases, and changelog
EXAMPLE_KIND = "publish"
EXAMPLE_TITLE = "Versioning, releases, and changelog"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
30,
6,
13,
20,
27,
3,
10
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "547-publish"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "547-publish"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "547-publish"))
Browser JavaScript companion
// Page 547 browser-side experiment: Versioning, releases, and changelog
const pageExample547 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[30,6,13,20,27,3,10],"requests":["try","predict","run","reflect"],"page_marker":"547-publish"};
function summarizePage547(sample = pageExample547) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Versioning, releases, and changelog",
kind: "publish",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage547());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 548 / 561Chapter 35: Publishing and Maintainer Guide
Issue templates for learners
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Issue templates for learners is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 35. For the chapter-wide textbook implementation and custom diagram, jump to page 541.
# Page 548: Issue templates for learners
def issue_templates_for_learners_p548(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(issue_templates_for_learners_p548(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Issue templates for learners, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 548 curation harness: Issue templates for learners
EXAMPLE_KIND = "publish"
EXAMPLE_TITLE = "Issue templates for learners"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
2,
9,
16,
23,
30,
6,
13
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "548-publish"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "548-publish"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "548-publish"))
Browser JavaScript companion
// Page 548 browser-side experiment: Issue templates for learners
const pageExample548 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[2,9,16,23,30,6,13],"requests":["try","predict","run","reflect"],"page_marker":"548-publish"};
function summarizePage548(sample = pageExample548) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Issue templates for learners",
kind: "publish",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage548());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 549 / 561Chapter 35: Publishing and Maintainer Guide
Contributor guide for educators
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Contributor guide for educators is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 35. For the chapter-wide textbook implementation and custom diagram, jump to page 541.
# Page 549: Contributor guide for educators
def contributor_guide_for_educators_p549(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(contributor_guide_for_educators_p549(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Contributor guide for educators, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 549 curation harness: Contributor guide for educators
EXAMPLE_KIND = "publish"
EXAMPLE_TITLE = "Contributor guide for educators"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
5,
12,
19,
26,
2,
9,
16
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "549-publish"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "549-publish"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "549-publish"))
Browser JavaScript companion
// Page 549 browser-side experiment: Contributor guide for educators
const pageExample549 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[5,12,19,26,2,9,16],"requests":["try","predict","run","reflect"],"page_marker":"549-publish"};
function summarizePage549(sample = pageExample549) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Contributor guide for educators",
kind: "publish",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage549());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 550 / 561Chapter 35: Publishing and Maintainer Guide
Maintenance calendar
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Maintenance calendar is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 35. For the chapter-wide textbook implementation and custom diagram, jump to page 541.
# Page 550: Maintenance calendar
def maintenance_calendar_p550(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(maintenance_calendar_p550(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Maintenance calendar, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 551 / 561Chapter 36: Capstone Assessments and Project Rubrics
Capstone path: algorithm visualizer
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Capstone path: algorithm visualizer is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page is the Chapter 36 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of Capstone Assessments and Project Rubrics.
# Page 551: Capstone path: algorithm visualizer
def capstone_path_algorithm_visualizer_p551(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(capstone_path_algorithm_visualizer_p551(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Capstone path: algorithm visualizer, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 552 / 561Chapter 36: Capstone Assessments and Project Rubrics
Capstone path: personal search engine
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Capstone path: personal search engine is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 36. For the chapter-wide textbook implementation and custom diagram, jump to page 551.
# Page 552: Capstone path: personal search engine
def capstone_path_personal_search_engine_p552(values, target):
lo, hi, log = 0, len(values), []
while lo < hi:
mid = (lo + hi) // 2
log.append((lo, mid, hi, values[mid]))
if values[mid] < target:
lo = mid + 1
else:
hi = mid
return {'index': lo, 'found': lo < len(values) and values[lo] == target, 'trace': log}
print(capstone_path_personal_search_engine_p552([1, 4, 6, 9, 13], 9))
Manual review notes for students
What to inspect first
Track values, target, sizes before reading the answer.
Common trap
Do not memorize the label "Capstone path: personal search engine" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit a tiny input, the full trace, and the exact comparison or index decision that changes the state.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 552 curation harness: Capstone path: personal search engine
EXAMPLE_KIND = "search"
EXAMPLE_TITLE = "Capstone path: personal search engine"
SAMPLE = {
"values": [
4,
11,
14,
18,
21,
25,
28
],
"target": 18,
"sizes": [
4,
8,
16,
32,
64
],
"page_marker": "552-search"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "values",
"marker": sample.get("page_marker", "552-search"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "values": []} if "values" in sample else dict(sample)),
("single-step", {**sample, "values": sample.get("values", [])[:1]} if isinstance(sample.get("values"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "552-search"))
Browser JavaScript companion
// Page 552 browser-side experiment: Capstone path: personal search engine
const pageExample552 = {"values":[4,11,14,18,21,25,28],"target":18,"sizes":[4,8,16,32,64],"page_marker":"552-search"};
function summarizePage552(sample = pageExample552) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Capstone path: personal search engine",
kind: "search",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage552());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with values. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 553 / 561Chapter 36: Capstone Assessments and Project Rubrics
Capstone path: route planner
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Capstone path: route planner is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 36. For the chapter-wide textbook implementation and custom diagram, jump to page 551.
# Page 553: Capstone path: route planner
from collections import deque
def capstone_path_route_planner_p553(graph, start):
queue = deque([start])
seen = {start}
order = []
while queue:
node = queue.popleft()
order.append(node)
for nxt in graph.get(node, []):
if nxt not in seen:
seen.add(nxt)
queue.append(nxt)
return order
sample = {'A': ['B', 'C'], 'B': ['D'], 'C': ['D'], 'D': []}
print(capstone_path_route_planner_p553(sample, 'A'))
Manual review notes for students
What to inspect first
Track graph, weighted_edges, start, goal before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the graph representation, frontier or priority structure, visited/settled set, and final order or distances.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with graph. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 554 / 561Chapter 36: Capstone Assessments and Project Rubrics
Capstone path: constraint solver
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Capstone path: constraint solver is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 36. For the chapter-wide textbook implementation and custom diagram, jump to page 551.
# Page 554: Capstone path: constraint solver
def capstone_path_constraint_solver_p554(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(capstone_path_constraint_solver_p554(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track items, constraint before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit the decision tree prefix, pruning rule, undo step, and first three leaves visited.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with items. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 555 / 561Chapter 36: Capstone Assessments and Project Rubrics
Capstone path: compression playground
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Capstone path: compression playground is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 36. For the chapter-wide textbook implementation and custom diagram, jump to page 551.
# Page 555: Capstone path: compression playground
def capstone_path_compression_playground_p555(text, pattern):
hits = []
for i in range(len(text) - len(pattern) + 1):
if text[i:i+len(pattern)] == pattern:
hits.append(i)
return hits
print(capstone_path_compression_playground_p555('abracadabra', 'abra'))
Manual review notes for students
What to inspect first
Track text, pattern before reading the answer.
Common trap
Do not memorize the label "Capstone path: compression playground" before you can state the input, output, invariant, and one failing edge case.
Expected deliverable
Submit the text, pattern, prefix or alignment table, and mismatch recovery step.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 555 curation harness: Capstone path: compression playground
EXAMPLE_KIND = "string"
EXAMPLE_TITLE = "Capstone path: compression playground"
SAMPLE = {
"text": "abracadabra",
"pattern": "abra",
"page_marker": "555-string"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "text",
"marker": sample.get("page_marker", "555-string"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "text": []} if "text" in sample else dict(sample)),
("single-step", {**sample, "text": sample.get("text", [])[:1]} if isinstance(sample.get("text"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "555-string"))
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with text. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 556 / 561Chapter 36: Capstone Assessments and Project Rubrics
Capstone path: streaming dashboard
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Capstone path: streaming dashboard is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 36. For the chapter-wide textbook implementation and custom diagram, jump to page 551.
# Page 556: Capstone path: streaming dashboard
def capstone_path_streaming_dashboard_p556(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(capstone_path_streaming_dashboard_p556(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track values, target, sizes before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Capstone path: streaming dashboard, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with values. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 557 / 561Chapter 36: Capstone Assessments and Project Rubrics
Rubric: correctness and invariants
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Rubric: correctness and invariants is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 36. For the chapter-wide textbook implementation and custom diagram, jump to page 551.
# Page 557: Rubric: correctness and invariants
def rubric_correctness_and_invariants_p557(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(rubric_correctness_and_invariants_p557(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A proof is not a paragraph after the algorithm; it is the reason each transition is allowed.
Expected deliverable
Submit a short explanation of Rubric: correctness and invariants, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 557 curation harness: Rubric: correctness and invariants
EXAMPLE_KIND = "proof"
EXAMPLE_TITLE = "Rubric: correctness and invariants"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
29,
5,
12,
19,
26,
2,
9
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "557-proof"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "557-proof"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "557-proof"))
Browser JavaScript companion
// Page 557 browser-side experiment: Rubric: correctness and invariants
const pageExample557 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[29,5,12,19,26,2,9],"requests":["try","predict","run","reflect"],"page_marker":"557-proof"};
function summarizePage557(sample = pageExample557) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Rubric: correctness and invariants",
kind: "proof",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage557());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 558 / 561Chapter 36: Capstone Assessments and Project Rubrics
Rubric: clarity and accessibility
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Rubric: clarity and accessibility is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 36. For the chapter-wide textbook implementation and custom diagram, jump to page 551.
# Page 558: Rubric: clarity and accessibility
def rubric_clarity_and_accessibility_p558(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(rubric_clarity_and_accessibility_p558(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Rubric: clarity and accessibility, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 558 curation harness: Rubric: clarity and accessibility
EXAMPLE_KIND = "accessibility"
EXAMPLE_TITLE = "Rubric: clarity and accessibility"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
1,
8,
15,
22,
29,
5,
12
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "558-accessibility"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "558-accessibility"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "558-accessibility"))
Browser JavaScript companion
// Page 558 browser-side experiment: Rubric: clarity and accessibility
const pageExample558 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[1,8,15,22,29,5,12],"requests":["try","predict","run","reflect"],"page_marker":"558-accessibility"};
function summarizePage558(sample = pageExample558) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Rubric: clarity and accessibility",
kind: "accessibility",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage558());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 559 / 561Chapter 36: Capstone Assessments and Project Rubrics
Rubric: testing and reproducibility
Mini quest: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Rubric: testing and reproducibility is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 36. For the chapter-wide textbook implementation and custom diagram, jump to page 551.
# Page 559: Rubric: testing and reproducibility
def rubric_testing_and_reproducibility_p559(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(rubric_testing_and_reproducibility_p559(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of Rubric: testing and reproducibility, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 559 curation harness: Rubric: testing and reproducibility
EXAMPLE_KIND = "testing"
EXAMPLE_TITLE = "Rubric: testing and reproducibility"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
4,
11,
18,
25,
1,
8,
15
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "559-testing"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "559-testing"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "559-testing"))
Browser JavaScript companion
// Page 559 browser-side experiment: Rubric: testing and reproducibility
const pageExample559 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[4,11,18,25,1,8,15],"requests":["try","predict","run","reflect"],"page_marker":"559-testing"};
function summarizePage559(sample = pageExample559) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Rubric: testing and reproducibility",
kind: "testing",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage559());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 560 / 561Chapter 36: Capstone Assessments and Project Rubrics
Final world-class readiness review
Boss battle: make the invisible state visible
Beginner promise: this page teaches one move, one diagram, one runnable miniature, and one check. By the end, a learner should be able to explain the input, the state, the invariant, the first transition, and the stopping rule without copying code.
Mental model: Final world-class readiness review is not a fact to memorize. It is a small machine: put a clear input in, watch the state change one safe step at a time, and stop only when the output contract is satisfied.
Trace prompt: before running the lab, write a three-row table with columns before, move, and after. The best beginner explanation is a trace someone else can replay.
Common beginner mistake: reading the finished code as if it explains itself. Instead, compare the diagram, the lab output, and the reference implementation line by line.
In-page context references
Use these only when a word blocks you, then come back to the lab.
MDN Array.sort - comparator behavior and numeric sort caution
MDN Canvas API - browser drawing and visualization reference
Hand-made diagram
Visual QA instruction: verify the highlighted state matches the first line of the lab output. This keeps the diagram explanatory rather than decorative.
What to name
Input: the sample fields in the lab dictionary.
State: the part that changes after exactly one move.
Invariant: the promise that remains true after the move.
Stop: the condition that makes more work unnecessary.
Beginner confidence ladder
Run the original example.
Predict one changed output.
Change one input.
Explain the result aloud.
Write one edge-case test.
Chapter anchor: This page belongs to Chapter 36. For the chapter-wide textbook implementation and custom diagram, jump to page 551.
# Page 560: Final world-class readiness review
def final_world_class_readiness_review_p560(steps):
state = {'done': [], 'invariant': 'each step is explained before the next step starts'}
for step in steps:
state['done'].append(step)
return state
print(final_world_class_readiness_review_p560(['predict', 'run', 'explain', 'test']))
Manual review notes for students
What to inspect first
Track steps, values, requests before reading the answer.
Common trap
A polished artifact still needs a reproducible setup, keyboard path, and a visible failure mode.
Expected deliverable
Submit a short explanation of Final world-class readiness review, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 560 curation harness: Final world-class readiness review
EXAMPLE_KIND = "project"
EXAMPLE_TITLE = "Final world-class readiness review"
SAMPLE = {
"steps": [
"read input",
"state invariant",
"make one safe move",
"check output"
],
"values": [
7,
14,
21,
28,
4,
11,
18
],
"requests": [
"try",
"predict",
"run",
"reflect"
],
"page_marker": "560-project"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "steps",
"marker": sample.get("page_marker", "560-project"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "steps": []} if "steps" in sample else dict(sample)),
("single-step", {**sample, "steps": sample.get("steps", [])[:1]} if isinstance(sample.get("steps"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "560-project"))
Browser JavaScript companion
// Page 560 browser-side experiment: Final world-class readiness review
const pageExample560 = {"steps":["read input","state invariant","make one safe move","check output"],"values":[7,14,21,28,4,11,18],"requests":["try","predict","run","reflect"],"page_marker":"560-project"};
function summarizePage560(sample = pageExample560) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "Final world-class readiness review",
kind: "project",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage560());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Checkpoint questions
1. Prediction
Which field in the sample input should change the first output line?
Start with steps. Change one value and compare the first line of the lab trace.
2. Invariant
What promise should still be true after one move?
The representation should still describe the same problem, and the next step should not discard information needed by the output contract.
3. Transfer
How do you know you learned the idea rather than memorized the page?
You can draw a new input, run the same rule by hand for two steps, and explain why the diagram still matches the code.
Practice task
Create a tiny failing example, explain why it fails, then repair the code or the precondition. Add the repair to your learner notes before marking this page done.
Page 561 / 561References and Citation Map
References and citation map
Page-local deep read
Mental model for References and citation map: Treat this page as a source-selection and verification exercise. The important learner move is to connect each claim to the closest reliable reference, then return to the course example and explain the behavior in plain English.
What to trace: Start with the page lab input learner_question, choices. Write down which source you would open first, what exact claim that source verifies, and what part of the course explanation remains your own reasoning.
Beginner checkpoint: After running the lab, change the learner question and justify why the selected reference changed. If the reason is vague, use the reference shelf before continuing.
Chapter anchor: This page is the Chapter 37 anchor. Use its chapter-wide implementation, custom diagram, and page-specific lab as the reference point for the rest of References and Citation Map.
This page keeps the course honest: implementation details, browser behaviors, notebook structure, publishing advice, and accessibility goals link to public documentation that learners can inspect directly.
When a learner asks why a code example uses a certain library method, jump to the documentation link beside the example. The course text explains the teaching move; the linked documentation explains the exact API behavior.
A page-specific flow from sample input through invariant check to output.
Sample
learner_question, choices
Name the representation before running code.
→
Invariant check
The best source is the one closest to the claim: official API docs for method behavior, platform docs for publishing behavior, and course text f…
This is the condition to explain in your own words.
→
Output
Open the exact API documentation for API behavior, then return to the course explanation for the teaching model.
Compare this with the lab trace.
Use this diagram while running the page lab: change learner_question, choices, watch the invariant step, then compare the output.
Try it: source-picking lab
Run a page-specific miniature that maps a beginner question to the most honest documentation source.
Ready for page 561: References and citation map
This lab helps learners choose the right source instead of collecting random links.
Real reference-selection helper
Code docs for this example:Python heapq (priority queue API) • MDN sort (browser comparator behavior) • GitHub Pages (publishing workflow)
REFERENCE_RULES = {
"API behavior": "Use official language or browser documentation.",
"algorithm idea": "Use the course explanation first, then a trusted algorithm reference.",
"publishing workflow": "Use GitHub Pages documentation because deployment details change.",
"accessibility check": "Use W3C WAI guidance and test with keyboard, contrast, and labels.",
}
def choose_source(question: str) -> str:
q = question.lower()
if any(word in q for word in ["heap", "deque", "bisect", "cache", "sort"]):
return REFERENCE_RULES["API behavior"]
if any(word in q for word in ["publish", "github", "pages", "deploy"]):
return REFERENCE_RULES["publishing workflow"]
if any(word in q for word in ["screen reader", "keyboard", "contrast", "label"]):
return REFERENCE_RULES["accessibility check"]
return REFERENCE_RULES["algorithm idea"]
print(choose_source("Why does this example use a heap for the next item?"))
Reference-map practice
Pick one earlier page, find one claim about an API or platform behavior, and verify it with the nearest official documentation link. Then write a one-sentence note explaining why that source is more trustworthy than a generic search result.
Manual review notes for students
What to inspect first
Track learner_question, choices before reading the answer.
Common trap
Avoid reading passively. Predict the next state before looking at the output.
Expected deliverable
Submit a short explanation of References and citation map, one runnable example, and one edge case that would catch a wrong solution.
Curated reference shelf
Use these when the page raises a concrete question. Prefer the closest source: official API docs for exact behavior, course notes for concepts, and visualization references for diagrams.
Use this after the main example. It gives you a second way to exercise the page idea and a small structure for testing edge cases.
Python harness
# Page 561 curation harness: References and citation map
EXAMPLE_KIND = "reference_map"
EXAMPLE_TITLE = "References and citation map"
SAMPLE = {
"learner_question": "Why does this example use a heap for the next item?",
"choices": [
"API behavior",
"algorithm idea",
"publishing workflow",
"accessibility check"
],
"page_marker": "561-reference_map"
}
def describe_case(sample=SAMPLE):
"""Return a compact student-facing contract for this page."""
keys = [key for key in sample if key != "page_marker"]
return {
"topic": EXAMPLE_TITLE,
"kind": EXAMPLE_KIND,
"inputs_to_watch": keys,
"first_input": "learner_question",
"marker": sample.get("page_marker", "561-reference_map"),
}
def edge_cases(sample=SAMPLE):
"""Generate small variations students should run before trusting an answer."""
cases = [
("original", dict(sample)),
("empty-ish", {**sample, "learner_question": []} if "learner_question" in sample else dict(sample)),
("single-step", {**sample, "learner_question": sample.get("learner_question", [])[:1]} if isinstance(sample.get("learner_question"), list) else dict(sample)),
]
return cases
def assert_contract(result):
"""A deliberately small assertion hook: replace with the real page output."""
assert result is not None, "The algorithm must return an inspectable result."
return True
if __name__ == "__main__":
print(describe_case())
for label, case in edge_cases():
print(label, case.get("page_marker", "561-reference_map"))
Browser JavaScript companion
// Page 561 browser-side experiment: References and citation map
const pageExample561 = {"learner_question":"Why does this example use a heap for the next item?","choices":["API behavior","algorithm idea","publishing workflow","accessibility check"],"page_marker":"561-reference_map"};
function summarizePage561(sample = pageExample561) {
const keys = Object.keys(sample).filter((key) => key !== "page_marker");
return {
title: "References and citation map",
kind: "reference_map",
keys,
marker: sample.page_marker,
nextChange: keys[0] ? `Change ${keys[0]} and rerun the page lab.` : "Add one tiny input.",
};
}
console.table(summarizePage561());
Student practice studio
Choose one action, write your prediction, then run the page lab above and compare.
Pick an action to get a page-specific prompt.
Reference page checkpoint
What should be cited?
Cite APIs, platform behavior, external problem references, browser features, and claims that students may need to verify independently.
What should stay original?
Explanations, diagrams, labs, checkpoints, and classroom prompts are written as original teaching material for this course.