// for competitive programmers

Stop debugging code.
Debug thinking instead.

You've written while (left < right) and couldn't state what that condition actually preserves. You pass 90% of test cases and fail on the empty array or single element you can't explain. The bug isn't in the code — it's in the invariant you never stated.

A coach that explains is a textbook.
A coach that mentors is the real coach.

Unlike ChatGPT, which will hand you the algorithm if you push — this coach won't, even if you beg.

View on GitHub

Five questions. In order.
You cannot skip a gate.

Gates unlock by demonstration, not by explanation. Not by asking nicely. A user who jumps to Gate 4 without clearing Gate 2 gets brought back to Gate 2.

1
Problem Understanding
What is this problem actually asking?
"Explain what this problem is actually asking in one sentence. No jargon. No restating the description. What does it want you to produce?"
Clears when the sentence would let a stranger solve the problem without reading the original statement.
✗ "Find the longest subarray using two pointers."
✓ "Return the length of the longest subarray with at most k zeros."
2
Constraints
What complexity can you afford?
"What is the input size? What does that tell you about the complexity you can afford?"
Clears when you correctly identify the complexity budget and what it rules out. The coach never pushes for a faster solution — that conversation happens after the card, not before.
✗ "n = 10^5 so we need to be efficient."
✓ "n ≤ 10^5 means O(n²) — 10^10 ops — would TLE. O(n log n) or better is the budget."
3
Manual Trace
Walk through the example. Show every step.
"Walk through the first example by hand — any method, even brute force. Then: what work are you repeating that you could carry forward from the previous step?"
Two parts. The smarter algorithm must emerge from your own trace. The coach never names it — not "two-pointer", not "sliding window". Structure surfaces itself, or you stay in Gate 3.
✗ "I'd use a sliding window where left moves when the window is invalid."
✓ "[0,4] → length 5 with 2 flips. Then I realized I missed the window that flips on both sides."
4
Invariant + Liveness + Bounds + Edge Cases
What is always true about [left, right]?
"Before any code: what is guaranteed about everything to the left of your slow pointer at every single moment during the loop — start, each step, and end?"
Four parts, all four must clear: the safety invariant, why the loop terminates, why your exact loop bound is correct and not ±1, and every named edge case traced on a specific input. Only then: "Write the code. Paste it here when you're done."
✗ "The window is valid when we update max." (only true sometimes)
✓ "Zeros in [left, right] ≤ k — not just when max updates. At every single step."
5
Verification — triggered by a bug
Where does your invariant first break?
"Set the code aside. Tell me: at which step does your invariant first break?"
Coach reads the code once, silently, and classifies the bug: structural (rewrite the loop), typing (pointed out directly — no Socratic dance for a typo), or thinking (never debug the code — always ask about the invariant). Each class handled differently.
✗ "It's wrong at line 12 because I forgot to increment left."
✓ "Step 3: right=4, left=0, zeros=k+1. The invariant breaks here — window is over budget."

You don't get this by asking for it.
You get it by proving the invariant yourself.

Every session that reaches a correct solution ends with this card. Save every card. Over time they become a library of patterns you actually understand — not patterns you memorized from editorials.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
INVARIANT CARD
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PROBLEM      : Longest Substring Without Repeating Characters (LeetCode #3)
TYPE         : sliding-window-variable

SLOW POINTER : left — all characters in [left, right] are unique at every moment
FAST POINTER : right — scanner; advances one step per iteration regardless
TERMINATION  : right == s.size(); maxLen holds the longest valid window seen

EDGE CASE    : empty string → returns 0 ✓  single char → returns 1 ✓  all same → max stays 1 ✓

EARNED       : 2026-05-21
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

What this coaches

✓ in scope
  • Fast / slow pointer Remove Element, Move Zeroes
  • Opposite-end two-pointer Two Sum sorted, Container With Most Water
  • Sliding window — fixed size Max Average Subarray, Find All Anagrams
  • Sliding window — variable size Longest Substring, Min Window Substring
  • Partition pointer Sort Colors, Segregate by parity
— out of scope
  • Dynamic programming
  • Graph algorithms (BFS, DFS, shortest path)
  • Tree traversals
  • Divide and conquer
  • Pure greedy / math — no pointer invariant

If you paste an out-of-scope problem, the coach names what algorithm family it looks like and stops. This is not a general CP coach. Specificity is the point.

Drop it in. Start immediately.

  1. 1 Clone or download this folder
  2. 2 Open claude.ai → New Project
  3. 3 Upload all .md files — root level and everything inside reference/ — into the project knowledge base
  4. 4 Paste any LeetCode or Codeforces problem as text
  5. 5 Gate 1 fires immediately. No configuration needed.

Claude Code users: point it at this folder instead. Sonnet 4.6 is sufficient. No Opus needed.