Sharing my Roblox interview experience, hoping it helps everyone. I'm still in the middle of interviewing right now.
I applied to Roblox with three years of full-time experience, mass-applying as an experienced hire. I don't know why, but they first gave me an online assessment, which is mostly playing their little puzzle games plus answering some behavioral questions.
I have to complain about this a bit: I had to download the Roblox app specifically to play these games. The first game was factory optimizing: different production lines have several checkpoints, and you change the number of inputs to maximize the output. The second game was designing a robot car that has to cross different terrain, like snowy mountains and bushes. The third part was behavioral questions, for example: the project is almost due and you discover there was a problem with the earlier design, what do you do (single choice).
Honestly I didn't feel I played especially well, but I still passed. Personally I think these games are completely meaningless and say nothing about an engineer's level.
Then I got to the actual phone screen. Sharing the questions: match 3 and search autocomplete. I didn't get to finish the follow-up on one of them, but I felt the interviewer was nice and gave me hints.
Match-3 Grid
You're given an m x n grid of positive integers. A match is 3 or more equal values in a row, side by side, either horizontally or vertically.
Part 1: Find the matches. Return a list of (value, length) for every match in the grid.
- List all horizontal matches first, scanning rows top to bottom and each row left to right.
- Then list all vertical matches, scanning columns left to right and each column top to bottom.
- A run counts once at its full length. A run of four 7s is
(7, 4), not two runs of 3. - A cell can belong to both a horizontal and a vertical match. Report both.
Part 2: Clear and drop. After finding the matches:
- Set every cell that belongs to any match to
0. - In each column, let the non-zero values fall to the bottom, keeping their original top-to-bottom order. All the zeros end up at the top of the column.
- Return the resulting grid.
Example
Input:
1 2 3 4
7 7 7 7
5 2 7 1
6 2 7 3
Part 1 output:
[(7, 4), (7, 3)]
Row 1 has four 7s, so it is a horizontal match of length 4. Column 2 has 7, 7, 7 in rows 1 to 3, so it is a vertical match of length 3. Column 1 is 2, 7, 2, 2. The 2s are not three in a row, so there is no match.
After clearing matched cells:
1 2 3 4
0 0 0 0
5 2 0 1
6 2 0 3
Part 2 output (after dropping):
0 0 0 0
1 2 0 4
5 2 0 1
6 2 3 3
This one was pretty straightforward, just a lot of if/else statements, so it took a while. For Part 1, scan by row and then by column, using two pointers to find each run of consecutive equal values; if the length is >= 3, record (value, length) and store those cells' coordinates in a set. For Part 2, set everything in the set to 0, then for each column fill the non-zero values downward from the bottom.
Search Autocomplete
You're building autocomplete for a search bar. You're given a log of past searches and a list of autocomplete requests.
Inputs:
searchQueries: list of strings, the queries users searchedsearchTimestamps: list of ints, wheresearchTimestamps[i]is whensearchQueries[i]was searchedprefixes: list of strings, what the user has typed so far in each autocomplete requestprefixTimestamps: list of ints, whereprefixTimestamps[j]is whenprefixes[j]was typedresultCount: int, the maximum number of suggestions to return per request
For each autocomplete request j, return up to resultCount suggestions. Only consider past searches that happened at or before prefixTimestamps[j], and start with prefixes[j]. A query equal to the prefix counts.
Rank the matching queries by:
- Search count, highest first.
- Earliest time the query was first searched, earliest first, if counts tie.
- Alphabetical order, if both still tie.
Return a list of lists, one list of suggestions per request, in the same order as prefixes. If nothing matches, that request's list is empty.
Example
searchQueries = ["apple", "app", "apple", "apply", "banana", "app", "app"]
searchTimestamps = [1, 2, 3, 4, 5, 6, 7]
prefixes = ["app", "app", "app", "b", "c"]
prefixTimestamps = [3, 6, 7, 5, 10]
resultCount = 2
Output:
[["apple", "app"], ["apple", "app"], ["app", "apple"], ["banana"], []]
- "app" at t=3: "apple" was searched 2 times and "app" 1 time.
- "app" at t=6: "apple" and "app" were each searched 2 times. "apple" was first searched earlier (t=1 vs t=2), so it ranks first. "apply" was searched once and is cut off by
resultCount. - "app" at t=7: "app" now has 3 searches, so it moves ahead of "apple".
- "b" at t=5: only "banana" matches.
- "c" at t=10: nothing matches, so the list is empty.
For each prefix, first filter out the queries with timestamp <= the current time that satisfy startswith(prefix), and use a hashmap to count each query's count and earliest timestamp. Then push them into a heap keyed by (-count, earliestTimestamp, query) and take the first resultCount. The key point is that the tuple order maps exactly onto the three levels of tie-breaking rules.
Discussion
Loading comments…