Project Euler Problem #39!

August 9th, 2009
by Serinox

Problem #39 says:

If p is the perimeter of a right angle triangle with integral length sides, {a,b,c},
there are exactly three solutions for p = 120.
{20,48,52}, {24,45,51}, {30,40,50}
For which value of p ≤ 1000, is the number of solutions maximised?

In order to solve this problem we’re going to need to keep track of a few things, first we need to make sure we have a list of all triangles that we’ve already checked, second we need a HashTable of Perimeters so we can increment a perimeter each time we find a matching triangle.

The second part of the problem is what we need to know about our friend the triangle. First we know that were only looking for perimeters under 1000, second we know its a right triangle. The second is important because it lets us ignore a lot of triangle sets that don’t make a right triangle. So our constraints are a+b+c ≤ 1000 and a^2 + b^2 = c^2.

All of the above brings us to the following c# solution.

using System;
using System.Diagnostics;
using System.Collections;

namespace ProjectEuler
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            int Answer = 0;
            int SideLimit = 998;
            Hashtable Perimeters = new Hashtable();
            ArrayList KnownCombinations = new ArrayList();

            Perimeters.Add(0, 0);

            for (int a = 1; a <= SideLimit; a++)
            {
                Console.WriteLine("a = " + a.ToString());
                for (int b = 1; b <= SideLimit; b++)
                {
                    for (int c = 1; c <= SideLimit; c++)
                    {
                        if (a + b + c <= 1000)
                        {
                            if ((a * a) + (b * b) == (c * c))
                            {
                                if (!KnownCombinations.Contains(OrderBySize(a, b, c)))
                                {
                                    int Count;
                                    if (Perimeters.Contains(a + b + c))
                                    {
                                        Count = (int)Perimeters[a + b + c];
                                    }
                                    else
                                    {
                                        Perimeters.Add(a + b + c, 0);
                                        Count = 0;
                                    }
                                    Count++;
                                    Perimeters[a + b + c] = Count;
                                    KnownCombinations.Add(OrderBySize(a, b, c));

                                }
                            }
                        }
                    }
                }
            }
            foreach (int c in Perimeters.Keys)
            {
                if ((int)Perimeters[c] > (int)Perimeters[Answer])
                {
                    Answer = c;
                }
            }

            Console.WriteLine(Answer);
            sw.Stop();
            Console.WriteLine(sw.Elapsed);
            Console.ReadLine();
        }
        public static string OrderBySize(int a, int b, int c)
        {
            ArrayList tmp = new ArrayList();
            tmp.Add(a);
            tmp.Add(b);
            tmp.Add(c);
            tmp.Sort();
            return ((int)tmp[0]).ToString() + ((int)tmp[1]).ToString() + ((int)tmp[2]).ToString();
        }
    }
}

Posted in Project Euler | Comments (0)

No comments yet

Leave a Reply

You must be logged in to post a comment.