Tuesday 28 April 2009

PROJECT EULER #73

Link to Project Euler problem 73

Consider the fraction, n/d, where n and d are positive integers. If n < d and HCF(n,d)=1, it is called a reduced proper fraction.
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 there are 3 fractions between 1/3 and 1/2.
How many fractions lie between 1/3 and 1/2 in the sorted set of reduced proper fractions for d <= 10,000?


Yet again a big thanks to my mentor: After trying to brute-force this by generating all the fractions using the a/b < c/d ...insert (a+c) /(b+d) if b+d = n, type of solution (I stopped the program after 40 mins) he suggested looking at this strategy (took 1.05 s):

using System;
using System.Collections.Generic;

namespace ProjectEuler
{
class Program
{
static void Main()
{
//Problem 73
DateTime start = DateTime.Now;
int number =10000;
var primeFactors = GeneratePrimeFactors(number);
int max = 0,min=0,sum=0;
for (int i = number; i > 3; i--)
{
int count = 0;
max = (int) Math.Floor((decimal) i/2);
min=(int)Math.Ceiling((decimal) i/3);
for (int j = min; j <=max; j++)
{
int test = primeFactors[i].Count;
foreach (int k in primeFactors[i])
if (j%k == 0)
test--;
if (test == primeFactors[i].Count)
count++;
}
sum += count;
}
Console.WriteLine(sum);
Console.WriteLine();
TimeSpan time = DateTime.Now - start;
Console.WriteLine("This took {0}", time);
Console.ReadKey();
}
public static List<List<int>> GeneratePrimeFactors(int n)
{
var primes = GeneratePrimes(n);
var primeFactors = new List<List<int>> {new List<int> {0}};
for (int i = 1; i <= n; i++)
primeFactors.Add(new List<int>());
if (n==1) return primeFactors;
foreach (int i in primes)
for (int j = i; j <= n; j += i)
primeFactors[j].Add(i);
return primeFactors;
}
public static bool IsPrime(int n)
{
if (n < 2) return false;
if (n == 2) return true;
for (long i = 2; i <= Math.Sqrt(n); i++)
if (n % i == 0) return false;
return true;
}
public static List<int> GeneratePrimes(int n)
{
var primeNumbers = new List<int> { 2, 3 };
for (int i = 5; i <= n; i += 2)
if (IsPrime(i))
primeNumbers.Add(i);
return primeNumbers;
}
}
}

No comments: