Quick Overview

Given a board size and the sequence of columns two players drop pieces into, return which player first lines up four pieces horizontally, vertically or diagonally, or 0 if nobody does. It tests grid simulation, gravity placement and careful line counting in all four directions.

Find the Winner of a Connect Four Game from Its Move Sequence

Company: Snowflake

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

Two players play Connect Four on a grid with `rows` rows and `cols` columns. They take turns dropping a piece into a column, and the piece falls to the lowest empty cell of that column. Given the sequence of columns played, return the player who first gets four pieces in a line. ### Function Signature ```python def connect_four_winner(rows: int, cols: int, moves: list[int]) -> int: ``` ### Rules - The grid starts empty. Player 1 moves first and the players alternate, so `moves[i]` is played by player 1 when `i` is even and by player 2 when `i` is odd. - `moves[i]` is a column index from `0` to `cols - 1`. The piece occupies the lowest empty cell of that column. - A player wins as soon as four of their pieces occupy four consecutive cells along a row, a column or either diagonal. A line longer than four also counts. - Return `1` or `2` for the first player to win; any moves after the winning move are ignored. Return `0` if nobody has won after all the moves. ### Constraints - `1 <= rows <= 100` and `1 <= cols <= 100` - `0 <= len(moves) <= rows * cols` - `0 <= moves[i] <= cols - 1`, and no column receives more than `rows` pieces over the whole list. ### Examples In the picture, `X` is player 1, `O` is player 2, and the last line is the bottom row of the grid. **Example 1** ```text Input: rows = 6, cols = 7, moves = [0, 1, 1, 2, 2, 3, 2, 3, 3, 0, 3] Output: 1 . . . . . . . . . . . . . . . . . X . . . . . X X . . . O X X O . . . X O O O . . . ``` The last move, by player 1, completes the diagonal that rises from the bottom-left corner. Player 2 has three in a row along the bottom but never gets the fourth. **Example 2** ```text Input: rows = 6, cols = 7, moves = [0, 1, 0, 2, 0, 0, 6, 3, 5, 4, 6] Output: 2 ``` Player 1 stacks three pieces in column 0, and player 2 blocks the fourth. Player 2's move at index 9 fills the bottom row from column 1 to column 4 and wins; the move at index 10 is ignored. **Example 3** ```text Input: rows = 6, cols = 7, moves = [3, 3, 3, 3, 2, 4] Output: 0 ``` No player has four pieces in a line.

Overview: Given a board size and the sequence of columns two players drop pieces into, return which player first lines up four pieces horizontally, vertically or diagonally, or 0 if nobody does. It tests grid simulation, gravity placement and careful line counting in all four directions.

Two players play Connect Four on a grid with `rows` rows and `cols` columns. They take turns dropping a piece into a column, and the piece falls to the lowest empty cell of that column. Given the sequence of columns played, return the player who first gets four pieces in a line. Implement `connect_four_winner(rows, cols, moves)`. ### Rules - The grid starts empty. Player 1 moves first and the players alternate, so `moves[i]` is played by player 1 when `i` is even and by player 2 when `i` is odd. - `moves[i]` is a column index from `0` to `cols - 1`. The piece occupies the lowest empty cell of that column. - A player wins as soon as four of their pieces occupy four consecutive cells along a row, a column or either diagonal. A line longer than four also counts. - Return `1` or `2` for the first player to win; any moves after the winning move are ignored. Return `0` if nobody has won after all the moves. The answer is always `0`, `1` or `2`, so no value exceeds 2^31-1. ### Constraints - `1 <= rows <= 100` and `1 <= cols <= 100` - `0 <= len(moves) <= rows * cols` - `0 <= moves[i] <= cols - 1`, and no column receives more than `rows` pieces over the whole list. ### Examples In the picture, `X` is player 1, `O` is player 2, and the last line is the bottom row of the grid. **Example 1** ```text Input: rows = 6, cols = 7, moves = [0, 1, 1, 2, 2, 3, 2, 3, 3, 0, 3] Output: 1 . . . . . . . . . . . . . . . . . X . . . . . X X . . . O X X O . . . X O O O . . . ``` The last move, by player 1, completes the diagonal that rises from the bottom-left corner. Player 2 has three in a row along the bottom but never gets the fourth. **Example 2** ```text Input: rows = 6, cols = 7, moves = [0, 1, 0, 2, 0, 0, 6, 3, 5, 4, 6] Output: 2 ``` Player 1 stacks three pieces in column 0, and player 2 blocks the fourth. Player 2's move at index 9 fills the bottom row from column 1 to column 4 and wins; the move at index 10 is ignored.

Constraints

  • 1 <= rows <= 100 and 1 <= cols <= 100
  • 0 <= len(moves) <= rows * cols
  • 0 <= moves[i] <= cols - 1, and no column receives more than rows pieces over the whole list

Examples

Input: (6, 7, [])

Expected Output: 0

Explanation: Empty move list (length 0) on a 6x7 grid: nobody has played, so the result is 0.

Input: (1, 1, [0])

Expected Output: 0

Explanation: Smallest grid, 1x1, with its only possible move (length 1): a single piece cannot form a line, so 0.

Hints

  1. Keep track of how many pieces each column already holds, so you always know which cell a move lands in.
  2. Pieces are never removed, so a line of four can only appear at the moment a piece is dropped, and it must include that piece.
  3. The newest piece need not be at the end of its line: it can fill a gap in the middle, and a line longer than four still counts.

Loading coding console...

Show the approach

Approach

Simulate the game move by move. Keep heights[c], the number of pieces already in column c, so move i lands in row heights[c] (row 0 is the bottom) and belongs to player 1 when i is even and player 2 when i is odd.

Pieces are never removed, so a line of four can only appear at the moment a piece is dropped, and any such line must pass through that piece. After placing it, look along each of the four directions (horizontal, vertical, rising diagonal, falling diagonal): count the player's consecutive pieces outward from the new cell on both sides and add 1 for the cell itself. If any total reaches 4, return that player at once, which ignores every later move. If the loop finishes without a win, return 0.

Invariant: before move i is processed nobody has four in a line, otherwise the function would already have returned. So the first move whose cell joins a run of length at least 4 is exactly the first winning move, and each one-sided scan meets at most three matching pieces before it stops, which makes every move O(1). Counting both sides matters because the new piece can sit in the middle of its line (filling XX_XX makes five in a row), and comparing with >= 4 rather than == 4 accepts lines longer than four.

Edge cases: an empty move list returns 0; a grid with fewer than four rows and fewer than four columns can never produce a winner; the bounds checks keep every scan inside the grid on single-row or single-column boards and along the edges and corners.

Time complexity:
O(rows * cols + len(moves))
Space complexity:
O(rows * cols)