/* * Test of variants of the sieve of Eratosthenes (C++) * by Project Nayuki, 2022. Public domain. * https://www.nayuki.io/page/the-versatile-sieve-of-eratosthenes */ #include #include #include #include #include #include #include "EratosthenesSieves.hpp" using std::size_t; using std::uint32_t; using std::vector; // Forward declarations static void testValues(); static void testPrefixConsistency(); int main() { try { testValues(); testPrefixConsistency(); std::cerr << "Test passed" << std::endl; return EXIT_SUCCESS; } catch (std::exception &e) { std::cerr << e.what() << std::endl; return EXIT_FAILURE; } } static void testValues() { { vector expect{false, false, true, true, false, true, false, true, false, false, false, true, false, true, false, false, false, true, false, true, false, false, false, true, false, false, false, false, false, true, false}; vector actual = sievePrimeness(expect.size() - 1); if (actual != expect) throw std::runtime_error("Mismatch"); } { vector expect{0, 1, 2, 3, 2, 5, 2, 7, 2, 3, 2, 11, 2, 13, 2, 3, 2, 17, 2, 19, 2, 3, 2, 23, 2, 5, 2, 3, 2, 29, 2}; vector actual = sieveSmallestPrimeFactor(expect.size() - 1); if (actual != expect) throw std::runtime_error("Mismatch"); } { vector expect{0, 1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16, 6, 18, 8, 12, 10, 22, 8, 20, 12, 18, 12, 28, 8}; vector actual = sieveTotient(expect.size() - 1); if (actual != expect) throw std::runtime_error("Mismatch"); } { vector expect{0, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 3}; vector actual = sieveOmega(expect.size() - 1); if (actual != expect) throw std::runtime_error("Mismatch"); } { vector expect{0, 1, 2, 3, 2, 5, 6, 7, 2, 3, 10, 11, 6, 13, 14, 15, 2, 17, 6, 19, 10, 21, 22, 23, 6, 5, 26, 3, 14, 29, 30}; vector actual = sieveRadical(expect.size() - 1); if (actual != expect) throw std::runtime_error("Mismatch"); } } static void testPrefixConsistency() { const uint32_t N = 10000; { vector prev; for (uint32_t i = 0; i < N; i++) { vector cur = sievePrimeness(i); for (uint32_t j = 0; j < i; j++) { if (cur.at(j) != prev.at(j)) throw std::runtime_error("Mismatch"); } prev = cur; } } { vector (*)(uint32_t)> FUNCS{ sieveSmallestPrimeFactor, sieveTotient, sieveOmega, sieveRadical, }; for (vector (*func)(uint32_t) : FUNCS) { vector prev; for (uint32_t i = 0; i < N; i++) { vector cur = func(i); for (uint32_t j = 0; j < i; j++) { if (cur.at(j) != prev.at(j)) throw std::runtime_error("Mismatch"); } prev = cur; } } } }