#include "goldbach.h"
#include <iostream>
#include <iterator>
#include <omp.h>

size_t single_goldbach(size_t k)
{
    const std::vector<size_t> relevant_primes = get_primes(k);
    size_t m = relevant_primes.size();

    size_t counter = 0;

#pragma omp parallel for shared(relevant_primes, m, k) reduction(+:counter)
    for(size_t i = 0; i < m; ++i)
    {
        for(size_t j = i; j < m; ++j)
        {
            if(relevant_primes[i] + relevant_primes[j] == k)
                ++counter;
        }
    }

    return counter;
}


std::vector<size_t> count_goldbach(size_t n)
{
    const std::vector<size_t> relevant_primes = get_primes(n);
    size_t m = relevant_primes.size();

    std::vector<size_t> counter_vector(n + 1, 0);

#pragma omp parallel for shared(relevant_primes, m, n) reduction(VecAdd:counter_vector)
    for(size_t i = 0; i < m; ++i)
    {
        for(size_t j = i; j < m; ++j)
        {
            size_t sum = relevant_primes[i] + relevant_primes[j];
            if(sum <= n)
                ++counter_vector[relevant_primes[i] + relevant_primes[j]];
        }
    }

    return counter_vector;
}
