Skip to content

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:

Input
3 4
O XO
XO
O  X
Output
+-+-+-+-+
|O| |X|O|
+-+-+-+-+
|X|O| | |
+-+-+-+-+
|O| |X| |
+-+-+-+-+

Deriving the patterns

Horizontal separator for n=4:

+ - + - + - + - +
= "+-" * 4 + "+"
= "+-+-+-+-+"

A row with n=4 cells:

| O | _ | X | O |       (_ = space)
= "|" + "|".join("O XO") + "|"
= "|O| |X|O|"

"|".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

01

"+-" * n + "+" for the separator

String multiplication builds repeated patterns cleanly. "+-" * n + "+" produces the correct separator for any width n without a loop.

02

"|".join(row) for cell formatting

A string is iterable -"|".join("OXO")"O|X|O". Wrapping with leading and trailing | completes the row format.

03

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.