PracHub
QuestionsCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates implementation skills for efficient algorithms and data structures to manage a sparse, unbounded grid with gravity and to detect N-in-a-row runs both vertically and horizontally.

  • medium
  • Jane Street
  • Coding & Algorithms
  • Machine Learning Engineer

Connect-N on an Infinite Board with Gravity

Company: Jane Street

Role: Machine Learning Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

You are asked to implement a variant of the classic Connect Four game, played on an unbounded board. ## Game Rules - The board consists of vertical columns indexed by integers. Columns extend **infinitely in both horizontal directions**, so any integer (including negative values) is a valid column index. - Each column is also **unbounded vertically**: it can hold any number of pieces. - Pieces are dropped into a column from above and fall under **gravity**: a piece inserted into column `col` lands on top of the pieces already in that column. If a column currently holds `h` pieces, the new piece occupies row `h` of that column (rows are 0-indexed from the bottom, so the bottom cell of every column is row 0). - Two or more players take part; each player is identified by an integer ID. - A player **wins** as soon as they have `N` of their own pieces in a line of consecutive cells, either: - **vertically** — `N` consecutive pieces stacked in the same column, or - **horizontally** — `N` pieces in the same row across `N` consecutive columns. Note that because columns fill independently, adjacent columns can have very different heights (the board is sparsely occupied). A horizontal line at row `r` only counts a column if that column actually has a piece at row `r` and that piece belongs to the player — an empty cell or an opponent's piece breaks the run. ## Task Implement a game class supporting: - `ConnectN(n)` — initialize the game where a player needs `n` in a row to win. - `insert(col, player)` — drop a piece for `player` into column `col`, and return `true` if this move gives `player` `N` in a row (vertically or horizontally), otherwise `false`. You will be given a sequence of moves and must report, for each move, whether it wins the game. Process every move in the sequence even after a win has occurred (each move is judged independently by the rule above). ## Performance Requirement The board is unbounded, so scanning the whole board after every move is not acceptable. Each `insert` must only examine the cells that the new piece could possibly affect: the top of its own column and the cells within distance `N - 1` of the new piece in its row. Your solution should handle up to $10^5$ moves efficiently, with each move costing $O(N)$ time (or better) and total memory proportional to the number of pieces placed. ## Input Format - The first line contains two integers `n` and `m` — the win length ($2 \le n \le 1000$) and the number of moves ($1 \le m \le 10^5$). - Each of the next `m` lines contains two integers `col` and `player` — the column ($-10^9 \le col \le 10^9$) and the player ID ($1 \le player \le 10^9$). ## Output Format For each move, in order, output `true` if that move creates a run of at least `n` consecutive pieces (vertically or horizontally) for the moving player, and `false` otherwise — one value per line. ## Example Input: ``` 3 7 0 1 1 2 1 1 2 2 -1 1 2 1 -1 1 ``` Output: ``` false false false false false false false ``` Walkthrough of the final board state (rows shown bottom-up): ``` row 1: . 1 1 row 0: 1 1 2 2 col: -1 0 1 2 ``` - Move 5 (`-1, 1`): player 1 now has pieces at row 0 in columns -1 and 0, but column 1 holds player 2's piece at row 0, so the horizontal run is only 2 — not a win for `n = 3`. - Move 6 (`2, 1`): the piece lands at row 1 of column 2. In row 1, only columns 1 and 2 are occupied by player 1 — a run of 2, not a win. Column 2 vertically holds `[2, 1]` — no vertical run either. A second example where a win occurs: Input: ``` 3 5 0 1 0 1 5 2 0 1 5 2 ``` Output: ``` false false false true false ``` The fourth move stacks player 1's third consecutive piece in column 0 (rows 0, 1, 2), completing a vertical run of length 3.

Quick Answer: This question evaluates implementation skills for efficient algorithms and data structures to manage a sparse, unbounded grid with gravity and to detect N-in-a-row runs both vertically and horizontally.

