I am trying to write a function in Java that will return the number of factors a specific number has.
The following restrictions should be taken into account.
- It should be done with BigInteger
- Storing the previously generated numbers is not allowed, thus more processing and less memory. (You can not use "Sieve of Atkin" like in this)
- Negative numbers can be ignored.
This is what I have so far, but it is extremely slow.
public static int getNumberOfFactors(BigInteger number) {
// If the number is 1
int numberOfFactors = 1;
if (number.compareTo(BigInteger.ONE) <= 0) {
return numberOfFactors;
}
BigInteger boundry = number.divide(new BigInteger("2"));
BigInteger counter = new BigInteger("2");
while (counter.compareTo(boundry) <= 0) {
if (number.mod(counter).compareTo(BigInteger.ZERO) == 0) {
numberOfFactors++;
}
counter = counter.add(BigInteger.ONE);
}
// For the number it self
numberOfFactors++;
return numberOfFactors;
}
I can propose faster solution, though I have a feeling that it will not be fast enough yet. Your solution runs in
O(n)and mine will work inO(sqrt(n)).I am going to use the fact that if n = xi1p1 * xi2p2 * xi3p3 * … xikpk is the prime factorization of
n(i.e. xij are all distinct primes) then n has (p1 + 1) * (p2 + 1) * … * (pk + 1) factors in total.Now here goes the solution:
This can be further optimized if you consider the case of 2 separately and then have the step for
xequal to 2 not 1 (iterating only the odd numbers).Also note that in my code I modify
number, you might find it more suitable to keepnumberand have another variable equal tonumberto iterate over.I suppose that this code will run reasonably fast for numbers not greater than 264.
EDIT I will add the measures of reasonably fast to the answer for completeness. As it can be seen in the comments below I made several measurements on the performance of the proposed algorithm for the test case 1000000072, which was proposed by Betlista:
whileto comparing with the square root ofnumberwhich I find using binary search the time taken reduces to 22 second.BigIntegers withlongthe time was reduced to 2 seconds. As the proposed algorithm will not run fast enough fornumberlarger than the range oflongit might make sense to switch the implementation tolong