Advance a Circular Buffer
Checking your account…
Sign in to save your code and progress across devices. The lesson and problem statement remain public.
Loading the interactive Practice workspace.If it does not appear, the problem and learning material remain readable, but browser execution is unavailable.Reload Practice workspace
Problem
Implement simulate_circular_buffer(capacity, actions). Each action is ["put", value] or ["get"]. Ignore put when full. For every get, append the oldest value to the returned list, or None when empty. capacity is positive.
Starter code
def simulate_circular_buffer(capacity, actions):
passTest cases
wraparound
{
"args": [
3,
[
[
"put",
1
],
[
"put",
2
],
[
"get"
],
[
"put",
3
],
[
"put",
4
],
[
"get"
],
[
"get"
],
[
"get"
]
]
]
}Expected: [1,2,3,4]
ignore-full-put
{
"args": [
2,
[
[
"put",
"a"
],
[
"put",
"b"
],
[
"put",
"c"
],
[
"get"
],
[
"get"
]
]
]
}Expected: ["a","b"]
Wizard outline
- Step 1: Report empty reads
Append None for each get action while the buffer has no stored values. Empty behavior defines the output contract before storage indexes start moving.
- Step 2: Preserve basic FIFO order
Track head, tail, and size so puts are read back in insertion order before wraparound. A non-wrapping trace makes each state variable meaning visible before modulo is applied.
- Step 3: Wrap bounded cursors
Apply modulo to both cursors and ignore put actions while size equals capacity. Modulo and the full guard convert the linear FIFO trace into a reusable fixed-size circular buffer.
Footguns and prerequisites
- Using head == tail alone cannot distinguish an empty buffer from a full one.
- Incrementing indices without modulo eventually writes outside fixed storage.
- python specific rapid fire
Reviewed references
Prepared Interview Problems
- Design Circular Queue(opens in a new tab)
Advance a Circular Buffer isolates head identifies the oldest live value, tail identifies the next write slot, and size stays between zero and capacity. That focused state discipline is required when implementing design circular queue as a complete Interview Problem.
- Implement Stack Using Queues(opens in a new tab)
Advance a Circular Buffer isolates head identifies the oldest live value, tail identifies the next write slot, and size stays between zero and capacity. That focused state discipline is required when implementing implement stack using queues as a complete Interview Problem.
Recommended approach and implementation
A bounded FIFO can reuse fixed storage when head, tail, and size make full and empty states explicit. head identifies the oldest live value, tail identifies the next write slot, and size stays between zero and capacity.
Why it works: Enqueue writes at tail then advances it modulo capacity, while dequeue reads at head then advances it the same way. Size distinguishes full from empty when indices coincide, so every operation preserves FIFO order.
def simulate_circular_buffer(capacity, actions):
storage = [None] * capacity
head = tail = size = 0
output = []
for action in actions:
if action[0] == 'put':
if size < capacity:
storage[tail] = action[1]
tail = (tail + 1) % capacity
size += 1
else:
if size == 0:
output.append(None)
else:
output.append(storage[head])
head = (head + 1) % capacity
size -= 1
return output