Ad Score Scheduler With Delay
Reported by candidates from Google's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Google's July 2026 OA reports include this ad scheduler problem, and it looks like a messy simulation until you see what it really reduces to: a max-heap of ready ads plus a queue of ads on cooldown. Every GET is a tick. You release ads whose cooldown just ended, pop the best one, drop its score by 1, and park it. That's the whole thing. The traps are in the tick counting and the tie-breaking. If you blank on the cooldown math under the clock, StealthCoder runs invisibly as a safety net during the live OA.
The problem
Process the operations in operations against an advertisement scheduler. Each operation is one of: INSERT id score delay: insert a new advertisement with a unique identifier, its current integer score, and a nonnegative delay. GET: return the eligible advertisement with the highest current score. If several eligible ads have the same score, return the lexicographically smallest identifier. After an ad is returned, decrease its score by 1. An advertisement returned by a GET cannot be returned on the next max(1, delay) GET calls. This guarantees that the same advertisement is never returned consecutively, even when its declared delay is 0. Calls that return no ad still count toward every waiting period. If no advertisement is eligible, return NONE. Inserted advertisements remain registered for the rest of the simulation. Return the result of every GET operation in order. Function runAdScheduler(operations: String[]) → String[] Examples Example 1 operations = ["INSERT alpha 5 0","INSERT beta 4 0","GET","GET","GET"] return = ["alpha","beta","alpha"] alpha wins the first call and its score becomes 4. It cannot repeat immediately, so beta is returned next. On the third call, alpha is eligible again and has the larger score. Example 2 operations = ["INSERT a 10 2","INSERT b 5 0","GET","GET","GET","GET"] return = ["a","b","NONE","a"] After the first result, a must sit out two calls. After the second result, b must sit out one call, so the third call has no eligible ad. Both are eligible by the fourth call, and a has the larger score. Constraints 1 <= operations.length <= 100000 Every operation is exactly GET or has the form INSERT id score delay. Each identifier contains 1 through 20 lowercase English letters and is inserted exactly once. -1000000000 <= score <= 1000000000 0 <= delay <= operations.length
Reported by candidates. Source: FastPrep
Pattern and pitfall
Keep a global GET counter. Each ad gets a ready time. When GET number t returns an ad, set its ready time to t + max(1, delay) + 1, so it can't appear in the next max(1, delay) calls. Use a min-heap on ready time for waiting ads and a max-heap on (score, then smallest id) for eligible ones. At the start of each GET, move every waiting ad whose ready time is at most t into the eligible heap. Pop the top, or output NONE. NONE calls still advance the counter, which is the classic pitfall. Another is INSERT mid-stream: a new ad is eligible immediately. Check Example 2 by hand: a with delay 2 returns on call 1 and is back on call 4. Complexity is O(n log n). Python needs a tuple key like (-score, id). Scores can go negative, so don't treat 0 as a sentinel. StealthCoder is your hedge if the heap bookkeeping slips.
StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.
You can drill Ad Score Scheduler With Delay 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 StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Google's OA.
Google 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.
Ad Score Scheduler With Delay FAQ
What's the trick in the Google Ad Score Scheduler problem?+
Split ads into two structures: a max-heap of eligible ads ordered by score then id, and a cooldown queue or min-heap keyed by ready time. Each GET advances a counter, releases ads that finished waiting, then pops the best one. Everything else is careful off-by-one handling.
How do I compute when an ad becomes eligible again?+
If an ad is returned on GET number t, it can't appear for the next max(1, delay) GETs. So it's eligible again at call t + max(1, delay) + 1. Check against Example 2: a, returned on call 1 with delay 2, is back on call 4.
Do GET calls that return NONE count toward cooldowns?+
Yes. The problem says calls with no ad still count toward every waiting period. Increment your tick counter on every GET regardless of the result, or your cooldowns will run long and fail the tests that include NONE outputs.
How do I handle ties on score?+
Return the lexicographically smallest identifier. In a min-heap language, push (-score, id). Strings compare lexicographically by default, so the smaller id wins. In a comparator-based language, compare score descending, then id ascending.
How should I prepare for this in 48 hours?+
Write a heap-plus-cooldown simulation from scratch and test it on both examples. Add edge cases: delay 0, a long delay, consecutive NONE results, and negative scores. Aim for O(n log n) with up to 100000 operations. Parsing the INSERT strings cleanly matters too.