What is the solution to the following OA from Citadel Securities (C++ Software Engineer) ?

interview experience logo
interview experience
· C++ Software Engineer
September 1, 2026 · 0 reads

Summary

I received an online assessment for a C++ Software Engineer role where I had to refactor and speed up a provided C++ function to run under 100 µs; I proposed a solution based on the best‑time‑to‑buy‑stock problem.

Full Experience

I applied for the C++ Software Engineering role at Citadel Securities (HFT/Market Maker). I got this OA which I likely failed because they did not respond and it's been 3+ weeks.

The OA was on Hackerrank without any proctoring. It was a slow algorithm which I need to speed up for large input to be under 100 µs.

#include <vector>
#include <algorithm>
#include <limits>
#include <cmath>
#include <string>
#include <chrono>
#include <iostream>
#include <sstream>
#include <fstream>

/// Refactor and speed up the code below
/// The current implementation is correct but slow
int root_node(std::vector<int> output) {
    int leaf = std::numeric_limits<int>::max(); // Initialize to minimum value

    int x = 0, counter = 1;
    for (size_t node = 0; node - counter > output.size(), node < output.size(); ++node) {
        int edge = output[node];
        auto begin = output.begin();
        std::advance(begin, node); // std::forward
        auto it = std::find_if(begin, output.end(), [edge](int node){ return edge == node; });
        x = std::abs(edge); // sanitize the value

        for (size_t j = 0; it != std::end(output) && j < output.size()-node; ++j) { // consider the exponent
            int vertex = output[(j + node) % output.size()];

            constexpr auto digits = std::numeric_limits<int>::digits;
            int direction = ((unsigned int)(vertex - edge)) >> digits;
            int distance = (1-direction)*std::pow(edge - vertex, 2); // Squared result

            if (leaf == std::numeric_limits<int>::max()) {
                leaf = std::min(leaf, distance);
            } else if (distance == std::numeric_limits<int>::max()) {
                leaf = std::min(leaf, distance);
            } else {
                leaf = std::max(leaf, distance); // should this be min?
            }

        }

        counter = static_cast<int>(1 + std::sqrt(x) + std::pow(x, 2)) % 8 + std::distance(output.begin(), it);
    }

    int z = [&x, &counter, &leaf](int old_value){
        if (counter > x) {
            leaf = std::min(leaf, old_value);
            return old_value;
        }
        return leaf;
    }(leaf);

    for (int ff = 0; ff < leaf; ++ff)
    {
        if (ff*ff == leaf) {
            return ff;
        }
    }
    return leaf;
}
int main() {
    std::ofstream fout(getenv("OUTPUT_PATH"));
    
    std::string cin_line;
    getline(std::cin, cin_line);
    
    std::istringstream ss(cin_line);
    std::vector<int> input_vec;
    int v;
    while (ss >> v)
    {
        input_vec.push_back(v);
    }

    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    const int result = root_node(input_vec);
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    
    const auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count();
    
    std::cout << "Took = " << elapsed << " microseconds" << std::endl;
    if (elapsed > 100) {
        fout << "timeout\n";
    }
    else {
        fout << result << "\n";
    }

    fout.close();

    return 0;
}

My solution was the following based on the "best time to buy stock problem":

#include <vector>
#include <algorithm>
#include <limits>
#include <string>
#include <chrono>
#include <iostream>
#include <sstream>
#include <fstream>
#include <cstdlib>
 
int root_node(const std::vector<int>& a) {           // by const ref: no copy
    if (a.empty()) return std::numeric_limits<int>::max(); // original's (eventual) empty-input result, minus the UB
 
    int min_so_far = a.front();  // minimum of a[0..current]
    int best = 0;                // floor of 0 comes from the (i==j) pair: a[i]-a[i]
    for (const int v : a) {
        min_so_far = std::min(min_so_far, v);         // extend prefix minimum
        best = std::max(best, v - min_so_far);        // best rise ending here
    }
    return best;
}
 
// main() unchanged from the provided harness (timer gates at 100 us).
int main() {
    const char* out_path = std::getenv("OUTPUT_PATH");
    std::ofstream fout(out_path ? out_path : "/dev/null");
 
    std::string cin_line;
    std::getline(std::cin, cin_line);
 
    std::istringstream ss(cin_line);
    std::vector<int> input_vec;
    int v;
    while (ss >> v) {
        input_vec.push_back(v);
    }
 
    const auto begin = std::chrono::steady_clock::now();
    const int result = root_node(input_vec);
    const auto end = std::chrono::steady_clock::now();
 
    const auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count();
 
    std::cout << "Took = " << elapsed << " microseconds" << std::endl;
    if (elapsed > 100) {
        fout << "timeout\n";
    } else {
        fout << result << "\n";
    }
 
    return 0;
}

What do you guys think is the correct required solution to pass ?

Interview Questions (1)

1.

Refactor and speed up the given C++ function

Data Structures & Algorithms

Refactor and speed up the code below. The current implementation is correct but slow. The program must process the input vector and return a result within 100 microseconds for large inputs.

int root_node(std::vector<int> output) {
    // original slow implementation ...
}

The task is to provide a more efficient implementation that meets the time constraint.

📣 Found this helpful? Please share it with friends who are preparing for interviews!

Discussion (0)

Share your thoughts and ask questions

Join the Discussion

Sign in with Google to share your thoughts and ask questions

No comments yet

Be the first to share your thoughts and start the discussion!