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.
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).Run your code to check it against the sample tests. Results appear here.