PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question tests practical coding ability by requiring implementation of a command-driven state machine on a bounded 2D grid. It evaluates simulation logic, boundary handling, and input parsing — skills commonly assessed in software engineering interviews to gauge attention to edge cases and clean state management.

  • medium
  • Shopify
  • Coding & Algorithms
  • Software Engineer

Grid Robot Command Simulator

Company: Shopify

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

# Grid Robot Command Simulator You are building a small command-driven robot simulator. A single robot lives on a 2D grid and is controlled by a stream of text commands (the kind you would type into a terminal). Your program reads the commands in order, updates the robot's state, and reports the robot's position and heading on demand. ## Robot Model - The grid is a finite rectangle of width `W` columns and height `H` rows. Cells are addressed by integer coordinates `(x, y)` where `0 <= x < W` (column, increasing to the right / East) and `0 <= y < H` (row, increasing upward / North). The cell `(0, 0)` is the bottom-left corner. - The robot has a position `(x, y)` and a heading that is one of the four cardinal directions: `N`, `E`, `S`, `W`. - The robot starts **unplaced**. Until it has been placed, every command other than a placement command is ignored. ## Commands Each command is a single line. Tokens within a line are separated by a single space. Commands are case-sensitive and given exactly as below. | Command | Effect | |---|---| | `PLACE x y D` | Place (or re-place) the robot at cell `(x, y)` facing direction `D` (one of `N`, `E`, `S`, `W`). Ignored if `(x, y)` is outside the grid or `D` is invalid. | | `MOVE` | Move the robot one cell forward in its current heading. | | `LEFT` | Rotate the robot 90 degrees counter-clockwise in place (heading only). | | `RIGHT` | Rotate the robot 90 degrees clockwise in place (heading only). | | `REPORT` | Output the robot's current state as `x,y,D` on its own line (for example `1,2,N`). | ## Movement and Boundary Rules - A `MOVE` that would carry the robot off the grid (beyond any edge) is **ignored**: the robot stays where it is, with its heading unchanged. The robot must never leave the grid or fall off an edge. - Any command issued before the first valid `PLACE` is ignored, including `REPORT` (a `REPORT` before placement produces no output). - A malformed or unrecognized command line is ignored (it does not crash the program and does not change state). ## Input - The first line contains two integers `W` and `H` separated by a space — the grid width and height. - Each subsequent line is one command, until end of input. ## Output - For every `REPORT` command that executes while the robot is placed, print one line `x,y,D`. - Print nothing else. ## Example Input: ``` 5 5 PLACE 0 0 N MOVE REPORT LEFT REPORT MOVE REPORT ``` Output: ``` 0,1,N 0,1,W 0,1,W ``` Explanation: The robot is placed at `(0,0)` facing North and moves to `(0,1)`. Turning `LEFT` from North gives West. The next `MOVE` faces West from column `0`, which would leave the grid, so it is ignored and the robot stays at `(0,1)` facing West. ## Constraints - `1 <= W, H <= 1000`. - The number of command lines is at most `100000`. - Coordinates in any `PLACE` command fit in a 32-bit signed integer (but may be out of grid bounds, in which case the placement is ignored). ## Follow-up (handle in the same program if you have time) Extend the simulator to support **multiple robots** sharing the grid. Each command after the grid line is prefixed by a robot id (a non-negative integer), for example `0 PLACE 1 1 N` or `2 MOVE`. Robots cannot occupy the same cell at the same time: a `MOVE` (or a `PLACE` onto an already-occupied cell) that would cause a collision is ignored, leaving both robots unchanged. A `REPORT` for robot `id` prints `id:x,y,D`. Decide and document how `PLACE` interacts with occupied cells and how you resolve ordering, then describe the edge cases your design handles.

Quick Answer: This question tests practical coding ability by requiring implementation of a command-driven state machine on a bounded 2D grid. It evaluates simulation logic, boundary handling, and input parsing — skills commonly assessed in software engineering interviews to gauge attention to edge cases and clean state management.

Grid Robot Command Simulator

