The Tallest Stacks
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
- mid
- Asked in
- A.P. Moller - Maersk
Problem
A terminal operations export logs one row per vessel call, each row naming the terminal that handled the call and the teu (container volume) it moved. For each terminal, report its two highest unique teu values, largest first, so a volume hit on several calls still counts only once. A terminal with only a single volume reports just that value, and an empty export reports nothing.
Every terminal has its records. Find the two that stand tallest.
Example 1
Input:
readings = [{"teu":1200,"terminal":"Rotterdam"},{"teu":1200,"terminal":"Rotterdam"},{"teu":950,"terminal":"Rotterdam"},{"teu":800,"terminal":"Rotterdam"},{"teu":1500,"terminal":"Singapore"},{"teu":1500,"terminal":"Singapore"}]Output:
{"Rotterdam":[1200,950],"Singapore":[1500]}Example 2
Input:
readings = [{"teu":700,"terminal":"Shanghai"},{"teu":900,"terminal":"Shanghai"},{"teu":850,"terminal":"Shanghai"},{"teu":900,"terminal":"Shanghai"}]Output:
{"Shanghai":[900,850]}Worked solution and explanation
Why this problem exists in real interviews
This is the 'second highest salary' chestnut wearing a shipping manifest, generalized one notch to top-two-distinct per group. The skill being probed: can you compute a per-key runner-up without letting duplicate maxima fool you? Anyone can group the rows and sort them. The trap is that the highest volume usually shows up on more than one vessel call, so the moment you sort a terminal's raw volumes largest-first and slice the top two, you get the same number twice. Get that wrong and Rotterdam reports [1200, 1200] when its real second-place volume was 950.
Break down the requirements
Step 1: Bucket the volumes by terminal
One pass over the rows, accumulating each terminal's volumes. Because the very next step needs uniqueness, accumulate straight into a set per terminal rather than a list. defaultdict(set) gives you an empty set on first touch so you can .add() without an existence check.
Step 2: Dedup is the whole point, not an afterthought
The spec says a volume hit on several calls counts once. Collapsing to distinct values is what separates the real second-highest from a repeated max. Doing it as you bucket (the set in step 1) means the ordering step never sees a duplicate.
Step 3: Take the two largest, and let short groups self-handle
Sort each terminal's distinct values from largest to smallest and slice the first two. The slice is what makes one-value terminals fall out for free: [v][:2] is just [v], no special branch needed. An empty export never enters the loop, so it returns an empty dict naturally.
The solution
from collections import defaultdict
def top_two_by_terminal(readings):
volumes = defaultdict(set)
for row in readings:
volumes[row["terminal"]].add(row["teu"])
return {
terminal: sorted(distinct, reverse=True)[:2]
for terminal, distinct in volumes.items()
}- Naive: sort then slice
sorted([1200, 1200, 950, 800], reverse=True)[:2]returns [1200, 1200]. The duplicate maximum eats both slots and the true second place, 950, never surfaces.- Correct: distinct, then slice
sorted({1200, 950, 800}, reverse=True)[:2]returns [1200, 950]. Collapsing to a set first guarantees the two slots hold two different volumes.
Common follow-up questions
- What changes if you need the top K distinct volumes per terminal instead of two, with K passed in? (Tests generalizing the slice to `[:k]` and noticing that `heapq.nlargest(k, distinct)` is the cleaner tool once K is small relative to the distinct count.)
- The export now streams in at billions of rows and will not fit in memory. How do you keep this per terminal? (Tests maintaining a bounded structure per key (a small top-2 tracker or a per-key heap) in a single streaming pass, or a distributed group-by-then-reduce, instead of materializing every value.)
- How would you return the second-highest only, and what should happen for a terminal with a single distinct volume? (Tests the explicit absent-runner-up decision: return `None`, omit the terminal, or raise, and pinning that contract before coding.)