Circular Server Scheduling with Recovery
Reported by candidates from ZipRecruiter's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
ZipRecruiter reported this one in October 2022, and it looks like a load balancer question but it's really a simulation with a cyclic pointer and a cooldown timer per server. If you've got an OA invite, expect to spend your time on the rules, not on a clever algorithm. Read the REQUEST, UP and recovery rules twice before you type. If you blank mid-assessment, StealthCoder runs invisibly on your desktop and can hand you a working solution as a safety net. The core job is simple: track each server's state, walk the commands, and count requests per server.
The problem
Servers 0 through serverCount - 1 are cyclic. Command index is its time. Maintain a pointer initially before server 0. REQUEST scans cyclically after the pointer for the first server available at this time. That server processes the request and becomes the pointer. If none is available, drop the request. After a server processes workLimit requests since its last wake, it is unavailable for the next recoveryTime command times; its work counter resets when recovery finishes. UP i immediately makes server i available and resets its work counter; the pointer does not move. Return the smallest server ID among those processing the most requests. Function busiestServer(serverCount: int, workLimit: int, recoveryTime: int, commands: String[]) → int Examples Example 1 serverCount = 3 workLimit = 5 recoveryTime = 2 commands = ["REQUEST","REQUEST","REQUEST","REQUEST"] return = 0 Available servers receive requests cyclically. Example 2 serverCount = 2 workLimit = 1 recoveryTime = 2 commands = ["REQUEST","REQUEST","REQUEST","REQUEST"] return = 0 Servers become available after their recovery windows. Constraints 1 <= serverCount, workLimit <= 1000 0 <= recoveryTime <= 100000 1 <= commands.length <= 100000
Reported by candidates. Source: FastPrep
Pattern and pitfall
What it really reduces to is a direct simulation. Keep four arrays: processed count, work counter since last wake, a busyUntil time (recovery end), and the pointer index. For each command at time t, a REQUEST scans up to serverCount servers starting at pointer+1 modulo serverCount, picks the first with busyUntil <= t, increments its counts, and moves the pointer there. If its work counter hits workLimit, set busyUntil to t + 1 + recoveryTime or whatever the examples confirm, and reset the counter when recovery ends. UP i sets busyUntil to 0 and clears the counter without touching the pointer. The pitfall is the off-by-one on the recovery window, so test it against Example 2. Worst case is 100000 commands times 1000 servers, about 10^8 steps, which is tight. A TreeSet of available servers or a lazy recovery heap gets you under it. If the timing rule trips you up live, StealthCoder is the hedge.
The honest play: practice the pattern, and have StealthCoder ready for the one you didn't see coming.
You can drill Circular Server Scheduling with Recovery 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. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass ZipRecruiter's OA.
ZipRecruiter reuses patterns across OAs. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Circular Server Scheduling with Recovery FAQ
How hard is the ZipRecruiter circular server scheduling problem really?+
Medium. No exotic algorithm, but the rules are fiddly. Most failures come from the recovery window off-by-one and forgetting that UP doesn't move the pointer. Write the simulation brute force first, then optimize only if you need to.
What's the trick to this problem?+
Treat it as a simulation with per-server state: processed count, work counter, and the time it becomes available again. The cyclic scan starts at pointer+1 modulo serverCount. Get those state transitions exact and the rest is bookkeeping.
Will a brute force scan pass the constraints?+
Possibly borderline. Up to 100000 commands times 1000 servers is around 10^8 operations in the worst case. Early exit on the first available server helps a lot. If you're worried, keep a sorted set of available servers and use a ceiling lookup after the pointer.
How should I handle the recovery and UP commands?+
Store a recoveryEnd time per server. Treat a server as available when current time is at or past that value, and reset its work counter at that moment. UP sets recoveryEnd to now and zeroes the counter. Check both against Example 2 by hand.
How do I prepare in 48 hours for this kind of OA?+
Practice two or three cyclic-pointer or scheduling simulations, like the classic busiest servers problem. Write out state variables before coding, then trace the given examples by hand. That habit catches the off-by-one errors this problem is built around.