ASAPUtils Logo ASAPUtils
Foundation · Week 0

Loops, Indices & Pattern Printing

Nested loops, index arithmetic, and loop invariants — taught through star patterns and pyramids. This is the skill that later makes tree traversal, two pointers, and DP tables feel obvious instead of impossible.

Watch it run

Step through it. Then hide the page and predict the next frame before pressing →. Predicting is the part that builds the skill; watching alone does not.

Why this page exists

If you can’t reliably print a centred pyramid, the problem is not pyramids. Pyramids have no data structure, no algorithm and no trick — they are nested loops and arithmetic on the loop variables, and nothing else. Struggling here means the underlying skill isn’t built yet: predicting how state evolves, one step at a time.

That same skill is what tree traversal, two pointers, sliding windows and DP tables all require. So this page is not a warm-up. It is the foundation, and it’s worth a full week’s attention before touching a single LeetCode problem.

The method: trace before you run

For every exercise below, do this before running the code:

  1. Draw a table with columns i, j, and what happens.
  2. Fill in the first three iterations by hand.
  3. Only then run it.
  4. Where your table and the real output disagree — that gap is your mental model being wrong. Finding that gap is the entire exercise. Fix the model, not just the code.

This feels slow. It’s the fastest thing in the whole 12 weeks.

Invariants

An invariant is one sentence that is true at the top of every iteration. For the right triangle:

At the top of the outer loop, output holds exactly i finished rows.

For an in-place array reversal:

Everything outside the range [l, r] is already in its final position.

Say the invariant out loud before you write the loop. Most off-by-one bugs are an invariant you never articulated — you can’t be off by one from a target you never stated.

The ladder

Work through these in order, in both C++ and JavaScript. Don’t skip ahead; each one adds exactly one new idea.

  1. Print 1..n, then n..1. State the invariant for each.
  2. A row of n stars.
  3. A right triangle (the visualizer above). New idea: the inner loop bound depends on i.
  4. An inverted right triangle. New idea: the bound counts down.
  5. A centred pyramid. New idea: two inner loops — spaces, then stars. This is the one that clicks.
  6. A diamond — a pyramid plus its inverse. New idea: reuse, not new logic.
  7. A hollow square, then a hollow pyramid. New idea: print a star only on the boundary, so the condition is about position, not count.
  8. Floyd’s triangle and Pascal’s triangle. New idea: same shape, different cell formula.
  9. Matrix walks on matrix[i][j]: row-major, column-major, main diagonal (i == j), anti-diagonal (i + j == n - 1), the boundary ring, then the full spiral.
  10. Reverse an array in place, then rotate it by k. Write the invariant for both.

Shape and content are two different problems

This is the insight that makes number pyramids and Pascal’s triangle stop being separate problems. Every pattern question is:

  • Shape — for row i, how many leading spaces and how many cells?
  • Content — for cell j of row i, what character or number goes there?

Solve the shape first with stars. Once the shape is right, swapping * for j + 1, or for a binomial coefficient, is a one-line change. People who find these hard are usually trying to solve both at once.

The three mistakes

  1. Guessing the formula instead of deriving it. Write out rows 0, 1 and 2 with their space and star counts, then find the formula that fits all three. Don’t pattern-match from memory.
  2. < vs <= by trial and error. If you’re flipping the operator until the output looks right, you don’t have an invariant. Stop and write one.
  3. Debugging by running. Running tells you that it’s wrong. Hand-tracing tells you why. Only the second one improves you.

Done when

You can write a centred pyramid in C++ and JavaScript from scratch, first try, no reference — and you can state the invariant of every loop you wrote. Then move on to recursion and the call stack, which is the same skill applied to a stack instead of a counter.

Related Topics