Render Overlapping Rectangles on an ASCII Canvas
Company: Amperity
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Onsite
# Render Overlapping Rectangles on an ASCII Canvas
Implement `render_canvas(width, height, rectangles)`. The canvas initially contains spaces and is returned as a list of `height` strings, each of length `width`.
Each rectangle is `(x, y, w, h, border_char, fill_char)`, where `(x, y)` is its upper-left corner, `w` is its width, and `h` is its height. Draw the outermost cells with `border_char` and interior cells with `fill_char`. Coordinates may place part or all of a rectangle outside the canvas; clip safely. Rectangles are drawn in input order, so later rectangles overwrite earlier pixels wherever they overlap.
## Constraints
- `0 <= width, height <= 1000`
- `1 <= w, h <= 1000`
- `x` and `y` may be negative.
- `border_char` and `fill_char` are single printable characters.
- The total canvas area is at most `10^6` cells.
## Example
For a `5` by `4` canvas and rectangle `(1, 1, 3, 2, '#', '.')`, return:
```text
###
###
```
A one-cell-wide or one-cell-high rectangle consists entirely of border cells.
## Clarifications
Canvas coordinates use zero-based columns and rows. Preserve trailing spaces in every returned row. Explain how clipping prevents invalid indexing without changing whether a visible cell is a border or interior cell of the original rectangle.
## Hints
Intersect each rectangle's coordinate range with the canvas before visiting pixels, but compute border status in the rectangle's original coordinates.
## Extensions
- Return only changed regions for a very large sparse canvas.
- Support transparency or z-indexes.
- Add tests for total clipping, corner clipping, thin rectangles, and overwrite order.
Quick Answer: Render bordered and filled rectangles onto a fixed ASCII canvas, clipping safely and honoring input-order overwrites. Handle negative coordinates, fully hidden shapes, one-cell dimensions, trailing spaces, overlap behavior, and a canvas of up to one million cells.
Implement render_canvas(width, height, rectangles). Create a blank canvas and return it as a list of height strings, each containing exactly width cells. Each rectangle is (x, y, w, h, border_char, fill_char), with (x, y) as its upper-left corner. Draw cells on the rectangle's original outer edge with border_char and its interior with fill_char. Clip any portion outside the canvas safely, but determine border versus interior from the original rectangle coordinates. Process rectangles in input order so every later rectangle overwrites earlier pixels where they overlap. A one-cell-wide or one-cell-high rectangle consists entirely of border cells, and trailing spaces in every returned row must be preserved.
Constraints
- 0 <= width, height <= 1000.
- The total canvas area width * height is at most 10^6 cells.
- Each rectangle is (x, y, w, h, border_char, fill_char), where 1 <= w, h <= 1000 and x and y may be negative.
- border_char and fill_char are each one printable character.
- Rectangles are drawn in input order, and later rectangles overwrite earlier pixels wherever they overlap.
Examples
Input: (5, 4, [(1, 1, 3, 2, "#", ".")])
Expected Output: [" "," ### "," ### "," "]
Explanation: The source example is preserved exactly; height two leaves no interior row, and all trailing spaces remain in the returned strings.
Input: (7, 5, [(0, 0, 7, 5, "#", "."), (2, 1, 3, 3, "@", "+")])
Expected Output: ["#######","#.@@@.#","#.@+@.#","#.@@@.#","#######"]
Explanation: The later three-by-three rectangle overwrites both border and fill cells of the earlier full-canvas rectangle.
Hints
- Intersect each rectangle's coordinate range with the canvas before visiting pixels, but compute border status in the rectangle's original coordinates.