Skip to content

Commit

Permalink
Set callback logic for prime factors
Browse files Browse the repository at this point in the history
  • Loading branch information
1Git2Clone committed Jan 11, 2025
1 parent 047f1b7 commit 60b504a
Showing 1 changed file with 38 additions and 17 deletions.
55 changes: 38 additions & 17 deletions src/utils/primes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "concepts.hpp"
#include <algorithm>
#include <cmath>
#include <functional>
#include <iostream>
#include <ranges>
#include <vector>
Expand Down Expand Up @@ -39,58 +40,78 @@ template <Integer T> bool is_prime(const T &n) {
// -----------------------------------------------------------------------------

/**
* Applies a callback function `f` to all the prime factors of a number: `n`.
*
* ---
*
* Implemented in O(sqrt(n)) space via the segmented sieve of eratosthenes
* algorithm[1].
*
* [1]:
* https://cp-algorithms.com/algebra/sieve-of-eratosthenes.hpptml#segmented-sieve
*/
template <Integer T> std::vector<T> get_prime_factors(const T &n) {
template <Integer T>
void operate_on_prime_factors(const T &n, std::function<void(const T &)> f) {
if (n <= 1)
return std::vector<T>();
if (is_prime(n))
return std::vector<T>{n};
return;

if (is_prime(n)) {
f(n);
return;
}

std::vector<T> primes;
if (n <= 8) {
// sqrt(n) < 3
if (n % 2 == 0)
primes.push_back(2);
f(2);
if (n % 3 == 0)
primes.push_back(3);
f(3);

return primes;
return;
}

T n_sqrt = static_cast<T>(std::sqrt(n));
std::vector<bool> is_prime(n_sqrt + 2, true);

for (const T &i : std::ranges::views::iota((T)2, (T)(n_sqrt + 1))) {
for (const T &i : std::ranges::views::iota(static_cast<T>(2), n_sqrt + 1)) {
if (is_prime[i]) {
if (n % i == 0) {
primes.push_back(i);
f(i);
}
for (T j = i * i; j <= n_sqrt; j += i) {
is_prime[j] = false;
}
}
};

return primes;
return;
}

/**
* Gets all the prime fractors from the `get_prime_factors` function and prints
* them to `stdout`.
* Returns all the prime factors of a number: `n` in a vector.
*/
template <Integer T> std::vector<T> print_prime_factors(const T &n) {
std::vector<T> nums = get_prime_factors(n);
template <Integer T> std::vector<T> get_prime_factors(const T &n) {
std::vector<T> primes;

operate_on_prime_factors(
n, std::function<void(const T &)>(
[&primes](const T &prime) { primes.push_back(prime); }));

return primes;
}

/**
* Prints all the prime factors of a number: `n` in a vector.
*/
template <Integer T> void print_prime_factors(const T &n) {
std::cout << "{ ";
std::ranges::for_each(nums, [](const T &num) { std::cout << num << " "; });
operate_on_prime_factors(n,
std::function<void(const T &)>([](const T &prime) {
std::cout << prime << " ";
}));
std::cout << "}" << std::endl;

return nums;
return;
}

#endif // !UTILS_PRIMES_HPP

0 comments on commit 60b504a

Please sign in to comment.