Katkat

Render Wrapped Paragraphs Inside One Text Box

AirbnbSoftware Engineer · Onsite

Last updated

Implement a text formatting utility that wraps multiple paragraphs at distinct per-paragraph widths and renders them inside a single, uniformly padded ASCII border box.

Problem Statement

You are building a terminal rendering utility for a CLI dashboard. You are given a list of paragraphs, where each paragraph is represented by a pair (text, wrap_width): the raw paragraph string and the maximum line width for that specific paragraph.

Your task is to:

  1. Wrap each paragraph greedily such that no line exceeds its assigned wrap_width. Words within a line must be separated by a single space, and no word may be split across lines.
  2. Determine the box's inner width W, which is the maximum wrap_width across all provided paragraphs.
  3. Render all wrapped lines inside a single ASCII box in top-to-bottom order:
    • Top border: + followed by W + 2 dashes (-), followed by +.
    • Each line of text: | followed by the wrapped text left-aligned and right-padded with spaces to length W, followed by |.
    • Bottom border: identical to the top border.

Return the rendered box as a list of strings, where each string represents one row.

Function Signature

def render_text_box(paragraphs: list[tuple[str, int]]) -> list[str]:
    pass

Constraints

  • 1 <= len(paragraphs) <= 100
  • 1 <= wrap_width <= 200 for each paragraph
  • text contains non-empty ASCII words separated by one or more spaces
  • Every word in a paragraph is guaranteed to have a length <= wrap_width of that paragraph
  • If a paragraph contains only whitespace, it contributes zero lines to the box interior

Examples

Example 1

paragraphs = [
    ("Hello world from Airbnb", 12),
    ("Enjoy your stay in our cozy apartment", 16)
]
render_text_box(paragraphs)

Output:

[
    "+------------------+",
    "| Hello world      |",
    "| from Airbnb      |",
    "| Enjoy your stay  |",
    "| in our cozy      |",
    "| apartment        |",
    "+------------------+"
]

Explanation:

  • Paragraph 1 wraps at width 12: ["Hello world", "from Airbnb"].
  • Paragraph 2 wraps at width 16: ["Enjoy your stay", "in our cozy", "apartment"].
  • Max width W = max(12, 16) = 16.
  • The top/bottom borders have 16 + 2 = 18 dashes.
  • Every interior line is padded with spaces up to length 16 and surrounded by "| " and " |".

Example 2

paragraphs = [
    ("A quick brown fox", 10)
]
render_text_box(paragraphs)

Output:

[
    "+------------+",
    "| A quick    |",
    "| brown fox  |",
    "+------------+"
]

Explanation:

  • W = 10. Borders have 12 dashes. Lines are wrapped within 10 characters and padded to 10 characters.

Hints

Hint 1

Break the problem down into two distinct phases: first wrap each paragraph into a flat list of lines, then format those lines into the ASCII box.

Hint 2

For word-wrapping, split each paragraph text by whitespace and greedily append words to the current line as long as `current_line_length + 1 + len(word) <= wrap_width`.

Hint 3

Calculate the interior width as the maximum requested `wrap_width` across all paragraphs, and use standard string formatting (like `ljust`) to pad each rendered line to this width.

Follow-up questions

  • How would you handle a word whose length exceeds its paragraph's wrap width (e.g., breaking by hyphenation)?
  • How would you support full justification (distributing extra spaces evenly between words) instead of left justification for non-terminal lines?
  • If the content is streaming and too large to fit in memory, how would you design this with a generator or fixed-memory pipeline?