Solve three mini-game algorithm tasks
Company: Optiver
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Technical Screen
Quick Answer: Solve three mini-game algorithm tasks evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.
Move-House Puzzle: Minimum Sliding Moves
Constraints
- 1 <= R, C and R*C <= ~12 for an exact BFS to remain tractable.
- Exactly one cell in each grid equals 0 (the empty cell).
- start and target share the same dimensions and the same multiset of labels.
- Return -1 when the target permutation is unreachable (e.g. an odd permutation given the empty-cell parity).
Examples
Input: ([[1, 2], [3, 0]], [[1, 2], [3, 0]])
Expected Output: 0
Explanation: Start already equals target, so zero moves are needed.
Input: ([[1, 2], [0, 3]], [[1, 2], [3, 0]])
Expected Output: 1
Explanation: Slide the block 3 left into the empty cell (one move).
Input: ([[1, 2], [3, 0]], [[1, 0], [3, 2]])
Expected Output: 1
Explanation: Slide the block 2 down into the empty cell (one move).
Input: ([[1, 2, 3], [4, 0, 5], [7, 8, 6]], [[1, 2, 3], [4, 5, 6], [7, 8, 0]])
Expected Output: 2
Explanation: Move 5 left then 6 up: two moves to reach the solved board.
Input: ([[1, 2], [3, 0]], [[2, 1], [3, 0]])
Expected Output: -1
Explanation: Swapping only tiles 1 and 2 while the blank stays put is an odd permutation and is unreachable in a 2x2 puzzle.
Input: ([[0, 1], [2, 3]], [[3, 2], [1, 0]])
Expected Output: 6
Explanation: This is the farthest reachable 2x2 configuration from the start, requiring the full diameter of 6 moves.
Hints
- Encode a grid as a flat tuple so it can be a dictionary/set key for the visited check.
- BFS layer-by-layer gives the shortest move count in an unweighted state graph; the first time you reach target is optimal.
- Generate neighbors by swapping the empty cell (0) with each in-bounds orthogonal neighbor.
- Parity matters: in a 2x2 board with a fixed blank position, a single transposition of two tiles is unreachable.
Arrow-or-Odd Stream
Constraints
- Each token is one of the four arrow glyphs or a non-negative integer.
- The first arrow in the stream always outputs 0 (no previous arrow).
- Integers between two arrows do not reset the remembered previous-arrow direction.
- 0 is even, so it outputs 0.
Examples
Input: (["→", "→", "↑", 3, 4, "↑"],)
Expected Output: [0, 1, 0, 1, 0, 1]
Explanation: First →:0 (no prior arrow); second →:1 (matches); ↑:0 (differs from →); 3:1 (odd); 4:0 (even); final ↑:1 (matches the previous arrow ↑, the 3 and 4 did not reset it).
Input: ([],)
Expected Output: []
Explanation: Empty stream yields an empty output.
Input: ([5],)
Expected Output: [1]
Explanation: 5 is odd.
Input: (["←"],)
Expected Output: [0]
Explanation: A lone arrow has no previous arrow, so 0.
Input: ([0, 1, 2, 7, 8],)
Expected Output: [0, 1, 0, 1, 0]
Explanation: Odd integers 1 and 7 output 1; 0, 2, 8 are even.
Input: (["←", "→", "→", "→", "↑"],)
Expected Output: [0, 0, 1, 1, 0]
Explanation: ←:0; →:0 (differs); →:1; →:1; ↑:0 (differs).
Input: (["↑", 3, "↑"],)
Expected Output: [0, 1, 1]
Explanation: First ↑:0; 3:1 (odd); second ↑:1 because the previous arrow was ↑ (the integer in between is skipped).
Hints
- Maintain a single variable holding the last arrow direction you saw.
- Only arrow tokens update that variable; integers leave it unchanged.
- An odd integer scores 1 regardless of any arrows around it.
- Compare the current arrow to the stored previous arrow before updating the stored value.
Find Identical Strings (Duplicates with Frequencies)
Constraints
- 0 <= number of strings <= 10^6.
- Strings may contain arbitrary Unicode characters, including the empty string.
- Only strings with frequency >= 2 appear in the result.
- Comparison is exact: no implicit case folding or Unicode normalization.
Examples
Input: (["apple", "banana", "apple", "cherry", "banana", "apple"],)
Expected Output: {"apple": 3, "banana": 2}
Explanation: apple appears 3 times and banana 2 times; cherry appears once and is excluded.
Input: ([],)
Expected Output: {}
Explanation: No strings, so no duplicates.
Input: (["unique"],)
Expected Output: {}
Explanation: A single occurrence is not a duplicate.
Input: (["a", "b", "c"],)
Expected Output: {}
Explanation: All distinct, nothing repeats.
Input: (["x", "x", "x", "x"],)
Expected Output: {"x": 4}
Explanation: x appears four times.
Input: (["café", "cafe", "café"],)
Expected Output: {"café": 2}
Explanation: Exact comparison keeps 'café' (with the accent) separate from 'cafe'; only 'café' repeats.
Input: (["", "", "a"],)
Expected Output: {"": 2}
Explanation: The empty string repeats twice; 'a' occurs once.
Hints
- A single pass with a hash map from string to count is enough.
- After counting, filter to entries whose count exceeds 1.
- The empty string is a valid key and can be a duplicate.
- If the input does not fit in memory, fall back to external sort or hash-bucket sharding.