Sign in to run and submit your work
Reading is open to everyone. Running code and saving drafts need an account so your work is yours and comes back on your next visit.
or
CODE WORKSPACE
An on-call dashboard draws a service's per-minute health checks as a strip of coloured blocks. One block per minute is 1,440 blocks a day; what the dashboard really wants is one block per run: two minutes OK, three minutes FAIL, two minutes OK, so an outage reads as a single bar with a length.
Write status_runs(statuses). It takes a list of status strings, one per minute in time order (for example ["OK", "OK", "FAIL", "OK"]), and returns a list of [status, count] pairs, one per run of consecutive equal statuses, in timeline order.
Function to write
status_runs(statuses: list[str]) -> list[list]A list of [status, count] runs of consecutive equal statuses, in timeline order.
How to approach it
You only ever need to compare a status with the run that is still open, which is the last run you built. Anything older is already closed.
Sample cases
+ 4 held back until you submit
an outage between two healthy runs
OK appears before and after the outage, so it is two separate runs with FAIL between them.
Input
Argument 1
[
'OK',
'OK',
'FAIL',
'FAIL',
'FAIL',
'OK',
'OK'
]Returns
[
[
'OK',
2
],
[
'FAIL',
3
],
[
'OK',
2
]
]a flapping check
Every minute differs from the last, so there are four one-minute runs, not two groups of two.
Input
Argument 1
[
'OK',
'FAIL',
'OK',
'FAIL'
]Returns
[
[
'OK',
1
],
[
'FAIL',
1
],
[
'OK',
1
],
[
'FAIL',
1
]
]an empty timeline
No checks means no runs: return an empty list, not None and not an error.
Input
Argument 1
[] (empty list)
Returns
[] (empty list)
Constraints
OK, OK, FAIL, OK is three runs, not two groups.[status, count] (lists, not tuples) in the order the runs happen. Every count is a positive integer.OK and ok are different statuses. Do not normalise them.[]. A timeline with one status throughout returns a single run.Worked example
Take "an outage between two healthy runs": ["OK", "OK", "FAIL", "FAIL", "FAIL", "OK", "OK"]. Start with no runs. Minute 1 is OK: open ["OK", 1]. Minute 2 is OK and matches the open run, so it becomes ["OK", 2]. Minute 3 is FAIL, which differs, so open ["FAIL", 1]; minutes 4 and 5 grow it to 3. Minute 6 is OK and differs from the open FAIL run, so it opens a new ["OK", 1], grown to 2 by minute 7. The result is [["OK", 2], ["FAIL", 3], ["OK", 2]].
The trap is counting by value. A Counter over the same input gives OK 4 and FAIL 3, which is two groups where the timeline has three runs, and on "a flapping check" it turns four one-minute runs into two groups of two.
What this tests
Run-length encoding: LeetCode 'String Compression' (problem 443) and the grouping half of 'Count and Say', in data clothing. O(n) time in one pass and O(r) space for r runs; the only state is the run currently open. Neither 'String Compression' nor run-length encoding is named in the data engineering interview reports we could find. A data engineer meets it when collapsing a status timeline into incidents, sessionising events by consecutive state, or solving the gaps-and-islands streak problem that SQL handles with a difference of ROW_NUMBERs.
status_runs(statuses: list[str]) -> list[list]Submit for review to find out what your query gets right, what it gets wrong, and how it compares with the best working query for this exercise.
This scenario runs a full workspace — editor, canvas and results side by side. It needs a laptop or desktop to be usable. Open this page on a bigger screen to start building.