Archive for the ‘Project Euler’ Category

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 #71!

July 7th, 2010

I’m just getting back into the swing of things here after a busy period between work, life and college.

Anyways, Problem #71 says:

Consider the fraction, n/d, where n and d are positive integers. If n

If we list the set of reduced proper fractions for d ≤ 8 in ascending order of size, we get:

1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8

It can be seen that 2/5 is the fraction immediately to the left of 3/7.

By listing the set of reduced proper fractions for d ≤ 1,000,000 in ascending order of size, find the numerator of the fraction immediately to the left of 3/7.

So the trick here is to just look at the denominators. We know the number we are trying to get close to is 3/7 so we make the numerator ((3/7)*denominator) which will most likely be a float, we then take the floor of that value which gives us the closest integer and use that value as the numerator. We then check the numerator and denominator against each other to make sure the GCD is 1. We can then check to see if this new fraction is closer to (3/7) or further away than the last value we checked keeping the closer of the two.

Solution runs in around 2 seconds. Written in c#/mono.

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

namespace Problem71
{
	class MainClass
	{
		public static void Main (string[] args)
		{
			Fraction Standard = new Fraction(3,7);
			Fraction Closest = new Fraction(0,1);
			Stopwatch sw = new Stopwatch();
			sw.Start();

			for (int d = 1; d<=1000000;d++)
			{
				int n = (int)Math.Floor(((double)3/(double)7)*d);
					if (GCD(d,n) == 1)
					{
						Fraction f = new Fraction(n,d);
						if (f.Value < Standard.Value)
						{
							if (f.Value > Closest.Value)
							{
								Closest = f;
							}
						}

					}

			}
			sw.Stop();
			Console.Write(Closest.Numerator.ToString() + "/" +
                             Closest.Denominator.ToString()+System.Environment.NewLine);
			Console.WriteLine(sw.Elapsed);
			Console.ReadLine();
		}
		public static int GCD (int a, int b)
		{
			if (b == 0)
				return a;
			else
				return GCD(b,(a%b));
		}
	}
	class Fraction
	{
		public Fraction (int n, int d)
		{
			_numerator = n;
			_denominator = d;
		}
		private int _numerator;
		private int _denominator;
		public int Numerator
		{
			get{return _numerator;}
			set{_numerator = value;}
		}
		public int Denominator
		{
			get{return _denominator;}
			set{_denominator = value;}
		}
		public decimal Value
		{
			get{return (((decimal)_numerator)/((decimal)_denominator));}
		}
	}
}

Posted in Project Euler | Comments (0)

Project Euler Problem #132!

May 23rd, 2010

Problem #132 says:

A number consisting entirely of ones is called a repunit. We shall define R(k) to be a repunit of length k.

For example, R(10) = 1111111111 = 11×41×271×9091, and the sum of these prime factors is 9414.

Find the sum of the first forty prime factors of R(10^(9)).

To solve this problem we take the number and rearrange it a bit, then check for primes that fit the formula runs in about 12 seconds.

Solution in Python. Requires the RabinMiller.py file.

Problem132.py

from RabinMiller import *
from time import *

t0 = time()
def GeoSum (a,  n,  c):
    if (n == 1):
        return 1
    if (n==2):
        return (1+a)%c
    ret = ((GeoSum(a, n/2, c)%c)*((1+pow(a, n/2, c))%c))%c
    if (n&1):
        ret = (ret+pow(a, n-1, c))%c
    return ret

sum = 0
count = 0
i = 3
while (count <40):
    if (MillerRabin(i) and not GeoSum(10, 10**9,  i)):
        count = count + 1
        sum = sum + i
        print count, " divids by ", i
    i = i + 2
print sum
print time() - t0

RabinMiller.py

import sys
import random

def toBinary(n):
  r = []
  while (n > 0):
    r.append(n % 2)
    n = n / 2
  return r

def test(a, n):
  """
  test(a, n) -> bool Tests whether n is complex.

  Returns:
    - True, if n is complex.
    - False, if n is probably prime.
  """
  b = toBinary(n - 1)
  d = 1
  for i in xrange(len(b) - 1, -1, -1):
    x = d
    d = (d * d) % n
    if d == 1 and x != 1 and x != n - 1:
      return True # Complex
    if b[i] == 1:
      d = (d * a) % n
  if d != 1:
    return True # Complex
  return False # Prime

def MillerRabin(n, s = 3):
  """
    MillerRabin(n, s = 1000) -> bool Checks whether n is prime or not

    Returns:
      - True, if n is probably prime.
      - False, if n is complex.
  """
  for j in xrange(1, s + 1):
    a = random.randint(1, n - 1)
    if (test(a, n)):
      return False # n is complex
  return True # n is prime

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 #99!

May 1st, 2010

Problem #99 says:

Comparing two numbers written in index form like 2^(11) and 3^(7) is not difficult,
as any calculator would confirm that 2^(11) = 2048 < 3^(7) = 2187.

However, confirming that 632382^(518061) > 519432^(525806) would be much more difficult,
as both numbers contain over three million digits.

Using base_exp.txt (right click and ‘Save Link/Target As…’), a 22K text file containing one
thousand lines with a base/exponent pair on each line, determine which line number has the greatest numerical value.

This is a problem that seems kinda complicated at first. Each of the base exponent sets creates a number that easily dwarfs anything a computer can currently handle. The solution is to do something else that still lets us compare them to one another. So instead of expanding the exponent base pair what we do is multiply the exponent by the natural log of the base and use that value. Using this method reading the file in is almost harder than solving the task.

Solution in F# requires .net 4, runs in under one second.


open System
open System.IO
open System.Diagnostics

let sw = new Stopwatch()
sw.Start()

let test b e =
    e * Math.Log(b)    

let CheckSets =
    let f = new StreamReader("base_exp.txt")
    let mutable lines = []
    let mutable line = f.ReadLine()
    while line <> null do
        lines <- lines @ [line]
        line <- f.ReadLine()
    lines

let mutable mv = 0.0
let mutable ml = 0
let mutable ln = 0

let FindAnswer =
    for s in CheckSets do
        ln <- ln + 1
        let ss = s.Split(",".ToCharArray())
        let b = float ss.[0]
        let e = float ss.[1]
        if (test b e) > mv then
            mv <- (test b e)
            ml <- ln
FindAnswer
Console.WriteLine(ml)
sw.Stop()
Console.WriteLine(sw.Elapsed)
Console.ReadLine() |> ignore

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