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

std::vector<std::bitset<512>> generate_random_bit_vectors(size_t numVectors) {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<size_t> dist(0, 1);

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

    return vectors;
}

int count_xor(const std::bitset<512>& x, const std::bitset<512>& y) {
    std::bitset<512> result = x ^ y;
    return result.count();
}

int main() {
    // Example usage with dynamic_bitset
    size_t numVectors = 800000;

    std::vector<std::bitset<512>> x = generate_random_bit_vectors(numVectors);
    std::vector<std::bitset<512>> y = generate_random_bit_vectors(numVectors);

    // 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;
}
