C05: Induction, counting, recurrences, graphs, and modular arithmetic
On this page
- A. Prerequisites and observable goals
- B. The central question: how does a small step establish an unbounded family?
- C. Strong and structural induction
- D. Counting: identify choices before applying formulas
- E. Recurrences count the work generated by recursion
- F. Modular arithmetic retains the information a problem needs
- G. Independent practice
- H. Complete solutions: C05
- I. Retention and readiness
A. Prerequisites and observable goals#
C04 logic and proofs; C02 recursion; elementary algebra.
Write valid induction proofs, distinguish strong and structural induction, count without confusing order or replacement, analyze a recurrence, and explain Euclid’s algorithm and modular exponentiation.
Level: Degree core.
B. The central question: how does a small step establish an unbounded family?#
Induction proves a statement for every integer from a starting point onward. Prove the base case. Then, for an arbitrary admissible , assume and prove . The induction hypothesis is a conditional tool inside the step, not permission to assume the final theorem. The base case starts the chain, and the step connects every consecutive link.
For , the base case uses the empty sum zero. Assuming the formula for , add the next term:
The first equality is where the induction hypothesis is used. Writing down the desired formula for without deriving it would be circular. Loop invariants have the same structure: initialization is the base case, preservation is the induction step, and loop termination connects the invariant with the postcondition.
C. Strong and structural induction#
Strong induction permits assuming all earlier cases within the declared range when proving the next case. It is useful when an object depends on several smaller sizes, not just one. To prove every integer is expressible as with nonnegative integers , establish 18, 19, 20, and 21. For , the smaller is covered, and adding one 4 completes the representation. Four base cases are needed because the step moves backward by four.
Structural induction follows the way objects are built. A full binary tree is either a leaf or an internal node with two full binary subtrees. Prove a property for a leaf, then prove that combining any two subtrees with the property produces a tree with the property. For the identity between leaves and internal nodes, a leaf has . Combining subtrees gives because the new root makes . The definition “full” matters: arbitrary one-child nodes would invalidate this formula.
D. Counting: identify choices before applying formulas#
The product rule counts a sequence of choices when each partial choice has a known number of continuations. Choosing an ordered list of distinct elements from gives . If order does not matter, each selected subset was counted times, yielding . With replacement and ordered positions, the count is . None of these formulas can be selected correctly until order and replacement are specified.
Inclusion–exclusion corrects double counting: . For three sets, subtract pairwise intersections and add the triple intersection once. The pigeonhole principle says that placing more than objects into boxes forces a box to contain at least two. More generally, some box holds at least among objects. A hash table with more possible keys than hash outputs must have collisions. This fact does not say how frequent collisions are under a particular workload or how efficiently they are handled.
E. Recurrences count the work generated by recursion#
If a divide-and-conquer algorithm splits an input into two equal subproblems and does additional work, a model is , with , initially for powers of two. At each of internal levels, the combined nonrecursive work is . The leaves contribute . Therefore . The recurrence describes a cost model, not a measured runtime or a proof of the algorithm’s output correctness.
A naive recursive Fibonacci implementation repeats subproblems: and each recompute many earlier values. Memoization or iteration changes the computation graph and can reduce the number of distinct subproblems to . A recurrence must match the actual implementation; writing a familiar formula beside different code does not analyze it.
A graph consists of vertices and edges. In a finite undirected simple graph, the sum of all vertex degrees equals , because every edge contributes one to each endpoint’s degree. A tree is connected and acyclic. Removing a leaf from a nontrivial finite tree leaves a smaller tree, enabling the induction proof . A disconnected acyclic graph is a forest, not a tree; the number of components changes the formula. C08 uses these distinctions in traversal and spanning-tree algorithms.
F. Modular arithmetic retains the information a problem needs#
Congruence means divides , with positive modulus . Addition and multiplication respect congruence, so large intermediate powers can be reduced modulo without changing the final residue. This is useful for cyclic indexing and number-theoretic algorithms. It does not justify arbitrary division: a modular inverse of exists exactly when . For example, , so 5 is the inverse of 3 modulo 7; 2 has no inverse modulo 6.
Euclid’s algorithm repeatedly replaces by . The gcd is unchanged because a common divisor divides and exactly when it divides and . Nonnegative remainders strictly decrease until zero, proving termination. Repeated squaring computes in modular multiplication steps by reading the exponent’s binary expansion. The lab is mathematical computation, not a cryptographic implementation: timing behavior, parameter validation, key handling, and side channels require specialized libraries and analysis.
G. Independent practice#
F foundation C standard course work T transfer S optional stretch L runnable lab or project. Attempt the complete set before opening its solutions.
Prove by induction that for all . Identify the exact use of the induction hypothesis.
Complete the strong-induction proof that every integer can be written with integers. Give all four base representations and explain why one base case would not support this step.
From eight distinct tasks, count ordered schedules of three different tasks and unordered selections of three tasks. Then explain why nine stored keys and eight hash buckets force a collision without proving poor average performance.
Solve , , for a power of two. Separately prove that a full binary tree with internal nodes has leaves. Explain why these are different uses of a tree.
Implement Euclid’s gcd and repeated-squaring mod_power in discrete_lab.py. Accept a nonnegative exponent and positive modulus, reject inappropriate input types, and compare modular powers with Python’s three-argument pow. State the loop invariant and the role of exponent bits.
Optional small hints
C05.01: the next odd number is . C05.05: maintain that the accumulated result times the current base raised to the remaining exponent is congruent to the original target.
H. Complete solutions: C05#
Compare the first step where your work differs. A corrected answer is not yet an independent success.
C05.01Show solution
A new square adds the next odd number
For , both the empty sum and are zero. Assume the sum through equals . Then the sum through is . Replacing the old sum by is the precise induction-hypothesis step. This proves the statement for every nonnegative integer, not just the illustrated small cases.
Back to C05.01C05.02Show solution
A step of four needs a complete starting band
, , , and . For arbitrary , strong induction supplies a representation of , since it lies between 18 and . Add one 4 to obtain . A single base case at 18 with this step would reach only integers congruent to 18 modulo 4; the other residues need their starting cases.
Back to C05.02C05.03Show solution
Order changes multiplicity
Ordered schedules number . Each unordered triple appears in orders, so there are selections. Nine keys distributed among eight buckets force at least one bucket to contain two keys. That is a worst-case existence statement for this allocation, not a distributional claim about chain lengths, lookup workload, hash quality, or total latency. A well-designed collision policy can still provide good expected performance under appropriate assumptions.
Back to C05.03C05.04Show solution
Cost trees and structural trees
There are internal levels, each with total added work , and leaves each costing one. Thus . For the full binary tree, the leaf base case has . Combining subtrees with yields and . The recurrence tree describes recursive calls and their costs; the structural proof applies to the definition of a full binary tree independent of any algorithm’s runtime.
Back to C05.04C05.05Show solution
Reference number-theoretic computation
"""C05.05: Euclid and repeated squaring."""
def gcd(a: int, b: int) -> int:
a, b = abs(a), abs(b)
while b:
a, b = b, a % b
return a
def mod_power(base: int, exponent: int, modulus: int) -> int:
if any(type(x) is not int for x in (base, exponent, modulus)):
raise TypeError("integer arguments required")
if exponent < 0 or modulus <= 0:
raise ValueError("exponent >= 0 and modulus > 0 required")
result = 1 % modulus
base %= modulus
while exponent:
if exponent & 1:
result = (result * base) % modulus
base = (base * base) % modulus
exponent //= 2
return result
if __name__ == "__main__":
print(gcd(252, 105), mod_power(7, 13, 11))Euclid preserves the gcd while decreasing the nonzero remainder. Repeated squaring maintains , where is the accumulated result, the current base, and the remaining exponent. If is odd, move one factor into ; then square and halve the remaining even exponent. When , the invariant states that is the desired residue. Initializing the result as also handles modulus one. Comparison with pow across generated values catches implementation errors, while the invariant explains why every valid iteration preserves the target. Large-integer arithmetic has nonconstant bit cost, so the multiplication-step count is not the entire runtime model.
I. Retention and readiness#
Retrieve proof hypotheses, finite domains, and loop-state tracing. Advance when you can choose ordinary, strong, or structural induction from the dependency structure, and when a complexity recurrence includes an explanation of the operations it counts.