Shape Rule
Spaces + digits
Each row prints leading spaces while j > i, then digits i..1 in descending order.

The right-aligned descending triangle prints 1, 21, 321, 4321, 54321 — a natural step after the spaced mirror in Program 29. This tutorial covers fixed-width loops, leading-space padding, conditional printing, a live preview, worked JavaScript examples, edge cases, and complexity.
Spaces + digits
Each row prints leading spaces while j > i, then digits i..1 in descending order.
i = 1..rows
for (let i = 1; i <= rows; i++) — one right-aligned row per iteration.
rows..1
if (j > i) prints space; else prints j.
Always rows
Inner loop always runs rows times — spaces pad the left side.
3–9 rows
Pick a row count and draw the right-aligned triangle in the browser.
Complexity
Each row runs one loop of width rows — total work scales as n².
A right-aligned descending number triangle prints leading spaces on each row, then digits from i down to 1. With rows = 5, the triangle grows rightward: 1, 21, … 54321.
In JavaScript you use one fixed-width inner loop: print a space when j > i, otherwise append j.
It combines conditional printing with leading-space padding — a step up from Program 29’s two-loop mirror.
Inner loop always runs rows times.
Print space for leading padding.
Print digit in descending order.
Follow Program 29; continue to Program 31 (number-star diamond) next.
In short: for each i, inner loop prints space or j, then console.log(line).
Given rows = 5, print a right-aligned descending triangle: for each i, print spaces while j > i, then print digits i..1 in a fixed-width inner loop.
// rows = 5 (conceptual shape)
// 1
// 21
// 321
// 4321
// 54321 | Item | Type | Description |
|---|---|---|
rows | int | Pattern height — also the fixed width of the inner loop. |
i | int | Outer loop — current row; controls how many leading spaces print. |
j | int | Inner loop — prints space when j > i, else prints j. |
for i from 1 to rows:
line = ""
for j from rows down to 1:
line += " " if j > i else j
console.log(line) | Approach | Idea | Best for |
|---|---|---|
| if/else | 1, 21, … | Learning and interviews |
| Conditional expression | line += (j > i) ? " " : j | Compact console programs |
| User-input rows | parseInt(prompt(...), 10) | Flexible row count |
| Goal | Pattern |
|---|---|
| Walk rows | for (let i = 1; i <= rows; i++) |
| Inner loop | for (let j = rows; j >= 1; j--) |
| Leading spaces | if (j > i) { line += " "; } else { line += j; } |
| End the row | console.log(line) |
| Conditional form | line += (j > i) ? " " : j |
| User input | parseInt(prompt(...), 10) |
Same right-aligned triangle — different ways to write the condition and control rows.
i = 1..rowsOne right-aligned row per iteration
" " if j > i else jSpace or digit
j = rows..1Fixed width each row
rows - iLeading spaces per row
Reach for this pattern when teaching fixed-width loops, leading-space padding, and conditional character output.
Natural follow-up after Program 29 — introduces right alignment with a single inner loop.
Outer/inner bound practice with an immediate visual check.
Combine loops with prompt() for a flexible row count.
Compare Program 29 (spaced mirror) and Program 31 (number-star diamond) next.
This is a console teaching pattern — not how you build modern app screens.
Key benefit: one small program that locks in nested loops, output sequencing, and O(n²) thinking.
Choose a row count between 3 and 9 and draw the right-aligned descending triangle in the browser.
Three complete JavaScript programs — fixed rows, user input with conditional expression form, and a smaller trace demo. Click View Output to reveal sample console results, or Try it Yourself to run the code live.
Print five rows of the right-aligned descending triangle with if/else in one inner loop.
rows = 5Hard-coded row count — ideal for first demos and screenshots.
const rows = 5;
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = rows; j >= 1; j--) {
if (j > i) {
line += " ";
} else {
line += j;
}
}
console.log(line);
} When i = 1, the inner loop appends four spaces then 1 — output 1. When i = 5, no leading spaces — output 54321.
Read the row count with prompt() instead of hard-coding 5.
Read rows with prompt() and parseInt(); the inner loop uses rows as the fixed width.
const rowsInput = prompt("Enter rows:");
const rows = parseInt(rowsInput, 10);
if (!Number.isFinite(rows) || rows < 1) {
console.log("Please enter a positive integer.");
} else {
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = rows; j >= 1; j--) {
line += (j > i) ? " " : j;
}
console.log(line);
}
} Same right-aligned core as Example 1; a conditional expression replaces if/else and rows replaces hard-coded 5. Non-numeric input yields NaN with bare parseInt(prompt(), 10) — validate with Number.isFinite for safer labs.
Run with rows = 3 to trace every row on paper before scaling up.
rows = 3Same if/else logic with a smaller row count for quick tracing.
const rows = 3;
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = rows; j >= 1; j--) {
if (j > i) {
line += " ";
} else {
line += j;
}
}
console.log(line);
} Only rows changes from 5 to 3 — the if/else structure stays identical. Trace i = 1, 2, 3 on paper to see how leading spaces shrink each row.
No imports needed for fixed rows; use prompt() when reading. Set rows = 5 and loop variables i, j.
for (let i = 1; i <= rows; i++) — ascending outer loop; one right-aligned row per iteration.
for (let j = rows; j >= 1; j--) — append space if j > i, else append j.
console.log(line) ends the row after the inner loop finishes.
Leading spaces shrink each row — O(n²) time, O(1) extra memory.
rows = 5Trace each outer-loop value of i, leading-space count, digit range, and full row output.
i | Leading spaces | Digits printed | Row output |
|---|---|---|---|
1 | 4 | 1 | 1 |
2 | 3 | 2, 1 | 21 |
3 | 2 | 3, 2, 1 | 321 |
4 | 1 | 4, 3, 2, 1 | 4321 |
5 | 0 | 5, 4, 3, 2, 1 | 54321 |
Leading spaces per row = rows - i — zero when i = rows.
Where this tiny pattern (and its loop structure) shows up beyond the homework prompt.
Clearest visual proof that outer and inner bounds interact.
Example: flip j > i to j <= i for spaces and watch alignment break.
Foundation for inverted, pyramid, diamond, and hollow variants.
Example: continue to Program 31 for a number-star diamond pattern.
Practice print vs row newline without complex math.
Example: put console.log(line) inside the inner loop by mistake.
Add spaces between digits once the two-loop structure works.
Example: use line += j + " " between digits for wider spacing.
Triangular totals make O(n²) concrete for beginners.
Example: count printed characters for rows = 5 — each row prints exactly rows characters.
Pair the pattern with Number.isFinite checks and positive-row checks.
Example: reject max <= 0 and re-prompt.
Pro Tip: when an interviewer asks for patterns, explain the outer/inner roles first — then write the loops. The story matters as much as the code.
Why this pattern earns a permanent spot in beginner C courses.
Wrong bounds show up immediately as a broken staircase.
Only loops and console output — no arrays or math libraries.
Invert, center, hollow, or change the fill character with small edits.
Streaming output needs no storage beyond loop counters.
Pro Tip: trace i and j on paper for rows = 3 before coding — watch how leading spaces shrink each row.
Small habits that keep number-pattern code clean.
Inner loop must always run rows times — spaces pad the left side.
Number.isFiniteUse Number.isFinite so bad input does not produce NaN when converting rows.
Only call console.log(line) after the inner loop finishes the row.
Mark which positions print spaces vs digits for each row before coding.
Trace i = 1..3 on paper before coding the full rows = 5 demo.
Pro Tip: if the output is a vertical list of single digits per line, you almost certainly put console.log(line) inside the inner loop.
Mistakes that commonly break right-aligned descending triangles.
Each digit lands on its own line — you get a column, not a triangle.
→ Use line += j or line += " "; console.log(line) only after the inner loop.
Using j <= i for spaces (instead of j > i) inverts which positions print digits.
→ Print space when j > i; print digit otherwise.
for (let j = 1; j <= rows; j++) appends ascending digits — not the descending order this pattern needs.
→ Keep for (let j = rows; j >= 1; j--) so digits read i..1.
Running the inner loop only to i removes leading spaces — output becomes left-aligned.
→ Inner loop must always run from rows down to 1.
parseInt(prompt())Letters or empty input yield NaN with bare parseInt(prompt(), 10).
→ Validate with Number.isFinite and re-prompt on failure.
Check these inputs before calling the solution done.
Output is 1 (with rows - 1 leading spaces).
Outer loop never runs — print nothing or show a message.
rows < 0Treat as invalid; re-prompt instead of silent empty output.
Two rows: 1 and 21.
Bare parseInt(prompt(), 10) yields NaN on bad input — use Number.isFinite first.
Each row prints exactly rows characters — total work grows as n².
Try these variations to lock in the pattern.
rows >= 1 after reading inputj > i; print digit j otherwise. Inner loop always runs rows times.line += builds the row; console.log(line) ends it — mix them carefully.rows > 0 for interactive programs; rows = 1 prints one digit with rows - 1 leading spaces.rows - i — compare with Program 3 where there are no leading spaces.Quick Takeaway: outer loop i = 1..rows, inner line += (j > i) ? " " : j, then console.log(line).
| Program | Time | Extra space |
|---|---|---|
| Nested loops (Examples 1–3) | O(n²) | O(1) |
| Smaller demo (Example 3) | O(n²) | O(1) |
The right-aligned descending number triangle is a compact lesson in fixed-width loops and leading-space padding: print spaces while j > i, then print digits in descending order, and end each row with console.log(line). Master the fixed-rows version, then try user input and a smaller trace demo.
Practice the three examples above, then continue to Program 31 for the number-star diamond pattern.
Inner loop must always use rows as the width — validate rows when reading from the console.
for (let i = 1; i <= rows; i++) in the outer loopif (j > i) print space, else append jrowsparseInt(prompt(), 10) with Number.isFiniteconsole.log(line) inside the inner looprowsj <= i for spaces)rows = 1 edge casePrint the pattern the beginner-friendly way.
j>i spaces, else j
Definitionj = rows..1
Coderows - i per row
CodePrint i..1
ShapeO(n²) time
AnalysisThis pattern uses a fixed column width (rows). For each row i, the inner loop appends spaces while j > i, then appends digits in descending order — producing a right-aligned triangle.
Move on to the number-star diamond pattern in the JavaScript number-pattern series.
12 people found this page helpful