Since you already have a list of the prime factors, what you want to do is to compute the powerset of that list.
Now, one problem is that you might have duplicates in the list (e.g. the prime factors of 20 = 2 * 2 * 5), but sets don't allow duplicates. So, we can make each element of the list unique by projecting it to a structure of the form {x, y} where x is the prime and y is the index of the prime in the list.
var all_primes = primes.Select((x, y) => new { x, y }).ToList();
Now, all_primes
is a list of the form {x, y} where x is the prime and y is the index in the list.
Then we compute the power set (definition of GetPowerSet
below):
var power_set_primes = GetPowerSet(all_primes);
Hence, power_set_primes
is an IEnumerable<IEnumerable<T>>
where T
is the anonymous type {x, y}
where x and y are of type int
.
Next, we compute the product of the each element in the power set
foreach (var p in power_set_primes)
{
var factor = p.Select(x => x.x).Aggregate(1, (x, y) => x * y);
factors.Add(factor);
}
Putting it all together:
var all_primes = primes.Select((x, y) => new { x, y }).ToList(); //assuming that primes contains duplicates.
var power_set_primes = GetPowerSet(all_primes);
var factors = new HashSet<int>();
foreach (var p in power_set_primes)
{
var factor = p.Select(x => x.x).Aggregate(1, (x, y) => x * y);
factors.Add(factor);
}
From http://rosettacode.org/wiki/Power_Set for implementations of powerset.
public IEnumerable<IEnumerable<T>> GetPowerSet<T>(List<T> list)
{
return from m in Enumerable.Range(0, 1 << list.Count)
select
from i in Enumerable.Range(0, list.Count)
where (m & (1 << i)) != 0
select list[i];
}