List Unallocated Experiment Buckets
PinterestSoftware Engineer · Technical ScreenLast updated
Determine all unassigned experiment bucket IDs in the range [0, total_buckets - 1] given lists of control and treatment bucket allocations.
Problem Statement
In an experimentation platform, user traffic is hashed into total_buckets discrete buckets indexed from 0 to total_buckets - 1. An experiment configuration assigns subsets of these buckets to a control group and one or more enabled_groups (treatment variants).
Due to manual configuration or upstream errors, input allocations may contain:
- Duplicate bucket IDs within the same group or across different groups.
- Out-of-bounds bucket IDs (negative integers or integers
>= total_buckets), which should be ignored.
Write a function find_unallocated_buckets that returns an ascending list of all bucket IDs in [0, total_buckets - 1] that have not been assigned to either the control group or any enabled group.
Function Signature
def find_unallocated_buckets(
total_buckets: int,
control: list[int],
enabled_groups: list[list[int]]
) -> list[int]:
pass
Input & Output Format
- Input:
total_buckets: Non-negative integer representing the capacity range[0, total_buckets - 1].control: A list of integer bucket IDs assigned to control.enabled_groups: A list of lists, where each sublist contains integer bucket IDs assigned to a treatment variant.
- Output:
- A list of unique integers representing unallocated buckets, sorted in ascending order.
Examples
Example 1
total_buckets = 10
control = [0, 2, 2, 15] # 15 is out of bounds, 2 is duplicated
enabled_groups = [
[3, 4],
[4, 7] # 4 is duplicated across groups
]
# Output: [1, 5, 6, 8, 9]
Explanation: Valid assigned buckets are 0, 2, 3, 4, and 7. Buckets 1, 5, 6, 8, and 9 remain unassigned.
Example 2
total_buckets = 4
control = [0, 1]
enabled_groups = [[2, 3]]
# Output: []
Explanation: All buckets 0 through 3 are allocated.
Constraints
1 <= total_buckets <= 100,0000 <= len(control) <= 100,0000 <= len(enabled_groups) <= 1,0000 <= sum(len(group) for group in enabled_groups) <= 100,000- Bucket IDs in inputs can be any 32-bit signed integer.
Hints
Hint 1
Identify which data structure allows you to track visited bucket indices with O(1) updates and lookups.
Hint 2
Be sure to filter out any IDs smaller than 0 or greater than or equal to total_buckets before marking them as allocated.
Hint 3
A boolean array or bitset of size total_buckets allows you to mark seen buckets and then collect unallocated ones in sorted order in a single pass.
Follow-up questions
- How would you adapt your solution if total_buckets was 10^12 and allocations were provided as contiguous closed intervals [start, end]?
- How would you modify the function to detect and return overlapping bucket allocations across different groups as conflict errors?
- If this check runs as a validation service handling thousands of requests per second with mostly fixed total_buckets = 1000, what optimizations would you introduce?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.