I've got an assignment which sounds like this:
Given a number \$m\$ and \$n\$ other numbers, say if the \$m\$-th root of the product of those numbers is a whole number (print 1) or not (print 0). If yes, also print, in sorted order, the result of the \$m\$-th root, decomposed in prime factors.
This is how the expression would look:
$$\sqrt[m]{x_1 x_2 x_3 \dots x_n}$$
My idea was this: for the result to be a whole number, if we were to decompose all of the numbers, then make the product of all of them, every power of every base has to be divisible with \$m\$.
This is what I came up with:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
using Prime_factorization = vector < pair<int, int> >;
void add_base_and_power(Prime_factorization& prime_factorization, int base, int power)
{
// Check if we've already got the base we're trying to add
auto it = find_if(prime_factorization.begin(), prime_factorization.end(), [&](pair <int, int> p) { return p.first == base; } );
if (it != prime_factorization.end()) // If yes, add the power to the existing base
it->second += power;
else
prime_factorization.push_back(make_pair(base, power)); // Else, create a new base
}
void check_if_is_factor(Prime_factorization& prime_factorization, int &number, int divisor)
{
if (number % divisor == 0) { // If the divisor is a base, we divide until it no longer can
int power { 0 };
while (number % divisor == 0) {
number /= divisor;
++power;
}
// Add base and power to factorization
add_base_and_power(prime_factorization, divisor, power);
}
}
void decompose(Prime_factorization& prime_factorization, int number)
{
check_if_is_factor(prime_factorization, number, 2); // Check if it divides by 2 so after that we can only check for uneven bases
for (int div { 3 }; div * div <= number && number > 1; div += 2)
check_if_is_factor(prime_factorization, number, div);
// If number is bigger than 1 it means we got out of the previous for loop with the first condition, so the number must be prime
if (number > 1)
add_base_and_power(prime_factorization, number, 1);
}
int main() {
// Get m-th root
int m;
cin >> m;
// Get number of terms
int n;
cin >> n;
// Take n numbers and decompose each of them
Prime_factorization prime_factorization;
for (int i { 1 }; i <= n; ++i) {
int x;
cin >> x;
decompose(prime_factorization, x);
}
// After decomposing all of the numbers, we check to see if each power can be divided by m(the root)
bool okay { true };
for (auto& i : prime_factorization)
if (i.second % m != 0) {
okay = false;
break;
}
// We must print the base-power combinations in sorted order
sort(prime_factorization.begin(), prime_factorization.end(), [](pair<int, int> p1, pair<int, int> p2) { return p1.first < p2.first; });
if (okay) {
cout << 1 << '\n';
for (auto& i : prime_factorization)
cout << i.first << ' ' << (i.second / m) << '\n';
} else
cout << 0;
}
How could I improve my code? Is there any better algorithm you might've thought of?