S3Q2 · Format Tic-Tac-Toe Board¶
⚡ Quick Reference
Type: Full I/O -formatted grid output
Core idea: build the horizontal separator once, then for each row pad to width n and wrap each cell in |.
m, n = map(int, input().split())
sep = ("+-" * n) + "+"
for _ in range(m):
row = input().ljust(n)[:n] # pad/trim to exactly n chars
print(sep)
print("|" + "|".join(row) + "|")
print(sep)
Key rules:
- Horizontal line: +- repeated n times, then +
- Row: | + each character joined by | + |
- Pad short rows with spaces to exactly n characters
- Print separator before every row and once more at the bottom
Problem Statement¶
Problem (I/O type)
Read an m × n tic-tac-toe board and print it with +, -, | borders. Each cell is separated by | vertically and +- horizontally.
Example:
3 4
O XO
XO
O X
+-+-+-+-+
|O| |X|O|
+-+-+-+-+
|X|O| | |
+-+-+-+-+
|O| |X| |
+-+-+-+-+
Deriving the patterns¶
Horizontal separator for n=4:
A row with n=4 cells:
"|".join("O XO") treats the string as an iterable of characters and puts | between each one. Then wrapping with leading and trailing | completes the row.
str.ljust(n) for padding
If a row string is shorter than n, row.ljust(n) right-pads it with spaces to length n. This ensures every row has exactly n cells. For example "XO".ljust(4) → "XO ".
Tracing the example¶
m=3, n=4, sep = "+-+-+-+-+"
| Step | Output |
|---|---|
| print sep | +-+-+-+-+ |
row "O XO" → "O XO" |
\|O\| \|X\|O\| |
| print sep | +-+-+-+-+ |
row "XO" → "XO " (padded) |
\|X\|O\| \| \| |
| print sep | +-+-+-+-+ |
row "O X" → "O X" |
\|O\| \| \|X\| |
| print sep | +-+-+-+-+ |
Solution approaches¶
m, n = map(int, input().split())
sep = "+-" * n + "+"
for _ in range(m):
row = input().ljust(n)[:n]
print(sep)
print("|" + "|".join(row) + "|")
print(sep)
ljust(n)[:n] pads short rows and trims any accidentally longer ones. Clean and handles edge cases automatically.
m, n = map(int, input().split())
# Build separator line
sep = ""
for _ in range(n):
sep += "+-"
sep += "+"
for _ in range(m):
row = input()
# Pad to exactly n characters
row = row + " " * (n - len(row))
row = row[:n]
print(sep)
# Build the cell row
cell_row = "|"
for char in row:
cell_row += char + "|"
print(cell_row)
print(sep)
Every step built explicitly -separator construction, padding, and cell row assembly all visible.
m, n = map(int, input().split())
sep = "+" + "-+" * n # alternative: "+" + "+".join(["-"] * n) + "+"
for _ in range(m):
row = input().ljust(n)[:n]
print(sep)
print("|" + "|".join(row) + "|")
print(sep)
"+" + "-+" * n is equivalent to "+-" * n + "+". Both produce the same string.
m, n = map(int, input().split())
sep = "+-" * n + "+"
rows = [input().ljust(n)[:n] for _ in range(m)]
formatted = list(map(lambda row: "|" + "|".join(row) + "|", rows))
print(("\n" + sep + "\n").join([sep] + formatted) + "\n" + sep)
map(lambda row: ..., rows) formats each row. The separator is then woven between rows using join. All output assembled in one expression.
Key takeaways¶
"+-" * n + "+" for the separator
String multiplication builds repeated patterns cleanly. "+-" * n + "+" produces the correct separator for any width n without a loop.
"|".join(row) for cell formatting
A string is iterable -"|".join("OXO") → "O|X|O". Wrapping with leading and trailing | completes the row format.
str.ljust(n) to normalise row length
Input rows may be shorter than n if they end in spaces (which terminals may strip). ljust(n) right-pads with spaces, ensuring every row has exactly n characters.