Posts Tagged ‘c#’

Project Euler Problem #102!

July 15th, 2010

Problem 102 says:

Three distinct points are plotted at random on a Cartesian plane, for which -1000 ≤ x, y ≤ 1000, such that a triangle is formed.

Consider the following two triangles:

A(-340,495), B(-153,-910), C(835,-947)

X(-175,41), Y(-421,-714), Z(574,-645)

It can be verified that triangle ABC contains the origin, whereas triangle XYZ does not.

This problem can be solved in a lot of different ways depending on how one wishes to approach it. You can find the angle of each two point pair of the triangle and the origin and check to see if they add to 360 degrees which would mean the point is inside the triangle, construct a special matrix and take the determinant, etc. However I chose to use a half plane method because it was quicker to implement and didn’t take that much longer to run. Basically we take the two point pairings of the points of the triangle and check to see if the origin is on the same side for all of them. I make the assumption that because they did not mention how points on the edge of the triangle should be handled that there are no such points which allows us to skip some checking.

Solution provided in c#/mono, runs in about .01 second including reading the file.

using System;
using System.Diagnostics;
using System.Drawing;
namespace Problem102
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			PointF origin = new PointF(0f,0f);
			Stopwatch sw = new Stopwatch();
			sw.Start();

			int TrianglesWithOrigin = 0;

			string line;
			System.IO.StreamReader file = new System.IO.StreamReader("triangles.txt");
			while((line = file.ReadLine()) != null)
			{
				string[] values = line.Split(',');
				PointF p1 = new PointF(float.Parse(values[0]),float.Parse(values[1]));
				PointF p2 = new PointF(float.Parse(values[2]),float.Parse(values[3]));
				PointF p3 = new PointF(float.Parse(values[4]),float.Parse(values[5]));
				if (Inside(origin,p1,p2,p3))
					TrianglesWithOrigin += 1;
			}
			file.Close();
			sw.Stop();
			Console.WriteLine(TrianglesWithOrigin);
			Console.WriteLine(sw.Elapsed);
			Console.ReadLine();
		}
		public static float Sign (PointF p1, PointF p2, PointF p3)
		{
			return (p1.X - p3.X) * (p2.Y - p3.Y) - (p2.X - p3.X) * (p1.Y - p3.Y);
		}
		public static bool Inside (PointF pt, PointF p1, PointF p2, PointF p3)
		{
			bool b1 = Sign(pt, p1, p2) < 0.0f;
			bool b2 = Sign(pt, p2, p3) < 0.0f;
  			bool b3 = Sign(pt, p3, p1) < 0.0f;
			return ((b1 == b2) && (b2 == b3));
		}

	}
}

Tags: , ,
Posted in Project Euler | Comments (0)

Project Euler Problem #75!

May 5th, 2010

Problem #75 says:

It turns out that 12 cm is the smallest length of wire that can be bent to form an integer
sided right angle triangle in exactly one way, but there are many more examples.

12 cm: (3,4,5)
24 cm: (6,8,10)
30 cm: (5,12,13)
36 cm: (9,12,15)
40 cm: (8,15,17)
48 cm: (12,16,20)

In contrast, some lengths of wire, like 20 cm, cannot be bent to form an integer sided right
angle triangle, and other lengths allow more than one solution to be found; for example,
using 120 cm it is possible to form exactly three different integer sided right angle triangles.

120 cm: (30,40,50), (20,48,52), (24,45,51)

Given that L is the length of the wire, for how many values of L ≤ 1,500,000 can exactly
one integer sided right angle triangle be formed?

Another counting problem but here we have to avoid duplicate entries that can come from a variety
of places. This solution uses the 2 number approach for generating Pythagorean triples, which it then finds
the lengths of the triple and catalogs it in an array to track duplicates, Then counts all the values of the
array that equal 1 for the final answer.

Solution is provided in c#/mono. Runs in under one second.

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

