Foundations to FrontierPart II: FoundationsBezhig

C05: Induction, counting, recurrences, graphs, and modular arithmetic

5 exercises, each with a complete solution. 1 figure. 1 code listing.

On this page
  1. A. Prerequisites and observable goals
  2. B. The central question: how does a small step establish an unbounded family?
  3. C. Strong and structural induction
  4. D. Counting: identify choices before applying formulas
  5. E. Recurrences count the work generated by recursion
  6. F. Modular arithmetic retains the information a problem needs
  7. G. Independent practice
  8. H. Complete solutions: C05
  9. I. Retention and readiness

A. Prerequisites and observable goals#

Before

C04 logic and proofs; C02 recursion; elementary algebra.

After

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 P(n)P(n) for every integer nn from a starting point onward. Prove the base case. Then, for an arbitrary admissible kk, assume P(k)P(k) and prove P(k+1)P(k+1). 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 1+2+⋯+n=n(n+1)/21+2+\cdots+n=n(n+1)/2, the base case n=0n=0 uses the empty sum zero. Assuming the formula for kk, add the next term:

∑i=1k+1i=k(k+1)2+(k+1)=(k+1)(k+2)2.\sum_{i=1}^{k+1}i=\frac{k(k+1)}2+(k+1) =\frac{(k+1)(k+2)}2.

The first equality is where the induction hypothesis is used. Writing down the desired formula for k+1k+1 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 n≥18n\ge18 is expressible as 4a+7b4a+7b with nonnegative integers a,ba,b, establish 18, 19, 20, and 21. For n≥22n\ge22, the smaller n−4≥18n-4\ge18 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 L=I+1L=I+1 between leaves and internal nodes, a leaf has L=1,I=0L=1,I=0. Combining subtrees gives L=L1+L2=(I1+1)+(I2+1)=I+1L=L_1+L_2=(I_1+1)+(I_2+1)=I+1 because the new root makes I=I1+I2+1I=I_1+I_2+1. 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 kk distinct elements from nn gives n(n−1)⋯(n−k+1)n(n-1)\cdots(n-k+1). If order does not matter, each selected subset was counted k!k! times, yielding (nk)=n!/[k!(n−k)!]\binom nk=n!/[k!(n-k)!]. With replacement and ordered positions, the count is nkn^k. None of these formulas can be selected correctly until order and replacement are specified.

Inclusion–exclusion corrects double counting: ∣A∪B∣=∣A∣+∣B∣−∣A∩B∣|A\cup B|=|A|+|B|-|A\cap B|. For three sets, subtract pairwise intersections and add the triple intersection once. The pigeonhole principle says that placing more than mm objects into mm boxes forces a box to contain at least two. More generally, some box holds at least ⌈n/m⌉\lceil n/m\rceil among nn 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 cncn additional work, a model is T(n)=2T(n/2)+cnT(n)=2T(n/2)+cn, with T(1)=dT(1)=d, initially for powers of two. At each of log⁡2n\log_2 n internal levels, the combined nonrecursive work is cncn. The nn leaves contribute dndn. Therefore T(n)=cnlog⁡2n+dn=Θ(nlog⁡n)T(n)=cn\log_2n+dn=\Theta(n\log n). 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: F(n−1)F(n-1) and F(n−2)F(n-2) each recompute many earlier values. Memoization or iteration changes the computation graph and can reduce the number of distinct subproblems to n+1n+1. 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 2∣E∣2|E|, 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 ∣E∣=∣V∣−1|E|=|V|-1. 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.

A recurrence as a tree of work. T(n)=2T(n/2)+cnT(n)=2T(n/2)+cn for n=8n=8. Each box is a subproblem, labelled with its size; the work done at one level, outside the recursive calls, adds up to c⋅8c\cdot8. Three levels of splitting and eight leaves give T(8)=24c+8dT(8)=24c+8d, and in general cnlog⁡2n+dncn\log_2n+dn.

