Вопрос

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.

Это было полезно?

Решение

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.

Другие советы

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.

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top