#define ENABLE_MU_0_TESTING
#include <FactorTable.hpp>
#include <generate.hpp>
#include <stdint.h>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <random>
using namespace primecount;
void check(bool OK)
{
std::cout << " " << (OK ? "OK" : "ERROR") << "\n";
if (!OK)
std::exit(1);
}
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dist(500000, 1000000);
auto max = dist(gen);
auto threads = max % 4;
auto lpf = generate_lpf(max);
auto mu = generate_moebius(max);
FactorTable<uint16_t> factorTable(max, threads);
int64_t uint16_max = std::numeric_limits<uint16_t>::max();
int64_t limit = factorTable.first_coprime();
std::vector<int> small_primes = { 2, 3, 5, 7, 11, 13, 17, 19 };
for (int n = 1; n <= max; n++)
{
int64_t i = factorTable.to_index(n);
bool is_prime = (lpf[n] == n);
for (int p : small_primes)
{
if (p >= limit)
break;
if (n % p == 0)
goto not_coprime;
}
std::cout << "mu(" << n << ") = " << factorTable.mu(i);
check(mu[n] == factorTable.mu(i));
std::cout << "lpf(" << n << ") = " << lpf[n];
if (n == 1)
check(factorTable.mu_lpf(i) == uint16_max - 1);
else if (is_prime)
check(factorTable.mu_lpf(i) == uint16_max);
else if (mu[n] == 0)
check(factorTable.mu_lpf(i) == 0);
else
check(lpf[n] == factorTable.mu_lpf(i) + (factorTable.mu(i) == 1));
not_coprime:;
}
std::cout << std::endl;
std::cout << "All tests passed successfully!" << std::endl;
return 0;
}