Round and Round They Go
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L4
- Asked in
- PwC
Problem
We're distributing a list of integer values (with duplicates) across a rotating set of containers, where each container is named 'set', 'list', or 'tuple'. Gather every occurrence of each distinct value into its own group, then hand the groups out, smallest value first, to the containers one at a time, wrapping back to the first container after the last. A 'set' container keeps each value only once; any other keeps the group exactly as gathered.
Each face waits its turn as the wheel comes back around.
Example
Input:
values = [1,2,3,4,5,5,1,1,3,6], containers = ["set","list","tuple"]
Output:
[{"values":[1],"container":"set"},{"values":[2],"container":"list"},{"values":[3,3],"container":"tuple"},{"values":[4],"container":"set"},{"values":[5,5],"container":"list"},{"values":[6],"container":"tuple"}]Worked solution and explanation
What this really is
Strip the costume and this is a two-phase group-then-dispatch: build a group per distinct value, walk the groups in a fixed order, and let a wrapping index over the container list decide each group's shape. The trap is order. If you emit groups in insertion order instead of sorted-value order, every group lands in the wrong container, and if you forget that only 'set' deduplicates, your set groups keep the duplicates they were supposed to collapse. Both mistakes still run cleanly; they just produce a quietly wrong answer.
Break down the requirements
Step 1: Build groups in sorted-key order
Walk values once and append each occurrence to groups[v]. Then iterate the keys in sorted order so the group sequence is deterministic.
Step 2: Rotate through containers by position
For group index i, the container is the one at the wrapping position over containers. This is the rotation; the wrap handles running past the end of the list.
Step 3: Apply the per-container transform
Only the 'set' container changes the values: it deduplicates, and since every occurrence in a group is the same value, that leaves a single copy. For 'list' and 'tuple', leave the group's values in their gathered sequence. Wrap the result as {'values': shaped, 'container': container}.
The solution
def distribute(values: list[int], containers: list[str]) -> list[dict]:
groups: dict[int, list[int]] = {}
for v in values:
groups.setdefault(v, []).append(v)
out = []
for i, key in enumerate(sorted(groups)):
container = containers[i % len(containers)]
group = groups[key]
if container == 'set':
shaped = list(set(group))
else:
shaped = list(group)
out.append({'values': shaped, 'container': container})
return outCommon follow-up questions
- What does the result look like when the number of distinct keys is less than the number of containers? Are the unused containers visible anywhere? (Tests that unused containers are simply never assigned to.)
- How would you add a fourth container type (say 'frozenset' or '`sorted_list`') without re-touching the dispatcher? (Tests extensibility via a strategy mapping rather than an inline if/elif chain.)
- What if the values were dicts instead of integers? Which container would break first and how would you guard it? (Tests awareness that unhashable types cannot be set elements, requiring a fallback.)