F. Modular arithmetic retains the information a problem needs#

Congruence a≡b(modm)a\equiv b\pmod m means mm divides a−ba-b, with positive modulus mm. Addition and multiplication respect congruence, so large intermediate powers can be reduced modulo mm 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 aa exists exactly when gcd⁡(a,m)=1\gcd(a,m)=1. For example, 3⋅5≡1(mod7)3\cdot5\equiv1\pmod7, so 5 is the inverse of 3 modulo 7; 2 has no inverse modulo 6.

Euclid’s algorithm repeatedly replaces (a,b)(a,b) by (b,a mod b)(b,a\bmod b). The gcd is unchanged because a common divisor divides aa and bb exactly when it divides bb and a−qba-qb. Nonnegative remainders strictly decrease until zero, proving termination. Repeated squaring computes ae mod ma^e\bmod m in O(log⁡(e+1))O(\log(e+1)) 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.

C05.01CSolution

Prove by induction that ∑i=1n(2i−1)=n2\sum_{i=1}^n(2i-1)=n^2 for all n≥0n\ge0. Identify the exact use of the induction hypothesis.

C05.02CSolution

Complete the strong-induction proof that every integer n≥18n\ge18 can be written 4a+7b4a+7b with a,b≥0a,b\ge0 integers. Give all four base representations and explain why one base case would not support this step.

C05.03CSolution

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.

C05.04TSolution

Solve T(n)=2T(n/2)+nT(n)=2T(n/2)+n, T(1)=1T(1)=1, for nn a power of two. Separately prove that a full binary tree with II internal nodes has I+1I+1 leaves. Explain why these are different uses of a tree.

C05.05LabSolution

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 2(k+1)−1=2k+12(k+1)-1=2k+1. 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 n=0n=0, both the empty sum and 020^2 are zero. Assume the sum through kk equals k2k^2. Then the sum through k+1k+1 is k2+[2(k+1)−1]=k2+2k+1=(k+1)2k^2+[2(k+1)-1]=k^2+2k+1=(k+1)^2. Replacing the old sum by k2k^2 is the precise induction-hypothesis step. This proves the statement for every nonnegative integer, not just the illustrated small cases.

Back to C05.01
C05.02Show solution

A step of four needs a complete starting band

18=4+7+718=4+7+7, 19=4+4+4+719=4+4+4+7, 20=4+4+4+4+420=4+4+4+4+4, and 21=7+7+721=7+7+7. For arbitrary n≥22n\ge22, strong induction supplies a representation of n−4n-4, since it lies between 18 and n−1n-1. Add one 4 to obtain nn. 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.02
C05.03Show solution

Order changes multiplicity

Ordered schedules number 8⋅7⋅6=3368\cdot7\cdot6=336. Each unordered triple appears in 3!=63!=6 orders, so there are 336/6=56336/6=56 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.03
C05.04Show solution

Cost trees and structural trees

There are log⁡2n\log_2n internal levels, each with total added work nn, and nn leaves each costing one. Thus T(n)=nlog⁡2n+nT(n)=n\log_2n+n. For the full binary tree, the leaf base case has (I,L)=(0,1)(I,L)=(0,1). Combining subtrees with Lj=Ij+1L_j=I_j+1 yields I=1+I1+I2I=1+I_1+I_2 and L=L1+L2=I1+I2+2=I+1L=L_1+L_2=I_1+I_2+2=I+1. 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.04
C05.05Show solution

Reference number-theoretic computation

code/solutions/discrete_lab.pyPython
"""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 r be≡a0e0(modm)r\,b^e\equiv a_0^{e_0}\pmod m, where rr is the accumulated result, bb the current base, and ee the remaining exponent. If ee is odd, move one factor bb into rr; then square bb and halve the remaining even exponent. When e=0e=0, the invariant states that rr is the desired residue. Initializing the result as 1 mod m1\bmod m 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.

Back to C05.05

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.