refactor: find_first_factor() refactored

This commit is contained in:
Mateusz Pusz
2022-03-21 11:16:50 +01:00
parent 3729a9fe93
commit ca283b94f6

View File

@@ -55,6 +55,23 @@ constexpr std::optional<std::size_t> 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<class InputIt>
constexpr std::optional<std::size_t> 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<class Rng>
constexpr std::optional<std::size_t> 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<std::size_t N>
constexpr std::array<std::size_t, N> 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)) {
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 (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;
}
}
}
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;
}