Python Number Pattern (Decreasing then Increasing)
Beginner
5 min read
Updated: Sep 2026
3 programs
Live preview
Definition
What Is This Pattern?
A mixed number triangle builds each row from two halves: descending i..2, then ascending 1..(rows - i + 1). Every row has exactly rows digits — with rows = 5 you get 12345, 21234, 32123, 43212, 54321.
Unlike Program 49 (products i*j), this shape concatenates digit sequences — no multiplication.
Approach
How to Solve It
Outer loop picks row i. Two inner loops fill the descending half, then the ascending half.
Method
Idea
Best for
Two inner loops
Descending j = i..2, then ascending k = 1..(rows-i+1)
Learning, interviews, demos
Compact trace
Same logic with rows = 3
Quick dry-runs on paper
Pseudocode
Pseudocode
for i from 1 to rows:
for j from i down to 2:
print j (no newline)
for k from 1 to (rows - i + 1):
print k (no newline)
print newline
Cheat sheet
Goal
Pattern
Outer rows
for i in range(1, rows + 1):
Descending half
for j in range(i, 1, -1): print(j, end="")
Ascending half
for k in range(1, rows + 2 - i): print(k, end="")
End the row
print()
Digits per row
Always rows
Printing Numbers vs Starting a New Line
API
Effect
Use for
print(j, end="") / print(k, end="")
Stays on the same line
Each digit
print()
Ends the current line
After both inner loops
Print digits without a newline, then end the row once. Putting bare print() inside either inner loop turns the pattern into a vertical list.
Try it
Live Preview
Change the row count and the mixed triangle updates instantly.
Use rows from 1 to 9 (single digits stay tidy). Tap a chip or type a value — the preview redraws as you go.
Live result5 rows · 25 digits
12345
21234
32123
43212
54321
Trace
Worked Walkthrough
Trace row i = 3 with rows = 5 — descending then ascending.
Half
Loop
Prints
Line so far
Descending
j = 3, 2
3, 2
32
Ascending
k = 1..(5-3+1) = 1..3
1, 2, 3
32123
When i = 1, the descending loop never runs — the whole row is just 1..rows. When i = rows, the ascending loop prints only 1, so the row is rows..(2)1.
Code
Python Programs
Three complete programs: fixed rows = 5, input() rows, and a compact rows = 3 demo. Use View Output to reveal sample results.
Example 1 — Fixed rows = 5
Hard-coded height — descending half, then ascending half, on every row.
Python
rows = 5
for i in range(1, rows + 1):
for j in range(i, 1, -1):
print(j, end="")
for k in range(1, rows + 2 - i):
print(k, end="")
print()
Output
12345
21234
32123
43212
54321
How It Works
1. Outer loop picks the row.i runs from 1 to 5 — one full line per value.
2. Descending half first.range(i, 1, -1) prints i..2 (skipped when i = 1).
3. Ascending half fills the rest.k runs from 1 to rows + 1 - i, then bare print() ends the row.
Example 2 — User Input Rows
Read the row count at runtime — both halves scale automatically.
Python
try:
rows = int(input("Enter the number of rows: "))
except ValueError:
print("Please enter a positive integer.")
raise SystemExit(1)
if rows < 1:
print("Please enter a positive integer.")
raise SystemExit(1)
for i in range(1, rows + 1):
for j in range(i, 1, -1):
print(j, end="")
for k in range(1, rows + 2 - i):
print(k, end="")
print()
Output (when user enters 4)
Enter the number of rows: 4
1234
2123
3212
4321
How It Works
1. Same two-loop core. Only the source of rows changes from a literal to input().
2. Width follows rows. Entering 4 yields four digits on every line.
3. Safer input tip. Cap demos for readable output:
Safer input tip
if rows < 1 or rows > 9:
print("Enter a whole number from 1 to 9.")
raise SystemExit(1)
Example 3 — Compact rows = 3
Smaller height for quick tracing on paper or in interviews.
Python
rows = 3
for i in range(1, rows + 1):
for j in range(i, 1, -1):
print(j, end="")
for k in range(1, rows + 2 - i):
print(k, end="")
print()
Output
123
212
321
How It Works
1. Only three rows. Easy to dry-run every descending and ascending step by hand.
2. Same formula. Nothing changes except rows — proving the pattern scales.
3. Last row is fully descending. Row 3 prints 321 — 3 2 then 1.
Edge Cases & Pitfalls
Check these before calling the solution done.
Descending bound
Stop at 2, not at 1
Use range(i, 1, -1). Going down to 1 duplicates the leading 1 from the ascending half.
Ascending length
Use rows + 1 - i
Wrong bounds break the fixed width of rows digits per line. In Python that is range(1, rows + 2 - i).
Newline
Do not put print() inside either inner loop
Call bare print() only after both halves finish.
Between loops
No break between halves
Run both inner loops back-to-back. A newline between them splits each row in half.
rows = 1
Single value
Output is just 1. A good sanity check for input validation.
input()
Catch ValueError
Bare int(input()) crashes on non-numeric text — wrap it in try/except ValueError.
Analysis
Time and Space Complexity
Program
Time
Extra space
Nested loops (Examples 1–3)
O(n²)
O(1)
Each of n rows prints exactly n digits, so total work is n². Only a few integers of extra memory.
Remember
Key Takeaways
Rule: print i..2, then 1..(rows - i + 1).
Fixed width: every row has exactly rows digits.
Break the row: call bare print() only after both inner loops.
Complexity:O(n²) time; O(1) extra space.
One line: for each row i, print descending i..2 then ascending 1..(rows-i+1), then end the line.
Frequently Asked Questions
Each row prints two parts: first a descending sequence from i down to 2, then an ascending sequence from 1 up to (rows - i + 1). Row 2 becomes 2 + 1234 = 21234.
One inner loop prints the descending part (j = i down to > 1). The other prints the ascending part (k = 1..(rows-i+1)). Splitting them keeps the two halves clear.
When i = 1, the descending loop j = i; j > 1 never runs. Only the ascending loop prints 1..rows.
Program 49 prints i*j products on each row. Program 50 concatenates digit sequences — descending then ascending — with no multiplication.
Printing a digit with end="" stays on the same line. Bare print() ends the current row. Digits use end=""; the row break uses print() after both inner loops.
O(n²) for n rows because each row prints n digits and there are n rows.
for j in range(i, 1, -1) prints i..2 — the same as a countdown that stops before 1.
Use try/except ValueError around int(input()) and require rows >= 1 — see Example 2.
🤔
Did you know?
Each row combines two sequences: descending i..2, then ascending 1..(rows-i+1). Every row has exactly rows digits — total prints = n², time O(n²).