Courier Drone: Fastest Fixed-Distance Segment From Tick Logs
OptiverSoftware Engineer · Online AssessmentLast updated
From per-tick distance logs, find the highest average speed over any time span that covers exactly a target distance, where spans may start and end partway through a tick. Tests prefix sums, linear interpolation, and showing that an optimal span touches a tick boundary.
A delivery drone reports its progress in fixed ticks. ticks[i] is the number of meters it flew during tick i. Every tick lasts tick_seconds seconds, so tick i covers the time range [i * tick_seconds, (i + 1) * tick_seconds].
Inside a tick the drone flies at a constant speed. After t seconds of tick i it has covered ticks[i] * t / tick_seconds meters of that tick.
The operations team wants the drone's best target-meter segment: the highest average speed over any continuous time span [a, b] in which the drone covers exactly target meters. That average is target / (b - a).
def best_segment_speed(ticks: list[int], tick_seconds: float, target: int) -> float: ...
Rules:
aandbcan be any real times with0 <= a < b <= len(ticks) * tick_seconds. A span can start or end partway through a tick.- Ticks with 0 meters (hovering) still count toward the elapsed time of any span that contains them.
- A span can sit entirely inside one tick if that tick alone covers at least
targetmeters. - Answers within
1e-6relative error are accepted.
Examples
ticks = [100, 100, 100, 100, 100], tick_seconds = 10, target = 500
answer = 10.0
The drone holds a steady 10 m/s, so every 500 m span takes 50 s.
ticks = [50, 300, 0, 250, 150], tick_seconds = 10, target = 500
answer = 17.857142857... (= 500 / 28)
Start at t = 10 (the start of the 300 m tick). Then fly 300 m, hover for 10 s, and fly 200 of the next 250 m in 8 s. That is 28 s in total. No other span is shorter.
ticks = [20, 900, 40], tick_seconds = 10, target = 500
answer = 90.0
The middle tick alone moves at 90 m/s, so 500 m fit inside it.
Constraints
1 <= len(ticks) <= 10^5,0 <= ticks[i] <= 10^51 <= target,sum(ticks) >= target- Running totals can exceed 2^31. Use 64-bit integers in fixed-width languages.
- Aim for O(n log n) or O(n).
Hints
Hint 1
Build prefix sums P so that P[i] is the distance covered by the start of tick i. Cumulative distance D(t) is then a piecewise-linear, non-decreasing function of time.
Hint 2
Fix the start a. The end b is the earliest time with D(b) = D(a) + target, and you can find it with a binary search over P plus one interpolation.
Hint 3
Think about the span length b(a) - a as a function of a. Between the points where a or b crosses a tick boundary, it is linear. Where must a minimum of a piecewise-linear function lie?
Hint 4
So you only need two families of candidates: spans that start on a tick boundary and spans that end on one.
Follow-up questions
- Make it O(n) with two pointers. What invariant makes the pointer monotone?
- Ops also wants the slowest target-meter segment. Does the boundary argument still hold?
- What if speed inside a tick changed linearly instead of staying constant?
- How would you answer many different targets on the same log efficiently?
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.