What is the most efficient algorithm to print all unique combinations of factors of a positive integer. For example if the given number is 24 then the output should be
bool isprime(int n){
for(int i=2; i<=sqrt(n); i++)
if(n%i==0)
return false;
return true;
}
void printprime(int n){
int i,j,y=n;
while(y%2==0){
cout<<"2 * ";
y/=2;
}
for(i=3; i<=sqrt(y); i+=2){
while(y%i==0){
cout<<i<<" * ";
y/=i;
}
}
if(y>2)
cout<<y;
}
void allfacs(int n){
int i;
unordered_set<int> done;
for(i=2; i<sqrt(n); i++){
if(n%i==0){
cout<<i<<" * "<<n/i<<endl;
if(!isprime(i) && done.find(i) == done.end()){
done.insert(i);
printprime(i);
cout<<n/i<<endl;
}
if(!isprime(n/i) && done.find(n/i) == done.end()){
done.insert(n/i);
cout<<i<< " * ";
printprime(n/i);
cout<<endl;
}
}
}
}
Here is my solution based on @rici's ideas.
def factors(number, max_factor=sys.maxint):
result = []
factor = min(number / 2, max_factor)
while factor >= 2:
if number % factor == 0:
divisor = number / factor
if divisor <= factor and divisor <= max_factor:
result.append([factor, divisor])
result.extend([factor] + item for item in factors(divisor, factor))
factor -= 1
return result
print factors(12) # -> [[6, 2], [4, 3], [3, 2, 2]]
print factors(24) # -> [[12, 2], [8, 3], [6, 4], [6, 2, 2], [4, 3, 2], [3, 2, 2, 2]]
print factors(157) # -> []
#include<bits/stdc++.h>
using namespace std;
int n;
// prod = current product of factors in combination vector
// curr = current factor
void fun(int curr, int prod, vector<int> combination )
{
if(prod==n)
{
for(int j=0; j<combination.size(); j++)
{
cout<<combination[j]<<" ";
}
cout<<endl;
return;
}
for(int i=curr; i<n; i++)
{
if(i*prod>n) break;
if(n%i==0)
{
combination.push_back(i);
fun(i, i*prod, combination);
combination.resize(combination.size()-1);
}
}
}
int main()
{
cin>>n;
vector<int> combination;
fun(2, 1, combination);
cout<<1<<" "<<n;
return 0;
}
vector<unsigned int> GetAllFactors(unsigned int number)
{
vector<unsigned int> factors;
for (int i = 2; i <= number; i++)
{
if (number % i == 0)
{
factors.push_back(i);
}
}
return factors;
}
void DoCombinationWithRepetitionFactors(vector<unsigned int> allFactors, unsigned currentProduct, unsigned targetProduct, vector<unsigned int> currentFactorSet, unsigned currentFactorIndex)
{
if (currentProduct == targetProduct)
{
for (auto a : currentFactorSet)
{
cout << a << " , ";
}
cout << endl;
return;
}
for (int i = currentFactorIndex; i < allFactors.size(); i++)
{
if (currentProduct * allFactors[i] <= targetProduct)
{
currentFactorSet.push_back(allFactors[i]);
DoCombinationWithRepetitionFactors(allFactors, currentProduct * allFactors[i], targetProduct, currentFactorSet, i);
currentFactorSet.pop_back();
}
}
}
I came up with this, seems easy to read and understand. Hope it helps!
def getFactors(num):
results = []
if num == 1 or 0:
return [num]
for i in range(num/2, 1, -1):
if (num % i == 0):
divisor = num / i
if(divisor <= i):
results.append([i, divisor])
innerResults = getFactors(divisor)
for innerResult in innerResults:
if innerResult[0] <= i:
results.append([i] + innerResult)
return results
Try this recursive approach that also takes in 2 more inputs namely a string to carry over the current value of i in for loop to perform subsequent reduction and also a temp int to know when not to print duplicate reversals i.e., 8*3 and 3*8.
public static void printFactors(int number, String parentFactors, int parentVal) {
int newVal = parentVal;
for (int i = number - 1; i >= 2; i--) {
if (number % i == 0) {
if (newVal > i) {
newVal = i;
}
if (number / i <= parentVal && i <= parentVal
&& number / i <= i) {
System.out.println(parentFactors + i + "*" + number / i);
newVal = number / i;
}
if (i <= parentVal) {
printFactors(number / i, parentFactors + i + "*", newVal);
}
}
}
}
And call this method using printFactors(12,'',12)
Let me know if you find flaws in this approach. Thanks!