S3Q2 · Dual Pattern Printing¶
⚡ Quick Reference
Type: Full I/O - two patterns separated by a blank line
n = int(input())
# Pattern 1 - symmetric concatenation
for i in range(1, n + 1):
print("".join(str(j) for j in range(1, i + 1)))
for i in range(n - 1, 0, -1):
print("".join(str(j) for j in range(1, i + 1)))
print() # blank line
# Pattern 2 - triangular sequential numbers
num = 1
for i in range(1, n + 1):
print(" ".join(str(num + j) for j in range(i)))
num += i
Key rules:
- Pattern 1: rows go 1 → n → 1, each row concatenates digits 1..i with no spaces
- Pattern 2: rows have 1, 2, 3, … n numbers; numbers increase sequentially across rows
- Blank line between the two patterns
- No trailing spaces in Pattern 2
Problem Statement¶
Problem (I/O type)
Read n. Print two patterns separated by a blank line:
1. Symmetric concatenation pattern (ascending then descending)
2. Triangular sequential number pattern
Example - n = 4:
4
1
12
123
1234
123
12
1
1
2 3
4 5 6
7 8 9 10
Pattern 1 - Symmetric Concatenation¶
Each row i concatenates digits 1, 2, …, i with no spaces. The pattern goes up to n, then back down to 1:
for i in range(1, n + 1):
print("".join(str(j) for j in range(1, i + 1)))
for i in range(n - 1, 0, -1): # n-1 down to 1
print("".join(str(j) for j in range(1, i + 1)))
Total rows: 2n - 1 (n going up, n-1 going down).
Pattern 2 - Triangular Sequential Numbers¶
Row i contains i numbers, continuing from where the previous row left off:
Track a running counter num:
After row i, num advances by i - next row starts at the right value.
Tracing n = 4¶
Pattern 1:
i |
Output |
|---|---|
| 1 | 1 |
| 2 | 12 |
| 3 | 123 |
| 4 | 1234 |
| 3 | 123 |
| 2 | 12 |
| 1 | 1 |
Pattern 2 (num tracker):
i |
num before |
Numbers | num after |
|---|---|---|---|
| 1 | 1 | 1 |
2 |
| 2 | 2 | 2 3 |
4 |
| 3 | 4 | 4 5 6 |
7 |
| 4 | 7 | 7 8 9 10 |
11 |
Solution approaches¶
n = int(input())
# Pattern 1 - ascending
for i in range(1, n + 1):
row = ""
for j in range(1, i + 1):
row += str(j)
print(row)
# Pattern 1 - descending
for i in range(n - 1, 0, -1):
row = ""
for j in range(1, i + 1):
row += str(j)
print(row)
print() # blank line
# Pattern 2
num = 1
for i in range(1, n + 1):
row = []
for _ in range(i):
row.append(str(num))
num += 1
print(" ".join(row))
def concat_row(i):
return "".join(str(j) for j in range(1, i + 1))
n = int(input())
# Pattern 1
rows = [concat_row(i) for i in range(1, n + 1)]
print("\n".join(rows + rows[-2::-1]))
print()
# Pattern 2
num = 1
for i in range(1, n + 1):
end = num + i
print(" ".join(map(str, range(num, end))))
num = end
rows[-2::-1] reverses the list starting from the second-to-last element - elegant way to get the descending half without the peak row being duplicated.
Key takeaways¶
Two loops for the symmetric pattern
The ascending half uses range(1, n+1); the descending half uses range(n-1, 0, -1). The peak row (n) appears only once - the descending loop starts at n-1.
Running counter for sequential numbers
Track num and advance it by i after each row. range(num, num+i) generates exactly i sequential numbers starting from num.
print() for a blank line
print() with no arguments prints an empty line - the separator between the two patterns. Cleaner than print("").