Design crypto trading order control API
Company: Coinbase
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates understanding of state management and finite-state machines, API design for lifecycle control, and implementation of in-memory data structures and transition validation in the Coding & Algorithms category.
Constraints
- 0 <= len(orders) <= 200000
- 0 <= len(operations) <= 200000
- Each `orderId` in `orders` is unique
- Each initial state is one of `NEW`, `ACTIVE`, `PAUSED`, `CANCELLED`, `FILLED`
- Each operation action is one of `pause`, `resume`, or `cancel`
Examples
Input: ([('o1', 'ACTIVE'), ('o2', 'PAUSED'), ('o3', 'FILLED')], [('pause', 'o1'), ('resume', 'o2'), ('cancel', 'o1'), ('cancel', 'o3')])
Expected Output: ([True, True, True, False], [('o1', 'CANCELLED'), ('o2', 'ACTIVE'), ('o3', 'FILLED')])
Explanation: o1 is paused, o2 is resumed, then o1 is cancelled from PAUSED. Cancelling a FILLED order fails.
Input: ([('a', 'NEW'), ('b', 'CANCELLED'), ('c', 'ACTIVE')], [('pause', 'a'), ('resume', 'c'), ('cancel', 'b'), ('cancel', 'x'), ('cancel', 'c'), ('pause', 'c')])
Expected Output: ([False, False, False, False, True, False], [('a', 'NEW'), ('b', 'CANCELLED'), ('c', 'CANCELLED')])
Explanation: NEW cannot be paused, ACTIVE cannot be resumed, CANCELLED cannot be cancelled again, unknown order x fails, c is cancelled successfully, and then cannot be paused afterward.
Input: ([('btc', 'ACTIVE')], [('pause', 'btc'), ('resume', 'btc'), ('pause', 'btc'), ('cancel', 'btc'), ('resume', 'btc')])
Expected Output: ([True, True, True, True, False], [('btc', 'CANCELLED')])
Explanation: The order moves ACTIVE -> PAUSED -> ACTIVE -> PAUSED -> CANCELLED. After cancellation, resume fails.
Input: ([('z', 'PAUSED')], [])
Expected Output: ([], [('z', 'PAUSED')])
Explanation: With no operations, the state remains unchanged.
Input: ([], [('pause', 'ghost'), ('cancel', 'ghost')])
Expected Output: ([False, False], [])
Explanation: There are no stored orders, so every operation fails.
Solution
def solution(orders, operations):
states = {}
order_sequence = []
for order_id, state in orders:
states[order_id] = state
order_sequence.append(order_id)
transitions = {
'pause': {'ACTIVE': 'PAUSED'},
'resume': {'PAUSED': 'ACTIVE'},
'cancel': {'ACTIVE': 'CANCELLED', 'PAUSED': 'CANCELLED'}
}
results = []
for action, order_id in operations:
if order_id not in states or action not in transitions:
results.append(False)
continue
current_state = states[order_id]
next_state = transitions[action].get(current_state)
if next_state is None:
results.append(False)
else:
states[order_id] = next_state
results.append(True)
final_states = [(order_id, states[order_id]) for order_id in order_sequence]
return results, final_states
Time complexity: O(n + m), where n is the number of orders and m is the number of operations. Space complexity: O(n).
Hints
- A dictionary keyed by `orderId` lets you find and update an order's current state in O(1) time.
- Instead of writing many nested `if` statements, consider storing allowed transitions in a table like `(action, current_state) -> next_state`.