Reported September 2026
Etchedheap priority queue

Periodic Event Loop

Reported by candidates from Etched's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.

Get StealthCoderRuns invisibly during the live Etched OA. Under 2s to a working solution.
Founder's read

Etched reported this one in September 2026, and the name "Periodic Event Loop" makes it sound fancier than it is. Strip the framing and it's a merge of sorted streams: each event emits times period, 2*period, up to runLimits[i] runs, and you output everything at or before the horizon ordered by time, then by event ID. You don't simulate every tick up to a billion. You pull the next due event from a heap. If you blank during the live OA, StealthCoder is the silent backup that reads the problem and hands you the heap solution.

The problem

At time zero, register periodic events. Event i first executes at periods[i] and should execute at each multiple of that period until it has run runLimits[i] times. A run limit models a callback returning false after that execution.
Execute only events due at or before horizon. When several events are due together, run smaller eventIds first. Return an execution log of strings time:eventId. Event IDs are unique.

Function
runPeriodicEvents(eventIds: String[], periods: int[], runLimits: int[], horizon: int) → String[]

Examples
Example 1
eventIds = ["beat","flush"]
periods = [2,3]
runLimits = [3,2]
horizon = 6
return = ["2:beat","3:flush","4:beat","6:beat","6:flush"]
The events execute at 2:beat, 3:flush, 4:beat, then both at time 6 in ID order.
Example 2
eventIds = ["z","a"]
periods = [4,4]
runLimits = [1,1]
horizon = 4
return = ["4:a","4:z"]
Equal due times are ordered lexicographically by event ID.

Constraints
0 <= eventIds.length = periods.length = runLimits.length <= 100000
1 <= periods[i], horizon <= 1000000000
0 <= runLimits[i] <= 100000
The returned log contains at most 200000 entries.

Reported by candidates. Source: FastPrep

Pattern and pitfall

The trick is a min-heap keyed on (nextTime, eventId). Push every event with runLimits above zero at time periods[i]. Pop the smallest, append "time:eventId" if time is at or before horizon, then if runs remain, push it back at time plus period. Once the popped time exceeds horizon, stop, since everything left is later. Pitfall one: looping over time from 1 to horizon. Horizon reaches 1e9, so that dies. Pitfall two: comparing IDs wrong. Use plain string comparison, not numeric or length-first. Pitfall three: forgetting runLimits of 0 means the event never runs. Use a 64-bit type for time plus period if your language needs it. Complexity is O(n + k log n) where k is the log size, capped at 200000. If the heap comparator or tuple ordering trips you up mid-assessment, StealthCoder is the hedge that gives you a clean version fast.

StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.

If this hits your live OA

You can drill Periodic Event Loop cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. If you're reading this with an OA window open, you're who this was built for.

Get StealthCoder

Related leaked OAs

⏵ The honest play

You've seen the question. Make sure you actually pass Etched's OA.

Etched reuses patterns across OAs. If you're reading this with an OA window open, you're who this was built for. Works on HackerRank, CodeSignal, CoderPad, and Karat.

Periodic Event Loop FAQ

What's the trick in Periodic Event Loop?+

Don't simulate time. Use a min-heap of (nextDueTime, eventId). Pop the earliest, log it, and push it back at time plus period if runs remain. Stop when the popped time passes the horizon. Ties break on event ID automatically through the tuple ordering.

How hard is this Etched OA question really?+

Medium at most. The idea is a standard priority-queue merge. The difficulty is noticing that horizon goes up to 1e9, which rules out tick-by-tick simulation, and handling ties and zero run limits correctly.

Do I need a heap, or can I just sort?+

Sorting works too. Generate every (time, id) pair for each event up to min(runLimits[i], horizon / period) runs, then sort. The output is capped at 200000 entries, so that's safe. The heap is cleaner on memory and stops early.

What edge cases break solutions here?+

Empty input returns an empty list. A runLimit of 0 means the event never fires. A period larger than the horizon means no runs. Two events due at the same time must sort by ID as strings. Watch overflow when adding period to time in fixed-width integer languages.

How do I prepare for this in 48 hours?+

Write a heap-based k-way merge from scratch twice, with a tuple comparator on time then string ID. Practice the stop condition and the re-push logic. That covers this problem and most scheduler-style OA questions without needing broader study.

Problem reported by candidates from a real Online Assessment. Sourced from a publicly-available candidate-aggregated repository. Not affiliated with Etched.

OA at Etched?
Invisible during screen share
Get it