Highway toll checkpoints from plate logs
A highway has numbered toll checkpoints. Each checkpoint's name contains its position as a number, for example "A1" is at position 1 and "CP12" is at position 12. Ignore every non-digit character when reading the position.
Each time a car passes a checkpoint, the system logs (timestamp, plate, checkpoint). A car pays |p1 - p2| * 10 for each move between two checkpoints it passes one after the other. A car seen only once pays nothing.
Implement:
-
position(checkpoint) -> int: the position from the name. Raise an error if the name has no digits. -
bills(logs) -> Dict[str, int]: the total toll for each plate. The logs may arrive in any order; charge each car's sightings in timestamp order. - A streaming
TollTrackerwithrecord(timestamp, plate, checkpoint) -> int(returns the fee for this move) andtotal(plate) -> int. Events arrive in timestamp order. Each call must be O(1), and memory must not grow with the number of events. - Trip boundaries: with an optional
trip_gap, two sightings of the same car more thantrip_gapapart belong to different trips, and the move between them is free.
Constraints
- Up to 10^6 log entries; positions fit in a 32-bit integer.
- Timestamps are integers. A plate never has two sightings with the same timestamp.
Example
logs = [(3, "KX-210", "N2"), (1, "KX-210", "N8"), (7, "KX-210", "N6"),
(4, "JB-77", "N3")]
bills(logs) -> {"KX-210": 100, "JB-77": 0}
# KX-210 in time order: N8 -> N2 -> N6, so 6*10 + 4*10 = 100
Trip gap
logs = [(0, "V", "A1"), (10, "V", "A4"), (500, "V", "A9"), (510, "V", "A6")]
bills(logs) -> {"V": 110} # 30 + 50 + 30
bills(logs, trip_gap=100) -> {"V": 60} # A4 -> A9 crosses a 490 gap, so it is free
Interviewers often follow up with logs too large for memory, late events in a stream, and different rates per segment.
Sign in to see the worked answer
The full answer, chapter by chapter, with what interviewers expect at each level. Free with an account: one full answer per company.
