Rectangle board: add rectangles, count those covering a point, and undo

Read the full interview experience this question came from →

Quick Overview

A coding exercise to implement a board of axis-aligned rectangles that supports adding a rectangle, counting how many rectangles contain a given point, and undoing the most recent addition. It tests boundary semantics, clean state management for undo, complexity analysis, and choosing a faster spatial index when queries dominate.

Rectangle board: add rectangles, count those covering a point, and undo

Company: OpenAI

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: hard

Interview Round: Onsite

Implement a board that holds axis-aligned rectangles and supports three operations: add a rectangle, return how many rectangles on the board contain a given point, and undo. This was the coding round of an onsite. A starting interface (adjust it to the interviewer's answers), where `(x1, y1)` and `(x2, y2)` are opposite corners of the rectangle: ```python class RectangleBoard: def add(self, x1: int, y1: int, x2: int, y2: int) -> None: ... def count(self, x: int, y: int) -> int: ... def undo(self) -> bool: ... ``` ### Clarifying Questions - Are coordinates integers? Can the corners be given in any order, and can a rectangle have zero width or zero height? - Does a point on an edge or exactly on a corner count as inside? - Roughly how many rectangles and queries are expected, and is `count` called much more often than `add`? - What should `undo` do when there is nothing left to undo? - Is redo required? ### Part 1 — Add and count Implement `add` and `count`: `count(x, y)` returns the number of rectangles currently on the board that contain the point `(x, y)`. The same rectangle added twice counts twice. ```hint Measure before optimizing Write the direct version first, then ask how the numbers of adds and queries compare before reaching for a spatial structure. ``` #### What This Part Should Cover - A correct containment test, including corner normalization and the agreed boundary rule - The complexity of the direct approach and when it is good enough - A faster structure for query-heavy workloads, with its costs ### Part 2 — Undo Add `undo()`, which reverts the most recent `add` that has not already been undone and reports whether anything was undone. ```hint Remember what changed Decide what to record at the moment of each change so that reverting it never requires rebuilding the board. ``` #### What This Part Should Cover - The history structure and the exact behavior on an empty history - How undo interacts with whatever index Part 1 uses - The complexity of undo ### What a Strong Answer Covers - Settles coordinate types, corner order, the boundary rule and the empty-undo behavior before coding - Clean, correct code for all three operations, with tests that include edges, corners, duplicates and repeated undo - A complexity analysis, and a justified choice between the direct approach and an index - A history design that generalizes to other mutating operations and to redo ### Follow-up Questions - Add redo. What happens to the redo history when a new rectangle is added after an undo? - Add `remove(rect_id)` and make `undo` revert removals as well. - The board holds a very large number of rectangles and `count` is called far more often than `add`. What structure would you use, and how does undo interact with it? - Return the ids of the rectangles that contain the point, newest first. What changes?

Overview: A coding exercise to implement a board of axis-aligned rectangles that supports adding a rectangle, counting how many rectangles contain a given point, and undoing the most recent addition. It tests boundary semantics, clean state management for undo, complexity analysis, and choosing a faster spatial index when queries dominate.

Read the full OpenAI Software Engineer interview experience this question came from

OpenAI logo
OpenAI
Oct 12, 2026
hardSoftware EngineerOnsiteSoftware Engineering Fundamentals
0
0

Implement a board that holds axis-aligned rectangles and supports three operations: add a rectangle, return how many rectangles on the board contain a given point, and undo. This was the coding round of an onsite.

A starting interface (adjust it to the interviewer's answers), where (x1, y1) and (x2, y2) are opposite corners of the rectangle:

class RectangleBoard:
    def add(self, x1: int, y1: int, x2: int, y2: int) -> None: ...
    def count(self, x: int, y: int) -> int: ...
    def undo(self) -> bool: ...

Clarifying Questions Guidance

  • Are coordinates integers? Can the corners be given in any order, and can a rectangle have zero width or zero height?
  • Does a point on an edge or exactly on a corner count as inside?
  • Roughly how many rectangles and queries are expected, and is count called much more often than add ?
  • What should undo do when there is nothing left to undo?
  • Is redo required?

Part 1 — Add and count

Implement add and count: count(x, y) returns the number of rectangles currently on the board that contain the point (x, y). The same rectangle added twice counts twice.

What This Part Should Cover Guidance

  • A correct containment test, including corner normalization and the agreed boundary rule
  • The complexity of the direct approach and when it is good enough
  • A faster structure for query-heavy workloads, with its costs

Part 2 — Undo

Add undo(), which reverts the most recent add that has not already been undone and reports whether anything was undone.

What This Part Should Cover Guidance

  • The history structure and the exact behavior on an empty history
  • How undo interacts with whatever index Part 1 uses
  • The complexity of undo

What a Strong Answer Covers Guidance

  • Settles coordinate types, corner order, the boundary rule and the empty-undo behavior before coding
  • Clean, correct code for all three operations, with tests that include edges, corners, duplicates and repeated undo
  • A complexity analysis, and a justified choice between the direct approach and an index
  • A history design that generalizes to other mutating operations and to redo

Follow-up Questions Guidance

  • Add redo. What happens to the redo history when a new rectangle is added after an undo?
  • Add remove(rect_id) and make undo revert removals as well.
  • The board holds a very large number of rectangles and count is called far more often than add . What structure would you use, and how does undo interact with it?
  • Return the ids of the rectangles that contain the point, newest first. What changes?