Problem with Project Euler Problem 12
I'm having trouble with Project Euler's problem 12. My code is correctly generating the series, as far as I can tell, and it gets the correct solution to the test problem. I don't believe that long
is getting overflowed because it does return a solution, just not the correct one. Any thoughts?
The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
1: 1 3: 1,3 6: 1,2,3,6 10: 1,2,5,10 15: 1,3,5,15 21: 1,3,7,21 28: 1,2,4,7,14,28 We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
class Program
{
static long lastTriangle = 1;
static void Main(string[] args)
{
long x = 1;
do
{
x = nextTriangle(x);
Console.WriteLine(x);
} while (numDivisors(x) < 500);
Console.WriteLine(x);
Console.ReadLine();
}
static long nextTriangle(long arg)
{
lastTriangle += 1;
long toReturn = lastTriangle + arg;
return toReturn;
}
static long numDivisors(long arg)
{
long count = 0;
long lastDivisor = 0;
开发者_StackOverflow Boolean atHalfWay = false;
for (long x = 1; x <= arg && !atHalfWay; x++)
{
if (arg % x == 0 && x != lastDivisor)
{
count++;
lastDivisor = arg / x;
}
else if (x == lastDivisor)
{
atHalfWay = true;
}
}
return count*2;
}
}
If x
is a square numDivisors
counts the square root of x
twice.
The problem isn't that the square roots of perfect squares are counted twice. When arg is a square, numDivisors(arg)
gives a completely wrong answer, not just one off. Consider arg = 36
. When x = 4
, lastDivisor gets set to 9. Next iteration, x = 5;
if (36 % 5 == 0 && 5 != 9) // 36 % 5 == 1
else if (5 == 9)
// Nothing done, next x
if (36 % 6 == 0 && 6 != 9) // true
{
count++;
lastDivisor = 36 / 6; // 6
}
// next x
if (36 % 7 == 0 && 7 != 6) // 36 % 7 == 1
else if (7 == 6)
// next x
Now x will never equal lastDivisor and the loop runs until x == 36
, so all divisors are counted twice.
Another mistake your condition while (numDivisors(x) < 500)
, the problem asks for the first triangle number with more than 500 divisors, if there was one with exactly 500 divisors before, you'd find that.
Exercise for the reader: why is it - in the problem as stated - not necessary to check for squares and count the square root only once?
精彩评论