You are building a small command-driven robot simulator. A single robot lives on a 2D grid of width `W` columns and height `H` rows. Cells are addressed by integer coordinates `(x, y)` with `0 <= x < W` (column, increasing East) and `0 <= y < H` (row, increasing North); `(0, 0)` is the bottom-left corner. The robot has a position and a heading — one of `N`, `E`, `S`, `W` — and starts **unplaced**. You are given the grid as `grid = [W, H]` and a list of command strings `commands`. Process the commands in order and return a list of the lines produced by `REPORT`. **Commands** (case-sensitive, single space between tokens): - `PLACE x y D` — place (or re-place) the robot at `(x, y)` facing `D`. Ignored if `(x, y)` is outside the grid or `D` is invalid. - `MOVE` — move one cell forward in the current heading. A `MOVE` that would carry the robot off the grid is **ignored** (position and heading unchanged). - `LEFT` — rotate 90 degrees counter-clockwise in place. - `RIGHT` — rotate 90 degrees clockwise in place. - `REPORT` — append the robot's state `"x,y,D"` to the output (e.g. `"1,2,N"`). **Rules:** Every command before the first valid `PLACE` is ignored, including `REPORT` (which produces no output). Any malformed or unrecognized line is ignored without changing state. Return the list of `REPORT` outputs, in order.

Constraints

  • 1 <= W, H <= 1000
  • Number of command lines <= 100000
  • PLACE coordinates fit in a 32-bit signed integer but may be out of grid bounds (then the PLACE is ignored)
  • Commands are case-sensitive and exactly as specified

Examples

Input: ([5, 5], ['PLACE 0 0 N', 'MOVE', 'REPORT', 'LEFT', 'REPORT', 'MOVE', 'REPORT'])

Expected Output: ['0,1,N', '0,1,W', '0,1,W']

Explanation: Placed at (0,0) facing N, MOVE -> (0,1). LEFT from N gives W. The final MOVE faces W from column 0, which would leave the grid, so it is ignored.

Input: ([3, 3], ['REPORT', 'MOVE', 'PLACE 1 1 E', 'REPORT'])

Expected Output: ['1,1,E']

Explanation: REPORT and MOVE before the first valid PLACE are ignored and produce no output; only the post-PLACE REPORT prints.

Input: ([5, 5], ['PLACE 4 4 N', 'MOVE', 'RIGHT', 'MOVE', 'REPORT'])

Expected Output: ['4,4,E']

Explanation: At the top-right corner facing N, MOVE off the top edge is ignored. RIGHT turns to E; MOVE off the right edge is also ignored, so the robot stays at (4,4,E).

Input: ([1, 1], ['PLACE 0 0 S', 'MOVE', 'MOVE', 'REPORT', 'RIGHT', 'REPORT'])

Expected Output: ['0,0,S', '0,0,W']

Explanation: On a 1x1 grid every MOVE is off-grid, so position never changes; RIGHT from S yields W.

Input: ([5, 5], ['PLACE 2 2 N', 'GARBAGE', 'PLACE 9 9 N', 'PLACE 0 0 X', 'REPORT'])

Expected Output: ['2,2,N']

Explanation: An unrecognized line, an out-of-grid PLACE, and a PLACE with an invalid direction are all ignored, leaving the robot at (2,2,N).

Input: ([10, 10], ['PLACE 5 5 W', 'LEFT', 'LEFT', 'LEFT', 'LEFT', 'REPORT', 'MOVE', 'REPORT'])

Expected Output: ['5,5,W', '4,5,W']

Explanation: Four LEFT turns return to the original heading W; the interior MOVE west succeeds to (4,5).

Input: ([2, 2], [])

Expected Output: []

Explanation: No commands means no output.

Hints

  1. Track three pieces of state: position (x, y), heading, and a boolean for whether the robot has been placed. Ignore every non-PLACE command while unplaced.
  2. Encode the four headings with unit direction vectors (N=(0,1), E=(1,0), S=(0,-1), W=(-1,0)) so MOVE is just an add, and use two small lookup tables for LEFT/RIGHT rotations.
  3. Validate aggressively: a PLACE outside the grid or with a bad direction, and a MOVE that would leave the grid, must be no-ops. Reject malformed token counts so garbage lines never mutate state.

Grid Robot Command Simulator (Multiple Robots)

Extend the simulator to support **multiple robots** sharing one grid. The grid is still `grid = [W, H]`, but now every command in `commands` is prefixed by a non-negative integer robot id, for example `"0 PLACE 1 1 N"` or `"2 MOVE"`. Each robot maintains its own position and heading and starts unplaced. The per-robot commands behave exactly as in the single-robot version (`PLACE`, `MOVE`, `LEFT`, `RIGHT`, `REPORT`), with these added collision rules: - **No two robots may occupy the same cell at the same time.** - A `MOVE` whose target cell is currently occupied by another robot is **ignored** (both robots stay put). - A `PLACE` onto a cell currently occupied by a **different** robot is **ignored**. A robot may re-`PLACE` onto its own current cell (only the heading changes), and re-placing elsewhere vacates its old cell first. - A `REPORT id` appends `"id:x,y,D"` to the output (e.g. `"2:1,1,N"`). As before, any command for a robot that has not yet been placed (other than `PLACE`) is ignored, off-grid `MOVE`/`PLACE` are ignored, and malformed lines — including a missing, negative, or non-integer robot id — are ignored without changing state. Return the list of `REPORT` outputs, in order.

