diff --git a/src/core/include/units/bits/prime.h b/src/core/include/units/bits/prime.h index b9e06e72..eb77e503 100644 --- a/src/core/include/units/bits/prime.h +++ b/src/core/include/units/bits/prime.h @@ -55,6 +55,23 @@ constexpr std::optional first_factor_maybe(std::size_t n, std::size return std::nullopt; } +// TODO refactor two below functions with std::ranges when moved to modules +template +constexpr std::optional first_factor_maybe(InputIt first, InputIt last, std::size_t n, + std::size_t offset = 0) +{ + for (; first != last; ++first) + if (const auto k = first_factor_maybe(n, *first + offset)) return *k; + return {}; +} + +template +constexpr std::optional first_factor_maybe(const Rng& rng, std::size_t n, std::size_t offset = 0) +{ + using std::begin, std::end; + return first_factor_maybe(begin(rng), end(rng), n, offset); +} + template constexpr std::array first_n_primes() { @@ -136,26 +153,11 @@ struct wheel_factorizer { static constexpr std::size_t find_first_factor(std::size_t n) { - for (const auto& p : basis) { - if (const auto k = first_factor_maybe(n, p)) { - return *k; - } - } - - for (auto it = std::next(std::begin(coprimes_in_first_wheel)); it != std::end(coprimes_in_first_wheel); ++it) { - if (const auto k = first_factor_maybe(n, *it)) { - return *k; - } - } - - for (std::size_t wheel = wheel_size; wheel < n; wheel += wheel_size) { - for (const auto& p : coprimes_in_first_wheel) { - if (const auto k = first_factor_maybe(n, wheel + p)) { - return *k; - } - } - } - + if (const auto k = first_factor_maybe(basis, n)) return *k; + if (const auto k = first_factor_maybe(std::next(begin(coprimes_in_first_wheel)), end(coprimes_in_first_wheel), n)) + return *k; + for (std::size_t wheel = wheel_size; wheel < n; wheel += wheel_size) + if (const auto k = first_factor_maybe(coprimes_in_first_wheel, n, wheel)) return *k; return n; }