Implement a variant of Connect Four on an unbounded board. Columns are indexed by any integer (negative allowed) and extend infinitely in both horizontal directions; each column is also unbounded vertically. A piece dropped into column `col` falls under gravity and lands on top of that column's existing stack: if the column holds `h` pieces, the new piece occupies row `h` (rows are 0-indexed from the bottom). Two or more players play, each identified by an integer ID. A player wins the instant they have `N` of their own pieces in a line of consecutive cells, either vertically (N stacked in one column) or horizontally (N in the same row across N consecutive columns). Because columns fill independently the board is sparse: a horizontal line at row `r` only counts a column if that column actually has one of the player's pieces at row `r` — an empty cell or an opponent's piece breaks the run. Implement the game as a function `solution(n, moves)` where `n` is the win length and `moves` is a list of `[col, player]` moves applied in order. Return a list of booleans — one per move — where the i-th value is `true` if that move creates a run of at least `n` consecutive pieces (vertical or horizontal) for the moving player, and `false` otherwise. Every move is judged independently, so keep processing moves even after a win occurs. Each `insert` must only examine the cells the new piece can affect — the top of its own column (downward) and the cells within distance `N - 1` of the new piece along its row — so a single move costs O(N) time and total memory stays proportional to the number of pieces placed. Constraints: 2 <= n <= 1000, up to 1e5 moves, -1e9 <= col <= 1e9, 1 <= player <= 1e9.

Constraints

  • 2 <= n <= 1000
  • 1 <= number of moves m <= 1e5
  • -1e9 <= col <= 1e9 (negative columns are valid)
  • 1 <= player <= 1e9
  • The board is unbounded horizontally and vertically; occupancy is sparse.
  • Each move must be judged independently, even after a prior win.
  • Per-move work must stay O(N); do not rescan the whole board.

Examples

Input: (3, [[0,1],[1,2],[1,1],[2,2],[-1,1],[2,1],[-1,1]])

Expected Output: [False, False, False, False, False, False, False]

Explanation: Prompt example 1. Final board has player 1 at row 0 in columns -1 and 0, but column 1's row 0 holds player 2, so the horizontal run is only 2 (< 3). No column reaches 3 of the same player either — all moves report false.

Input: (3, [[0,1],[0,1],[5,2],[0,1],[5,2]])

Expected Output: [False, False, False, True, False]

Explanation: Prompt example 2. The fourth move stacks player 1's third consecutive piece in column 0 (rows 0,1,2), completing a vertical run of length 3 -> true. The other moves fall short.

Input: (2, [[-1,1],[0,1]])

Expected Output: [False, True]

Explanation: Horizontal win across a negative and a non-negative column: player 1 occupies row 0 of columns -1 and 0, a run of 2 for n=2.

Input: (3, [])

Expected Output: []

Explanation: Edge case: no moves means an empty result list.

Input: (5, [[0,1]])

Expected Output: [False]

Explanation: Single move can never reach a run of 5.

Input: (3, [[0,1],[1,2],[2,1],[3,1],[4,1]])

Expected Output: [False, False, False, False, True]

Explanation: Player 2's piece in column 1 blocks the horizontal run, so player 1's run is measured only from column 2 rightward. The fifth move makes columns 2,3,4 all player 1 at row 0 -> run of 3 -> true.

Input: (2, [[-1000000000,7],[-999999999,7]])

Expected Output: [False, True]

Explanation: Boundary columns at the extreme negative end (-1e9 and -1e9+1) form a horizontal run of 2 for player 7.

Hints

  1. Store each column as a stack (e.g. a dict from column index to a list of player IDs). The new piece's row is simply the current height of that column before insertion.
  2. The new piece is always on top of its column, so the only vertical run that can complete on this move ends at the new piece — count downward while the player matches; stop as soon as it differs.
  3. For the horizontal check, keep a separate map from (col, row) -> player. Only the new piece's row matters: walk left then right while the neighbor at the same row belongs to the same player. An empty cell (missing key) or an opponent's ID breaks the run.
  4. Because columns fill independently, adjacent columns can be at very different heights — never assume neighbors have a piece at your row; the (col, row) lookup naturally returns nothing for empty cells.
Last updated: Jul 2, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Collapsible Code Editor: Brace Matching and Toggle - Jane Street (medium)
  • Implement a Circular Buffer - Jane Street (medium)
  • Code Editor with Block Shrink and Expand (Code Folding) - Jane Street (medium)
  • Optimize trade PnL table updates - Jane Street (hard)
  • Transform sparse time-code stream to dense rows - Jane Street (easy)