Constraints

  • 1 <= W, H <= 1000
  • Number of command lines <= 100000
  • Robot ids are non-negative integers; a missing, negative, or non-integer id makes the line malformed and ignored
  • PLACE coordinates fit in a 32-bit signed integer but may be out of grid bounds (then the PLACE is ignored)

Examples

Input: ([5, 5], ['0 PLACE 0 0 N', '0 MOVE', '0 REPORT', '0 LEFT', '0 REPORT', '0 MOVE', '0 REPORT'])

Expected Output: ['0:0,1,N', '0:0,1,W', '0:0,1,W']

Explanation: A single robot behaves exactly as in part 1, now with the id prefix in REPORT output.

Input: ([5, 5], ['0 PLACE 1 1 N', '1 PLACE 1 2 S', '1 MOVE', '1 REPORT', '0 MOVE', '0 REPORT'])

Expected Output: ['1:1,2,S', '0:1,1,N']

Explanation: Robot 1 at (1,2) facing S tries to MOVE into (1,1) held by robot 0 — collision, ignored. Robot 0 then tries to MOVE N into (1,2) held by robot 1 — also a collision, ignored. Both stay put.

Input: ([5, 5], ['0 PLACE 2 2 N', '1 PLACE 2 2 S', '1 REPORT', '0 REPORT'])

Expected Output: ['0:2,2,N']

Explanation: Robot 1's PLACE targets (2,2), already held by robot 0, so it is ignored; robot 1 stays unplaced and its REPORT produces nothing.

Input: ([5, 5], ['2 MOVE', '2 REPORT', '0 PLACE 3 3 E', '0 REPORT'])

Expected Output: ['0:3,3,E']

Explanation: Commands for robot 2 before it is placed (MOVE, REPORT) are ignored; only robot 0's REPORT after a valid PLACE prints.

Input: ([5, 5], ['0 PLACE 1 1 E', '0 PLACE 4 4 W', '0 REPORT'])

Expected Output: ['0:4,4,W']

Explanation: Re-placing robot 0 to an empty cell vacates its old cell and moves it to (4,4) facing W.

Input: ([5, 5], ['0 PLACE 1 1 N', '1 PLACE 2 2 W', '0 PLACE 2 2 S', '0 REPORT', '1 REPORT'])

Expected Output: ['0:1,1,N', '1:2,2,W']

Explanation: Robot 0's re-PLACE onto (2,2), held by robot 1, is rejected, so robot 0 stays at its prior (1,1,N) and robot 1 is unaffected.

Input: ([5, 5], ['-1 PLACE 0 0 N', 'x PLACE 1 1 N', '0 PLACE 0 0 N', '0 REPORT'])

Expected Output: ['0:0,0,N']

Explanation: A negative id and a non-integer id make those lines malformed and ignored; only the valid robot 0 is placed.

Input: ([3, 1], ['0 PLACE 0 0 E', '1 PLACE 1 0 E', '0 MOVE', '0 REPORT', '1 MOVE', '1 REPORT'])

Expected Output: ['0:0,0,E', '1:2,0,E']

Explanation: On a 3x1 strip robot 0's MOVE into (1,0) is blocked by robot 1, but once robot 1 advances to (2,0) the strip clears; robot 0 simply stayed at (0,0).

Hints

  1. Replace the single robot's scalar state with a map id -> (x, y, heading), and add a second map cell -> id so you can check occupancy in O(1).
  2. A MOVE only commits if the target is in-grid AND not in the occupied map; on commit, delete the old cell from the map and insert the new one to keep the two maps consistent.
  3. Decide PLACE-vs-occupancy explicitly: re-placing a robot onto its own cell is allowed (heading-only), placing onto a cell held by a different robot is rejected, and moving a robot elsewhere must vacate its previous cell before claiming the new one.
Last updated: Jun 24, 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
  • 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

  • Compute Theme Similarity - Shopify (medium)
  • Compute Jaccard Similarity for Lists - Shopify (medium)
  • Implement URL Shortening Codec - Shopify (medium)
  • Simulate a rover fleet - Shopify (medium)
  • Simulate robot moves on a grid - Shopify (medium)