Tuesday 28 April 2009

PROJECT EULER #74

Link to Project Euler problem 74

The number 145 is well known for the property that the sum of the factorial of its digits is equal to 145:

1! + 4! + 5! = 1 + 24 + 120 = 145

Perhaps less well known is 169, in that it produces the longest chain of numbers that link back to 169; it turns out that there are only three such loops that exist:
169 -> 363601 -> 1454 -> 169
871 -> 45361 -> 871
872 -> 45362 -> 872
It is not difficult to prove that EVERY starting number will eventually get stuck in a loop. For example,
69 -> 363600 -> 1454 -> 169 -> 363601 (-> 1454)
78 -> 45360 -> 871 -> 45361 (-> 871)
540 -> 145 (-> 145)
Starting with 69 produces a chain of five non-repeating terms, but the longest non-repeating chain with a starting number below one million is sixty terms.
How many chains, with a starting number below one million, contain exactly sixty non-repeating terms?

This took too long (38 s) but I don't see any obvious optimisations (yet).

using System;
using System.Collections.Generic;

namespace ProjectEuler
{
class Program
{
public static List<long> factorials = GenerateFactorials(9);
static void Main()
{
//Problem 74
DateTime start = DateTime.Now;
int sixties = 0;
for (int i = 1; i < 1000000; i++)
{
int count = 0;
var cycle = new List<long>();
long number = i;
while (!cycle.Contains(number))
{
count++;
cycle.Add(number);
number = GenerateSumOfFactorials(number);
}
if (count == 60)
sixties++;
}
Console.WriteLine(sixties);
TimeSpan time = DateTime.Now - start;
Console.WriteLine("This took {0}", time);
Console.ReadKey();
}
public static List<long> GenerateFactorials(int n)
{
var factorialList = new List<long> { 1 };
for (int i = 1; i <= n; i++)
{
long factorial = 1;
for (int j = 1; j <= i; j++)
factorial *= j;
factorialList.Add(factorial);
}
return factorialList;
}
public static long GenerateSumOfFactorials(long n)
{
string s = n.ToString();
long sum = 0;
for (int i = 0; i < s.Length; i++)
sum += factorials[int.Parse(s.Substring(i, 1))];
return sum;
}
}
}

No comments: