#include <iostream>
#include <vector>
#include <random>
#include <chrono>

std::vector<std::vector<bool>> generate_random_bool_vectors(size_t numVectors, size_t vectorSize) {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::bernoulli_distribution dist(0.5);

    std::vector<std::vector<bool>> vectors(numVectors, std::vector<bool>(vectorSize));
    for (size_t i = 0; i < numVectors; ++i) {
        for (size_t j = 0; j < vectorSize; ++j) {
            vectors[i][j] = dist(gen);
        }
    }

    return vectors;
}

int count_xor(const std::vector<bool>& x, const std::vector<bool>& y) {
    // Check if the input vectors have the same size
    if (x.size() != y.size()) {
        std::cerr << "Error: Input vectors must have the same size!" << std::endl;
        return -1;  // Error code
    }

    int count = 0;
    for (size_t i = 0; i < x.size(); ++i) {
        // XOR operation and count the number of 1s
        count = count + x[i] ^ y[i];
    }

    return count;
}

int main() {
    // Example usage with boolean vectors
    size_t vectorSize = 512;
    size_t numVectors = 10000;

    std::vector<std::vector<bool>> x = generate_random_bool_vectors(numVectors, vectorSize);
    std::vector<std::vector<bool>> y = generate_random_bool_vectors(numVectors, vectorSize);

    // Measure the execution time of the count_xor function for each vector pair
    std::vector<std::vector<int>> results(numVectors, std::vector<int>(numVectors));
    auto start = std::chrono::high_resolution_clock::now();
    for (size_t i = 0; i < numVectors; ++i) {
        for (size_t j = 0; j < numVectors; ++j) {
            results[i][j] = count_xor(x[i], y[j]);
        }
    }
    auto end = std::chrono::high_resolution_clock::now();

    // // Print some example results
    // size_t numResultsToPrint = 5;
    // for (size_t i = 0; i < numResultsToPrint; ++i) {
    //     for (size_t j = 0; j < numResultsToPrint; ++j) {
    //         std::cout << "Count XOR (x[" << i << "], y[" << j << "]): " << results[i][j] << std::endl;
    //     }
    // }

    // Calculate and print the execution time
    std::chrono::duration<double> duration = end - start;
    std::cout << "Execution time: " << duration.count() << " seconds" << std::endl;

    return 0;
}
