Divisors of triangle numbers (Euler 12)

1.2k views Asked by At

I have found a couple of topics related to this very problem, I just want to know why my code returns incorrect data. So we have to find the first triangle number having more than 500 divisors. Details can be found here: http://projecteuler.net/problem=12 And here is my code:

Int64 triangularnum = 1;
            for (Int64 num = 2; num > 0; num++)
            {
                if(has501Divisors(triangularnum))
                {
                    MessageBox.Show(triangularnum.ToString());
                    break;
                }
                triangularnum += num;
            }



private bool has501Divisors(Int64 candidate)
        {
            bool has501 = false;
            int count = 0;
            for (int i = 1; i < Math.Sqrt(candidate); i++)
            {
                if (candidate % i == 0) count += 1;
                if (count > 501)
                {
                    return true;
                }
            }
            return has501;
        }

This gives me number 842161320 which is apparently incorrect.

3

There are 3 answers

0
Soner Gönül On BEST ANSWER

You should increment your count number by 2 not 1.

Also your

if (count > 501)

part is incorrect because your boundary should 500 not 501. Change it to count > 500 instead of.

static void Main(string[] args)
{
    Console.WriteLine(Find());
}

public static int Find()
{
    int number = 0;
    for (int i = 1; ; i++)
    {
        number += i; // number is triangle number i
        if (CountDivisorsOfNumber(number) > 500)
            return number;
    }
}


private static int CountDivisorsOfNumber(int number)
{
     int count = 0;
     int end = (int)Math.Sqrt(number);
     for (int i = 1; i < end; i++)
     {
         if (number % i == 0)
             count += 2;
     }
     if (end * end == number) // Perfect square
         count++;
     return count;
}

This prints 76576500 and looks like a right solution.

2
Carra On

Quick look but your check isn't ok:

if (count > 501)

This will stop at count 502, not 501.


for (int i = 1; i < Math.Sqrt(candidate); i++)

9 is divisible by 3, so you should use <= here. Also, you're divising by 1, you should start at i = 2.

3
vcsjones On

The problem is you are limiting your loop to the square root, which is smart, however that means you need to increment your count by two, not by 1 to account for both divisors.

Change your incrementation to this:

if (candidate % i == 0) count += 2;

Additionally, your count check checks for greater than 501 divisors, not 500.