def find_robots(grid: list, query: list, order: str = "ltbr") -> list:
The round: nine reports from November 2025 to October 2026: seven phone screens (about 20 minutes of coding next to a project deep dive; one had 45 minutes of coding and 15 of design), one onsite round, and one round whose format is not stated. Every report describes the same task; two give the full example map. Two reports describe the same push: brute force first, then precompute the distances in four directions. Two graded parts here: one query, then many queries on the same map.
You get a map, a list of rows where "O" is a robot, "E" is empty and "X" is a blocker, and a query of four distances to the closest blocker, by default in the order [left, top, bottom, right]. The edge of the map also counts as a blocker.
O E E E X query [2, 2, 4, 1] -> [[1, 1]]
E O X X X
E E E E E robot [1, 1]: left 2 (edge), top 2 (edge),
X E O E E bottom 4 (edge), right 1 (the X next to it)
X E X E X
Distance is the index gap. A blocker in the next cell is distance 1, and the edge sits one step past the last cell. That is the only reading under which the reported example gives [1, 1]; counting just the empty cells in between gives [1, 1, 3, 0] for that robot.
Part 1 — find the robots that match one query
def find_robots(grid: list, query: list, order: str = "ltbr") -> list: ...
[row, col] for every robot whose four distances equal the query, in row-major order, or [] when none does. Several robots can match."X" and the edge block. Another robot in the way does not.order says which direction each query slot is. Most reports give left, top, bottom, right ("ltbr"); one gives left, top, right, bottom ("ltrb"). The same four numbers find different robots under the two orders, so ask.Notes: the function and class names, the order parameter, the row-major output and Part 2's many-queries framing are ours. In the reports the interviewer asked for something better than brute force without naming a scenario; commenters on one report debate whether a single query justifies the precompute.
Precompute, for every cell, the distance to the nearest blocker or boundary in each of the four directions with four linear passes (left-to-right for left distances, right-to-left for right, top-down for top, bottom-up for bottom). Each robot's check is then four lookups, and the whole grid costs O(mn) instead of a fresh scan from every robot. In the report this comes from, the interviewer was not satisfied with brute force and asked for a better way without naming a scenario; the candidate discussed precomputing the four distances, wrote that version, and got an onsite invite.
Standard explanation — no candidate report records what the interviewer accepted here.
Repeated queries on the same grid. Scanning from every robot costs O(R (m + n)) per query; the four DP passes cost O(mn) once, and indexing robots in a hash map keyed by their (left, top, bottom, right) tuple makes each later query O(1) plus the output size. With a single query on a sparse grid, scanning from each robot can be cheaper.
Reported again and again from late 2025 into October 2026, mostly in phone screens, plus one onsite round; candidates call it a known high-frequency question. Phone screens are short: about 20 minutes of coding beside a 30-minute project deep dive in two reports. One interviewer stressed communication and implementation, said brute force was fine and that not finishing was acceptable. Another was not satisfied with brute force and asked for something better without naming a scenario; that candidate precomputed the four directional distances, wrote it, did only a verbal dry run of the given example (no test cases were provided), and was invited onsite the next day. In one onsite round the candidate only talked through the idea and wrote no code.
Also reported as Find Robot by Distance to Blockers · Find Robots Position
The round: nine reports from November 2025 to October 2026: seven phone screens (about 20 minutes of coding next to a project deep dive; one had 45 minutes of coding and 15 of design), one onsite round, and one round whose format is not stated. Every report describes the same task; two give the full example map. Two reports describe the same push: brute force first, then precompute the distances in four directions. Two graded parts here: one query, then many queries on the same map.
You get a map, a list of rows where "O" is a robot, "E" is empty and "X" is a blocker, and a query of four distances to the closest blocker, by default in the order [left, top, bottom, right]. The edge of the map also counts as a blocker.
O E E E X query [2, 2, 4, 1] -> [[1, 1]]
E O X X X
E E E E E robot [1, 1]: left 2 (edge), top 2 (edge),
X E O E E bottom 4 (edge), right 1 (the X next to it)
X E X E X
Distance is the index gap. A blocker in the next cell is distance 1, and the edge sits one step past the last cell. That is the only reading under which the reported example gives [1, 1]; counting just the empty cells in between gives [1, 1, 3, 0] for that robot.
Part 1 — find the robots that match one query
def find_robots(grid: list, query: list, order: str = "ltbr") -> list: ...
[row, col] for every robot whose four distances equal the query, in row-major order, or [] when none does. Several robots can match."X" and the edge block. Another robot in the way does not.order says which direction each query slot is. Most reports give left, top, bottom, right ("ltbr"); one gives left, top, right, bottom ("ltrb"). The same four numbers find different robots under the two orders, so ask.Part 2 — answer many queries on the same map
class RobotFinder:
def __init__(self, grid: list): ...
def find(self, query: list, order: str = "ltbr") -> list: ...
find is called many times (the stress test asks 4,000 queries on a 300 x 300 map). Do the per-map work once in the constructor.Notes: the function and class names, the order parameter, the row-major output and Part 2's many-queries framing are ours. In the reports the interviewer asked for something better than brute force without naming a scenario; commenters on one report debate whether a single query justifies the precompute.
Can you do better? Is there a way to precompute and speed this up?
What scenario justifies the precomputation overhead?
| Approach | Notes |
|---|---|
| Brute-force ray casting per robot | simple; O(M*N*(M+N)) per query in the worst case. One interviewer said brute force was fine to implement; others pushed for better. |
| Precompute four-direction DP arrays | O(M*N) preprocessing, then each query is a lookup if robots are indexed by their four distances; the passes need careful index management, which one report calls the hard part. |
Common mistakes: Stopping at brute force: one interviewer was not satisfied with the brute-force explanation and asked for something better, and one candidate who knew it called for DP could only write brute force.; Mixing up direction indices: one report calls this the hard part of the problem. Check the query order too: most reports give [left, top, bottom, right], one gives left, top, right, bottom.; Counting only the empty cells between the robot and the blocker: the reported example ([2, 2, 4, 1] gives the robot at [1, 1]) needs the index gap, so a blocker in the next cell is distance 1.
Interviewer hints: At least one interviewer did not provide a scenario to motivate the optimization and simply asked 'is there a better way?' after the brute-force explanation.; One interviewer emphasised communication and implementation, said implementing brute force was fine, and said it was acceptable even not to finish.; One interviewer gave no test cases on HackerRank and did not ask for any; a verbal dry run of the given example was enough to move on to design.
What passers do: One candidate who got an onsite invite discussed brute force, then precomputing the four directional distances, and wrote the optimised version; the interviewer had not said what scenario called for optimising.
Edge cases to test: Grid boundary counts as a blocker (a robot in column 0 has left distance 1); Robot adjacent to a blocker (distance = 1); Robot at a corner of the grid; Multiple robots in the grid, only some match the query; Whether other robots block: in the reported examples only 'X' and the boundary are blockers, so confirm before treating 'O' as open.
Send them this page. It is free to read, no account needed.
What you just read — canonical solution, follow-up arc, what passing candidates actually did — exists for all 83 Uber questions, refreshed monthly from new candidate reports.