namespace Problem75
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			Stopwatch sw = new Stopwatch();
			sw.Start();
			int limit = 1500000;
			int adjlimit = (int)(Math.Sqrt((float)limit));
			ArrayList tri = new ArrayList(limit);

			for (int st = 0; st < limit+1; st++)
				tri.Add(0);

			for (int i = 1; i <= adjlimit; i=i+2)
			{
				for (int j = 2; j<= adjlimit; j=j+2)
				{
					if (GCD(i,j) == 1)
					{
						int sum = Math.Abs((j*j) - (i*i)) + (2*j*i) + ((i*i) + (j*j));
						for (int s = sum; s < limit; s=s+sum)
						{

							tri[s] = (int)tri[s]+1;
						}
					}
				}
			}
			Console.WriteLine(TallyResults(tri));
			sw.Stop();
			Console.WriteLine(sw.Elapsed);
			Console.ReadLine();
		}
		public static int TallyResults(ArrayList a)
		{
			int RetVal = 0;
			foreach (int i in a)
			{
				if (i == 1)
					RetVal= RetVal+1;
			}
			return RetVal;
		}
		public static int GCD (int a, int b)
		{
			if (b == 0)
				return a;
			else
				return GCD(b,(a%b));
		}
	}
}

Tags: , , ,
Posted in Project Euler | Comments (0)

Project Euler Problem #51!

February 26th, 2010

Problem #51 says:

By replacing the 1st digit of *3, it turns out that six of the nine possible values: 13, 23, 43, 53, 73, and 83, are all prime.

By replacing the 3rd and 4th digits of 56**3 with the same digit, this 5-digit number is the first example having seven primes among the ten generated numbers, yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 56993. Consequently 56003, being the first member of this family, is the smallest prime with this property.

Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an eight prime value family.

For this problem what we need to look for are prime numbers that have repeating digits. We replace all of the similar digits with a new value. This means that the digits we replace cannot include the last digit because this will make the number non-prime for almost every replacement. The simplest way to do this is to pre-compute the digit that we are going to replace before going through all of the numbers and swapping digits out. So we have a class called CheckSet which does this for us allowing us to focus on swapping the digits and checking to see if the result is prime.

Solution below is in c#/mono and runs in about 18 seconds.

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

namespace ProjectEuler
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			Stopwatch sw = new Stopwatch();
			sw.Start();
			ArrayList p = GeneratePrimes(999999);
			ArrayList sub_p = new ArrayList();
			foreach (long l in p)
			{
				if (l > 100000)
				{
					CheckSet c = new CheckSet(l);
					if (c.DigitCount >= 1)
					{
						sub_p.Add(c);
					}
				}
			}

			foreach (CheckSet c in sub_p)
			{
				int size = FamilySize(ref p,c);
				if (size >=8)
				{
					Console.WriteLine(c.ToString());
					sw.Stop();
					Console.WriteLine(sw.Elapsed);
					Console.ReadLine();
					break;
				}
			}

		}
		static bool IsPrime(ref ArrayList primes, long num)
		{
			bool RetVal = true;
			long check = Convert.ToInt64(Math.Ceiling(Math.Sqrt(Convert.ToDouble(num))));
			foreach (long l in primes)
			{
				if (l > check)
					break;
				if (num % l == 0)
					RetVal = false;
			}
			return RetVal;
		}
        static ArrayList GeneratePrimes(long num)
        {
            ArrayList RetValue = new ArrayList();
            RetValue.Add((long)2);
            RetValue.Add((long)3);
            long Stepper = 5;
            long Check = 1;
            while (Stepper <= num)
            {
                foreach (long i in RetValue)
                {
                    if (Stepper % i == 0)
                    {
                        Check = 0;
                        break;
                    }
                    if (Math.Sqrt(Stepper) < i)
                    {
                        break;
                    }
                }
                if (Check == 1)
                {
                    //Console.WriteLine(((float)Stepper / (float)num) * 100);
                    RetValue.Add(Stepper);
                }
                Check = 1;
                Stepper++;
                Stepper++;
            }
            return RetValue;
        }
		static int FamilySize (ref ArrayList primes, CheckSet c)
		{
			int RetVal = 0;
			int[] digits = new int[10] {0,1,2,3,4,5,6,7,8,9};
			string num = c.Number.ToString();
			string cha = c.Digit;

			for (int i = 0; i<10;i++)
			{
				if (primes.Contains(long.Parse(num.Replace(cha,digits[i].ToString())))
                    && long.Parse(num.Replace(cha,digits[i].ToString())).ToString().Length == 6)
				{
					RetVal++;
				}
			}

			return RetVal;
		}
	}
	class CheckSet
	{
		public long Number;
		public string Digit;
		public int DigitCount;
		public CheckSet(long number)
		{
			Number = number;
			string s = number.ToString();
			string lastc = s[s.Length-1].ToString();
			int lengthcheck = s.Length;
			int[] digits = new int[10] {0,0,0,0,0,0,0,0,0,0};
			if (lastc != "0")
			{
				s = s.Replace("0","");
				digits[0] = lengthcheck - s.Length;
				lengthcheck = s.Length;
			}
			if (lastc != "1")
			{
				s = s.Replace("1","");
				digits[1] = lengthcheck - s.Length;
				lengthcheck = s.Length;
			}
			if (lastc != "2")
			{
				s = s.Replace("2","");
				digits[2] = lengthcheck - s.Length;
				lengthcheck = s.Length;
			}
			if (lastc != "3")
			{
				s = s.Replace("3","");
				digits[3] = lengthcheck - s.Length;
				lengthcheck = s.Length;
			}
			if (lastc != "4")
			{
				s = s.Replace("4","");
				digits[4] = lengthcheck - s.Length;
				lengthcheck = s.Length;
			}
			if (lastc != "5")
			{
				s = s.Replace("5","");
				digits[5] = lengthcheck - s.Length;
				lengthcheck = s.Length;
			}
			if (lastc != "6")
			{
				s = s.Replace("6","");
				digits[6] = lengthcheck - s.Length;
				lengthcheck = s.Length;
			}
			if (lastc != "7")
			{
				s = s.Replace("7","");
				digits[7] = lengthcheck - s.Length;
				lengthcheck = s.Length;
			}
			if (lastc != "8")
			{
				s = s.Replace("8","");
				digits[8] = lengthcheck - s.Length;
				lengthcheck = s.Length;
			}
			if (lastc != "9")
			{
				s = s.Replace("9","");
				digits[9] = lengthcheck - s.Length;
				lengthcheck = s.Length;
			}
			int MostCommonDigit = 0;
			int MostCommonDigitCount = 0;

			for (int i = 0;i<10;i++)
			{
				if (digits[i] > MostCommonDigitCount)
				{
					MostCommonDigit = i;
					MostCommonDigitCount = digits[i];
				}
			}

			Digit = MostCommonDigit.ToString();
			DigitCount = MostCommonDigitCount;
		}
		public override string ToString ()
		{
			return string.Format(Number.ToString() + " :: " + Digit+ " :: " + DigitCount.ToString());
		}

	}
}

