Reputation: 31
I was reading through the solution to Project Euler Problem 12 on MathBlog and I have some trouble understanding the logic behind the codes. The program uses prime factorisation to find the number of divisors of a triangle number.
private int PrimeFactorisationNoD(int number, int[] primelist) {
int nod = 1;
int exponent;
int remain = number;
for (int i = 0; i < primelist.Length; i++) {
// In case there is a remainder this is a prime factor as well
// The exponent of that factor is 1
if (**primelist[i] * primelist[i] > number**) {
return nod * 2;
}
exponent = 1;
while (remain % primelist[i] == 0) {
exponent++;
remain = remain / primelist[i];
}
nod *= exponent;
//If there is no remainder, return the count
if (remain == 1) {
return nod;
}
}
return nod;
}
I understand most part of the program except for the highlighted portion "primelist[i] * primelist[i] > number". I have trouble understanding the necessity of the this line of code. I will use an example to illustrate my point. Let say I have a number 510 = 2*3*5*17. The highlighted code will only be true when Primelist goes to number 23. But by the time the list goes to number 17, the condition remain == 1 will be true and program would have exited the loop. Would it be better if I change the code to if(remain==primelist[i]) since the loop would end when primelist goes to number 17 instead of 21?
Upvotes: 1
Views: 452
Reputation: 56802
First, it should better use remain
:
primelist[i] * primelist[i] > remain
It is an optimization, as there can be no divisors between the square root of remain
and remain
, so you only have the factor remain
left.
Also, the variable name exponent
is lying, it really contains the exponent plus one. Better initialize it to zero and multiply by exponent + 1
.
Upvotes: 0
Reputation: 433
The if condition speeds up the code in certain situations (although it should have "remain" in place of "number"). Once primelist[i] is reached we know that remain is not divisible by primelist[0] through primelist[i-1]. If primelist[i]^2>remain then we can conclude that remain is some prime between primelist[i] and primelist[i]^2-1 (inclusive), as if remain=ab then both a,b would have to be at least primelist[i] so remain would be at least primelist[i]^2, a contradiction. Thus we can stop searching for primes dividing remain.
For an example where this is faster, take number=7. Then the condition is triggered when we reach 3 (as 3^2=9>7), so we do not need to check all the primes up to 7.
Upvotes: 2