Skip to content

S3Q2 · Hollow X Pattern

⚡ Quick Reference

Type: Full I/O problem

Core idea: At row i, the main diagonal star is at column i and the secondary diagonal star is at column n-1-i. If they coincide, print one *; otherwise print both with spaces between.

n = int(input())
for i in range(n):
    main = i
    sec  = n - 1 - i
    if main == sec:
        print(' ' * main + '*')
    else:
        left, right = min(main, sec), max(main, sec)
        print(' ' * left + '*' + ' ' * (right - left - 1) + '*')

Key rules: - Main diagonal: column = i (row index) - Secondary diagonal: column = n - 1 - i - Diagonals meet when i == n - 1 - i, i.e. the middle row of an odd n - Interior spaces = right - left - 1 - No trailing spaces -- rows always end with *


Problem Statement

Problem

Given n >= 3, print an n × n hollow X pattern. A * appears on the main diagonal (col = row) and the secondary diagonal (col = n-1-row). Where both diagonals meet, print a single *. No trailing spaces.

Examples:

Input
5
Output
*   *
 * *
  *
 * *
*   *
Input
7
Output
*     *
 *   *
  * *
   *
  * *
 *   *
*     *

Understanding the problem

For each row i, compute which columns get a *:

Row i Main col (i) Sec col (n-1-i) Same? Line (n=5)
0 0 4 no * *
1 1 3 no * *
2 2 2 ✅ *
3 3 1 no * *
4 4 0 no * *

For rows where the two columns differ, left = min(main, sec) and right = max(main, sec). The line is: - left leading spaces - * - right - left - 1 interior spaces - *

min/max handle both halves of the X uniformly

In the top half, main < sec (left star from main diagonal, right from secondary). In the bottom half it flips. Using min and max to assign left and right covers both halves without a separate condition.

No trailing spaces because rows always end with *

Whether it's a single-star row or a two-star row, the last character printed is always *. No .rstrip() needed.


Solution approaches

n = int(input())
for i in range(n):
    main = i          # column of main diagonal star
    sec  = n - 1 - i  # column of secondary diagonal star

    if main == sec:
        # diagonals meet at the centre -- single star
        print(' ' * main + '*')
    else:
        # two stars; left is closer to column 0
        left  = min(main, sec)
        right = max(main, sec)
        interior = right - left - 1       # spaces between the two stars
        print(' ' * left + '*' + ' ' * interior + '*')
n = int(input())
def row(i):
    m, s = i, n - 1 - i
    if m == s: return ' ' * m + '*'
    l, r = min(m, s), max(m, s)
    return ' ' * l + '*' + ' ' * (r - l - 1) + '*'
print('\n'.join(row(i) for i in range(n)))
n = int(input())
row = lambda i: (
    ' '*i+'*' if i == n-1-i
    else (lambda l,r: ' '*l+'*'+' '*(r-l-1)+'*')(min(i,n-1-i), max(i,n-1-i))
)
print('\n'.join(row(i) for i in range(n)))

Key takeaways

01

Diagonal columns from the row index

In an n×n grid, the main diagonal is always at column = row (i), and the secondary diagonal is at column = n-1-i. These two formulas are the foundation of almost every X or diamond pattern problem.

02

Use min/max instead of top/bottom halves

Rather than separate logic for rows above and below the centre, left = min(main, sec) and right = max(main, sec) always assign the correct positions regardless of which half the row is in.

03

Interior spaces = right - left - 1

The number of spaces between two stars at column positions left and right is right - left - 1. This is a general formula: distance between positions minus the two stars themselves.