Tags: , , ,
Posted in Project Euler | Comments (0)

Project Euler Problem #60!

February 22nd, 2010

Problem #60 says:

The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.

Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.

At first I thought of writing a class that would generate all permutations for the possible answers. It was simpler to write a simple program that generates a list of primes and loops through it. Solution below is c#/mono and runs in 20 or so seconds.

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

namespace ProjectEuler
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			Stopwatch sw = new Stopwatch();
			sw.Start();
			ArrayList p = GeneratePrimes(10000);

			foreach (long i1 in p)
			{
				foreach (long i2 in p)
				{
					if (i2 <= i1) continue;
					if (!IsPrime(ref p, long.Parse(i1.ToString() + i2.ToString())) ||
                                            !IsPrime(ref p, long.Parse(i2.ToString() + i1.ToString())))
					{
						continue;
					}
					foreach (long i3 in p)
					{
						if (i3 <= i2) continue;
						if (!IsPrime(ref p, long.Parse(i1.ToString() + i3.ToString())) ||
                                                    !IsPrime(ref p, long.Parse(i3.ToString() + i1.ToString())) ||
						    !IsPrime(ref p, long.Parse(i2.ToString() + i3.ToString())) ||
                                                    !IsPrime(ref p, long.Parse(i3.ToString() + i2.ToString())))
						{
							continue;
						}
						foreach(long i4 in p)
						{
							if (i4 <= i3) continue;
							if (!IsPrime(ref p, long.Parse(i4.ToString() + i3.ToString())) ||
                                                            !IsPrime(ref p, long.Parse(i3.ToString() + i4.ToString())) ||
						       	    !IsPrime(ref p, long.Parse(i2.ToString() + i4.ToString())) ||
                                                            !IsPrime(ref p, long.Parse(i4.ToString() + i2.ToString())) ||
							    !IsPrime(ref p, long.Parse(i1.ToString() + i4.ToString())) ||
                                                            !IsPrime(ref p, long.Parse(i4.ToString() + i1.ToString())))
							{
								continue;
							}
							foreach(long i5 in p)
							{
								if (i5 <= i4) continue;
								if (!IsPrime(ref p, long.Parse(i5.ToString() + i3.ToString())) ||
                                                                    !IsPrime(ref p, long.Parse(i3.ToString() + i5.ToString())) ||
							    	    !IsPrime(ref p, long.Parse(i2.ToString() + i5.ToString())) ||
                                                                    !IsPrime(ref p, long.Parse(i5.ToString() + i2.ToString())) ||
								    !IsPrime(ref p, long.Parse(i1.ToString() + i5.ToString())) ||
                                                                    !IsPrime(ref p, long.Parse(i5.ToString() + i1.ToString())) ||
								    !IsPrime(ref p, long.Parse(i4.ToString() + i5.ToString())) ||
                                                                    !IsPrime(ref p, long.Parse(i5.ToString() + i4.ToString())))
								{
									continue;
								}
								else
								{
									Console.WriteLine(i1+i2+i3+i4+i5);
									sw.Stop();
									Console.WriteLine(sw.Elapsed);
									Console.ReadLine();
								}
							}
						}
					}
				}
			}

			sw.Stop();
			Console.WriteLine(sw.Elapsed);
			Console.ReadLine();
		}
		static bool IsPrime(ref ArrayList primes, long num)
		{
			bool RetVal = true;
			long check = Convert.ToInt64(Math.Ceiling(Math.Sqrt(Convert.ToDouble(num))));
			foreach (long l in primes)
			{
				if (l > check)
					break;
				if (num % l == 0)
					RetVal = false;
			}
			return RetVal;
		}
        static ArrayList GeneratePrimes(long num)
        {
            ArrayList RetValue = new ArrayList();
            RetValue.Add((long)2);
            RetValue.Add((long)3);
            long Stepper = 5;
            long Check = 1;
            while (Stepper <= num)
            {
                foreach (long i in RetValue)
                {
                    if (Stepper % i == 0)
                    {
                        Check = 0;
                        break;
                    }
                    if (Math.Sqrt(Stepper) < i)
                    {
                        break;
                    }
                }
                if (Check == 1)
                {
                    //Console.WriteLine(((float)Stepper / (float)num) * 100);
                    RetValue.Add(Stepper);
                }
                Check = 1;
                Stepper++;
                Stepper++;
            }
            return RetValue;
        }

	}
}

