Invariants
invariants
Foundations
Debugging by Tracing
Most beginners debug by staring at their code and hoping the bug reveals itself. Engineers who ship working software do something different: they trace execution one line at a time, watch each variable, and pinpoint the exact moment the program's state stops matching their mental model. That motion is a learnable, repeatable skill. **Debugging by Tracing** turns that skill into a structured workflow. You will define what program state actually is (the values of every variable plus the current line of execution), practice walking through a function step by step recording each change, and learn to use loop invariants (conditions that must hold before and after every iteration) to verify correctness without running the code. You will work through a systematic process of reproduce, trace, locate, fix, and verify, and you will see the most common beginner pitfalls including off-by-one errors, uninitialized variables, and misordered swaps. In **How to Read Code (JS & Python)**, you practiced tracing variables through `for` and `while` loops and stepping through function calls on the call stack. This lesson takes that same tracing motion and aims it at a specific goal: finding the line where a bug first introduces wrong state, instead of just understanding what correct code is doing. With Tier 1 essentials behind you, you will be ready to dive into the data structures track starting with **Arrays & Strings**, where every algorithm you write will benefit from being traceable and provably correct.
Not Started
0%
Algorithms
Complexity & Proof Intuition (Optional)
Comparison-based sorting cannot do better than `O(n log n)`. That is not a statement about merge sort or quick sort or any specific algorithm; it is a statement about every possible algorithm in this model, including ones nobody has invented yet. The proof is a counting argument over decision trees, and learning to read it changes how you reason about algorithmic limits forever. Lower bounds, NP-completeness, P versus NP, and loop invariants all live in the same theoretical neighborhood. **Complexity & Proof Intuition (Optional)** is an enrichment tour of that neighborhood. You will use loop invariants to prove iterative algorithms correct, revisit amortized analysis with the potential method, work through NP-completeness via polynomial-time reductions and the Cook-Levin theorem, examine the P vs. NP question and its implications, derive the `Omega(n log n)` comparison-sorting lower bound via decision trees, and meet the broader complexity zoo (co-NP, PSPACE, EXP). This lesson rests on three earlier ideas. **Asymptotic Analysis Fundamentals** gave you the language of growth rates that complexity classes refine. **Dynamic Programming (Intro)** and **Greedy (Intro)** showed you exact polynomial-time algorithms; this lesson asks which problems will never have one. This concludes the algorithms track. From here, the natural next step is sustained problem solving on hard interview problems and competitive programming contests that exercise the full toolkit you have built.
Not Started
0%
Community
Loop Invariants in Real Code, Not Textbook Code
What a loop invariant actually is, the three things it has to claim, how to use them in a code review (not a proof), and the bug a one-line invariant comment would have caught for me.
Binary Search Questions I Overcomplicated
Four binary search problems I made harder than they needed to be. Each shows the version I wrote in the loop and the version that should have been my first instinct, with invariants written down.
