Foundations to FrontierPart II: FoundationsBezhig

Cumulative checkpoint: programming and discrete reasoning

6 exercises, each with a complete solution.

Use after C01–C05. Reserve roughly 45–75 minutes, adjusting for your other commitments. Work without AI, solution pages, or execution on the first pass. Record assumptions and predicted behavior before testing. Score each problem for setup, reasoning, execution, verification, and explanation; a familiar answer copied from memory is not evidence of transfer.

CP.01CSolution

Trace total=0; for value in [3,-2,5]: total=2*total+value. Give the state after each iteration and write a recurrence for the state after kk values. Explain why it is not an ordinary running sum.

CP.02CSolution

In Python, let a=[[1],[2]]; b=a.copy(); b[0].append(7); b.append([3]). Give the final contents of both names and explain precisely which objects were copied and which remain shared.

CP.03CSolution

A C++ function returns a reference to a local std::vector<int>. Explain the defect. Compare returning the vector by value with returning a reference to caller-owned storage, including lifetime obligations.

CP.04CSolution

Negate “for every request there exists a server that eventually replies.” Then explain why this statement does not assert that one fixed server replies to every request.

CP.05CSolution

Prove by induction that 33 divides 4n−14^n-1 for every integer n≥0n\ge0. State the base case, induction hypothesis, and the exact algebraic use of that hypothesis.

CP.06TSolution

A recurrence has T(1)=1T(1)=1 and T(n)=T(n/2)+1T(n)=T(n/2)+1 for powers of two. Solve it and explain why a recursive implementation’s termination needs a domain restriction or rounding/base-case policy for other positive integers.

Optional small hints

CP.02: copying an outer list does not recursively copy inner lists. CP.05: rewrite 4n+1−14^{n+1}-1 using 4n−14^n-1. CP.06: count how many halvings reach one.

Complete solutions: CP#

Compare the first step where your work differs. A corrected answer is not yet an independent success.

CP.01Show solution

A weighted history, not a sum

The states are 33, 2(3)−2=42(3)-2=4, and 2(4)+5=132(4)+5=13. With inputs v1,…,vnv_1,\ldots,v_n, let t0=0t_0=0 and tk=2tk−1+vkt_k=2t_{k-1}+v_k. Earlier inputs are repeatedly doubled; for three inputs, t3=4v1+2v2+v3t_3=4v_1+2v_2+v_3, which gives 12−4+5=1312-4+5=13. An ordinary prefix sum instead satisfies sk=sk−1+vks_k=s_{k-1}+v_k. This derivation explains the observed state rather than merely quoting the printed output.

Back to CP.01
CP.02Show solution

The outer containers differ; one inner mutation is shared

Final a is [[1,7],[2]]; final b is [[1,7],[2],[3]]. The shallow copy created a new outer list containing references to the same two inner lists. Appending to the first inner list affects the shared object seen through both names. Appending a third inner list to b changes only that outer list. A memory diagram with two outer containers pointing to shared inner containers makes both effects predictable.

Back to CP.02
CP.03Show solution

A reference cannot extend the destroyed local object’s lifetime

The local vector is destroyed when the function returns, so a reference to it dangles. Using it is invalid even if the old memory appears intact. Returning by value transfers a valid result object under C++ value semantics, with move or copy-elision behavior as applicable; the caller owns the resulting lifetime. Returning a reference to caller-owned storage can be valid only while that storage remains alive and under a clear mutation/invalidation contract. The choice is about ownership and API semantics, not a blanket rule that references are always faster.

Back to CP.03
CP.04Show solution

Negate quantifiers in order

The negation is: there exists a request such that every server fails to eventually reply to that request. In symbolic form, ¬∀r∃s R(r,s)\neg\forall r\exists s\,R(r,s) becomes ∃r∀s ¬R(r,s)\exists r\forall s\,\neg R(r,s). The original permits the chosen server to depend on the request. For example, one server may answer odd-numbered requests and another even-numbered requests; every request has a responder, but neither server answers all requests. This is not the same as ∃s∀r R(r,s)\exists s\forall r\,R(r,s).

Back to CP.04
CP.05Show solution

Use the induction hypothesis as a divisible factor

For n=0n=0, 40−1=04^0-1=0, divisible by 33. Assume 4n−1=3k4^n-1=3k for an integer kk. Then 4n+1−1=4(4n−1)+3=12k+3=3(4k+1)4^{n+1}-1=4(4^n-1)+3=12k+3=3(4k+1), also divisible by 33. Therefore the claim holds for all nonnegative integers by induction. The proof does not assume the desired next case; it constructs its integer factor from the current case.

Back to CP.05
CP.06Show solution

A cost recurrence and an implementation domain are different

For n=2mn=2^m, after mm halvings the argument reaches one. Unrolling gives T(n)=T(1)+m=1+log⁡2nT(n)=T(1)+m=1+\log_2n. A literal real-valued halving routine on input 33 never reaches exactly one, while an integer routine must specify floor/ceiling and a base condition such as n≤1n\le1. The mathematical recurrence’s stated power-of-two domain made the base reachable. An implementation on a larger domain needs a new termination argument and possibly a different exact recurrence.

Back to CP.06

Retention and readiness#

Repair C01–C03 for state or lifetime errors and C04–C05 for quantifier or induction errors. Advance to independent algorithm work when you can explain these solutions from a blank page and solve a fresh variant, not merely recognize the reference.