Tags: , ,
Posted in Project Euler | Comments (0)

Project Euler Problem #142!

December 26th, 2009

Problem #142 say:

Find the smallest x + y + z with integers x > y > z > 0 such that x + y, x − y, x + z, x − z, y + z, y − z are all perfect squares.

Now one can brute force this by looping over x, y and z. That takes around 4 hours on a modern computer. However there are a few relationships we can take advantage of:

x+y=a
x-y=b
x+z=c
x-z=d
y+z=e
y-z=f

e=a-d
f=a-c
b=c-e

(x+z) = (x+y)-(x-z)
(y-z) = (x+y)-(x+z)
(x-y) = (x+z)-(y+z)

x=(a+b)/2
y=(e+f)/2
z=(c-d)/2

these relationships allow us to loop on a,c,d and get the rest of the numbers from those three, this makes the solution run in around 33 msecs. That’s around a ~436363% speedup! Solution provided in c#/mono.

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

namespace ProjectEuler
{
    class Program
    {
        static object LockHandle = new object();
        static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();
            long a2, b2, c2, d2, e2, f2;
            bool solved = false;
            sw.Start();

            for (long a = 10;!solved;a++)
            {
                a2 = a * a;
                for (long c = 5 + (0 & a); c < a && !solved; c += 2)
                {
                    c2 = c * c;
                    f2 = a2 - c2;
                    if (f2 < 1 || !IsSquare(f2))
                        continue;
                    for (long d = 2 + (1 & c); d < c; d += 2)
                    {
                        d2 = d * d;
                        e2 = a2 - d2;
                        if (e2 < 1 || !IsSquare(e2))
                            continue;
                        b2 = c2 - e2;
                        if (b2 > 0 && IsSquare(b2))
                        {
                            long x = (a2 + b2) / 2;
                            long y = (e2 + f2) / 2;
                            long z = (c2 - d2) / 2;
                            solved = true;
                            Console.WriteLine("x= " + x.ToString() +
                                 " y = " + y.ToString() + " z = " + z.ToString()
                                 + " sum = " + (z + y + x).ToString());
                            break;
                        }
                    }

                }
            }

            Console.WriteLine(sw.Elapsed);
            Console.ReadLine();
        }
        public static bool IsSquare(long n )
        {
            double root = Math.Sqrt(n);
            return (root % 1 == 0);
        }
    }
}

Tags: , , ,
Posted in Project Euler | Comments (0)