A right-angled triangle star pattern prints a left-aligned staircase of * characters: row i has exactly i stars.
Remember
Rule: on row i, print i stars
*
**
***
****
***** ← 5 rows
In JavaScript you solve it with two nested for loops: the outer loop picks the row, the inner loop appends stars with line += "*", then console.log(line) moves to the next line. Once this clicks, inverted triangles, pyramids, and hollow shapes become much easier.
Approach
How to Solve It
Two ways to emit the same shape — start with nested loops, then optionally shorten with "*".repeat(i).
Method
Idea
Best for
Nested loops
Outer = rows, inner builds line with += "*"
Learning, interviews, exams
"*".repeat(i)
Build a whole row in one call
Shorter demos once loops click
Pseudocode
Pseudocode
for i from 1 to rows:
line = ""
for j from 1 to i:
line += "*"
print line (with newline)
Change the row count and the triangle updates instantly — including the triangular star total.
Whole numbers from 1 to 20. Tap a chip or type a value — the preview redraws as you go.
Live result5 rows · 15 stars
*
**
***
****
*****
Trace
Worked Walkthrough — rows = 4
Trace each outer-loop value of i and count how many times the inner loop runs.
i
Inner j
Printed row
Stars
1
1..1
*
1
2
1..2
**
2
3
1..3
***
3
4
1..4
****
4
Total star characters: 1 + 2 + 3 + 4 = 10 = 4×5/2. That triangular sum is why time is O(n²).
Code
JavaScript Programs
Three complete programs: fixed rows, prompt input, and a "*".repeat(i) shortcut. Use View Output to reveal sample results.
Example 1 — Fixed rows = 5
Hard-coded height — ideal for first demos and screenshots.
JavaScript
let rows = 5;
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = 1; j <= i; j++) {
line += "*";
}
console.log(line);
}
Output
*
**
***
****
*****
How It Works
1. Set height.rows = 5 means the triangle has five lines.
2. Outer loop picks the row.i runs from 1 to rows. Start each row with an empty line.
3. Inner loop appends stars. For each i, j runs from 1 to i, so row i gets exactly i stars via line += "*".
4. Break the line.console.log(line) after the inner loop prints the row and starts the next one.
When i = 1 you get *; when i = 2 you get **; and so on up to five stars.
Example 2 — User Input Version
Read the row count at runtime with prompt. Validate with parseInt in real apps (shown below).
JavaScript
let rows = parseInt(prompt("Enter the number of rows:"), 10);
if (!Number.isFinite(rows) || rows < 1) {
console.log("Please enter a whole number of rows >= 1.");
} else {
for (let i = 1; i <= rows; i++) {
let line = "";
for (let j = 1; j <= i; j++) {
line += "*";
}
console.log(line);
}
}
Output (when user enters 7)
*
**
***
****
*****
******
*******
How It Works
1. Prompt and parse. Ask for a row count, then convert with parseInt(..., 10).
2. Validate first. Reject NaN or non-positive values before looping.
3. Same nested-loop core. Only the source of rows changes — the print logic matches Example 1.
Example 3 — "*".repeat(i)
Build each row in one call — same shape, no explicit inner star loop.
JavaScript
let rows = 5;
for (let i = 1; i <= rows; i++) {
console.log("*".repeat(i));
}
Output
*
**
***
****
*****
How It Works
1. One outer loop. Still walk i from 1 to rows.
2. Build the row."*".repeat(i) creates a string of length i filled with stars.
3. Print and advance.console.log prints that string and ends the line.
Learn the two-loop version first (Examples 1–2) so you can explain both bounds in an interview; treat this as a polish shortcut afterward.
Edge Cases & Pitfalls
Check these before calling the solution done.
log inside
Column of stars
If console.log is inside the inner loop, each star lands on its own line. Append with +=; call console.log only after the inner loop.
j <= rows
Rectangle, not triangle
Inner bound must be j <= i. j <= rows prints a filled rectangle.
No console.log
Nothing visible
Building line without logging it means you never see output. Always console.log(line) after the inner loop.
Reuse line
Growing leftovers
Reset line = "" at the start of each outer iteration, or stars from previous rows stick around.
rows = 1
Single star
Output is just * on one line — a good sanity check.
NaN input
Validate parseInt
Letters or empty prompt yield NaN — check Number.isFinite(rows) && rows >= 1.
Analysis
Time and Space Complexity
Program
Time
Extra space
Nested loops (Examples 1–2)
O(rows²)
O(rows) for the current line string
"*".repeat(i) (Example 3)
O(rows²)
O(rows) per temporary row string
Total stars printed = 1 + 2 + … + n = n(n+1)/2, which is still quadratic in n.
Remember
Key Takeaways
Rule: row i prints exactly i stars.
Two loops: outer = rows, inner appends with line += "*".
Break the row: call console.log(line) only after the inner loop.
Complexity:O(n²) time from the triangular star count.
One line: for each row i, append i stars, then console.log.
Frequently Asked Questions
The outer loop runs i from 1 to rows. For each row i, the inner loop runs j from 1 to i and appends a star to the line. Row 1 prints 1 star, row 2 prints 2 stars, and so on.
You need one loop for which row you are on and another for how many characters belong on that row. Nested for loops express that directly.
line += "*" stays on the same row with no newline between stars. console.log(line) ends the row after the inner loop finishes.
Reverse the outer loop so i runs from rows down to 1, for example for (let i = rows; i >= 1; i--). The first line then has rows stars. See Program 2.
O(n²) where n is the number of rows. Total star characters equal 1+2+…+n = n(n+1)/2.
Yes. console.log("*".repeat(i)) prints a full row in one call. Nested loops are better for learning; "*".repeat(i) is a handy shortcut later.
Use parseInt(prompt(...), 10) and check Number.isFinite(rows) && rows >= 1 so bad input does not produce NaN rows.
The outer loop never runs, so nothing is printed. Validate and prompt again if you want a clear user message.
🤔
Did you know?
Row i prints exactly i stars. Total stars for n rows is the triangular number n(n+1)/2 — the same count that makes this pattern O(n²).