Asked at Citadel Securities, Jump Trading
Theory: Data Structures You Implement, Not ImportRead the problem, hints and solution here. The editor needs a bigger screen: open this page on a laptop to write and run your code.
Available in C++ and Python. You are solving it in Python. Switch to C++
Every low-latency system has a ring buffer somewhere in its hot path: market-data handlers stage packets in one, loggers hand records across threads through one, and exchange gateways queue outbound orders in one. The reason is mechanical sympathy: a fixed block of memory, no allocation after construction, and index arithmetic instead of pointer chasing.
Implement RingBuffer<T>, a fixed-capacity FIFO over a pre-allocated
buffer:
explicit RingBuffer(std::size_t capacity): allocates storage for
exactly capacity elements, once, here. capacity >= 1.bool push(const T& value): appends at the tail; returns false (and
changes nothing) when full.std::optional<T> pop(): removes and returns the head; std::nullopt
when empty.std::optional<T> front() const: the head without removing it.std::size_t size() const, bool empty() const, bool full() const.No std::deque, std::queue, or std::list: the point is the index
arithmetic over contiguous storage (a std::vector<T> sized once in the
constructor is fine as the backing store). Indices must wrap; the buffer
must keep working through many times capacity operations.
[]{ RingBuffer<int> rb(2); std::vector<int> out; out.push_back(rb.push(1)); out.push_back(rb.push(2)); out.push_back(rb.push(3)); return out; }()
// [1, 1, 0] (third push rejected: full)
[]{ RingBuffer<int> rb(2); rb.push(7); rb.push(8); std::vector<int> out; out.push_back(*rb.pop()); rb.push(9); out.push_back(*rb.pop()); out.push_back(*rb.pop()); return out; }()
// [7, 8, 9] (wrap-around preserves FIFO order)
capacity up to \(10^6\).full() and empty() must be exact (the classic head==tail ambiguity is
yours to resolve).The same class, RingBuffer(capacity), with push(value) returning
False when full, pop() and front() returning None when empty, and
size(), empty(), full(). Allocate one list in the constructor and never
call list.pop(0) or insert(0, ...), which shift every element and are
the \(O(n)\) this structure exists to avoid. collections.deque is
banned. The provided driver run_ring_buffer(capacity, ops) applies a list
of operations to a fresh buffer and is what the tests call.