Skip to content

S3Q2 · Numeric Palindrome Hourglass

⚡ Quick Reference

Type: Full I/O - pattern printing

Core idea: build each row as a palindrome 1..k..1, center it with n-k leading spaces.

n = int(input())

def make_row(k):
    nums = list(range(1, k + 1)) + list(range(k - 1, 0, -1))
    return " " * (n - k) + " ".join(map(str, nums))

for k in range(n, 0, -1):      # top half: n down to 1
    print(make_row(k))
for k in range(2, n + 1):      # bottom half: 2 up to n
    print(make_row(k))

Key rules: - Row k palindrome: 1 2 ... k ... 2 1 (length 2k-1 numbers) - Leading spaces = n - k (widest row has 0 padding) - Top half: k = n, n-1, ..., 1 - Bottom half: k = 2, 3, ..., n (mirrors top, excludes middle) - Total rows: 2n - 1


Problem Statement

Problem (I/O type)

Read n. Print a numeric palindrome hourglass with 2n-1 rows. Top half narrows from k=n to k=1; bottom half widens from k=2 to k=n.

Example - n = 3:

Input
3
Output
1 2 3 2 1
  1 2 1
    1
  1 2 1
1 2 3 2 1

Deriving the pattern

Each row with parameter k has: - Content: numbers 1, 2, ..., k, ..., 2, 1 - a palindrome of 2k-1 numbers - Width: 2k-1 characters (spaces between numbers) - Leading spaces: n - k (to center within the widest row of width 2n-1)

n=3, k=3: spaces=0, row = "1 2 3 2 1"
n=3, k=2: spaces=1, row = "  1 2 1"     (1 leading space)
n=3, k=1: spaces=2, row = "    1"        (2 leading spaces)

Hourglass structure:

Top half:    k = n → n-1 → ... → 1    (narrows downward)
Bottom half: k = 2 → 3  → ... → n    (widens downward, skips k=1)


Tracing n = 4

k Leading spaces Row content
4 0 1 2 3 4 3 2 1
3 1 · 1 2 3 2 1
2 2 · · 1 2 1
1 3 · · · 1 ← middle
2 2 · · 1 2 1
3 1 · 1 2 3 2 1
4 0 1 2 3 4 3 2 1

Total: 2×4 - 1 = 7 rows ✓


Solution approaches

n = int(input())

def make_row(k):
    nums = list(range(1, k + 1)) + list(range(k - 1, 0, -1))
    return " " * (n - k) + " ".join(map(str, nums))

for k in range(n, 0, -1):
    print(make_row(k))
for k in range(2, n + 1):
    print(make_row(k))
n = int(input())

def make_row(k):
    # Build palindrome list: [1, 2, ..., k, ..., 2, 1]
    ascending  = list(range(1, k + 1))
    descending = list(range(k - 1, 0, -1))
    nums = ascending + descending

    # Center with leading spaces
    padding = " " * (n - k)
    return padding + " ".join(str(x) for x in nums)

# Top half: widest to narrowest
for k in range(n, 0, -1):
    print(make_row(k))

# Bottom half: second narrowest to widest (skip k=1)
for k in range(2, n + 1):
    print(make_row(k))
n = int(input())
max_width = 2 * (2 * n - 1) - 1   # max chars including spaces between

def make_row(k):
    nums = list(range(1, k + 1)) + list(range(k - 1, 0, -1))
    row  = " ".join(map(str, nums))
    return row.rjust(len(row) + (n - k))   # right-pad equivalent

for k in range(n, 0, -1):
    print(make_row(k))
for k in range(2, n + 1):
    print(make_row(k))
n = int(input())
make_row = lambda k: (
    " " * (n - k) +
    " ".join(map(str, list(range(1, k+1)) + list(range(k-1, 0, -1))))
)
rows = list(range(n, 0, -1)) + list(range(2, n + 1))
print("\n".join(map(make_row, rows)))

Lambda builds each row; the rows list defines the hourglass order. "\n".join(map(...)) prints all in one call.


Key takeaways

01

Palindrome row: range(1,k+1) + range(k-1,0,-1)

Concatenating ascending and descending ranges builds the palindrome without repeating the peak. range(k-1, 0, -1) starts just below the peak and goes down to 1.

02

Leading spaces = n - k

The widest row (k=n) needs 0 spaces; the narrowest (k=1) needs n-1 spaces. The formula n - k gives the correct padding for any row.

03

Bottom half skips k=1 (middle row)

The bottom loop starts at k=2, not k=1. The middle row (k=1) is printed once by the top half. Starting the bottom at k=2 avoids duplicating it.