S3Q2 · Hollow Square Ring Pattern¶
⚡ Quick Reference
Type: Full I/O problem
Core idea: Three row types -- top border, middle (border only), bottom border. Middle rows end with # so no trailing spaces.
n = int(input())
for i in range(n):
if i == 0 or i == n - 1:
print('#' * n)
else:
print('#' + ' ' * (n - 2) + '#')
Key rules:
- Row 0 and row n-1: # × n
- Every middle row: # + (n-2) spaces + #
- No trailing spaces -- middle rows end with #, not a space
Problem Statement¶
Problem
Given n, print an n × n hollow square using #. Only the border is filled; interior cells are spaces. No trailing spaces after the last # on any row. n >= 2 always.
Examples:
4
####
# #
# #
####
5
#####
# #
# #
# #
#####
2
##
##
Understanding the problem¶
Every row falls into one of three types:
| Row | Condition | Content |
|---|---|---|
| Top | i == 0 |
# × n |
| Middle | 0 < i < n-1 |
# + (n-2) spaces + # |
| Bottom | i == n-1 |
# × n |
For n = 4, that gives:
No trailing spaces because middle rows end with #
The hollow middle row is '#' + ' ' * (n-2) + '#'. The rightmost character is always #, so there is nothing to strip. A naive approach of building an n-wide string with spaces and replacing corners can leave trailing spaces -- building the string directly avoids this.
n = 2 edge case
When n = 2 there are no middle rows (rows 1 to n-2 is an empty range). Both rows 0 and 1 are border rows, so the output is just two ## lines. The loop handles this automatically without any special case.
Solution approaches¶
Key takeaways¶
Three-type row classification
Pattern printing usually reduces to classifying each row. Here the three types are: top border, middle (hollow), bottom border. The condition i == 0 or i == n-1 handles both borders in one branch.
Build strings directly to avoid trailing spaces
Constructing the middle row as '#' + ' '*(n-2) + '#' guarantees no trailing spaces. Avoid building an all-space string and then replacing positions -- that leaves spaces at the end if you forget to strip.
Precompute repeated strings
The Pythonic approach builds border and middle once, then assembles the full list with [border] + [middle]*(n-2) + [border]. Cleaner than computing the same string in every loop iteration.