Saturday, April 12, 2008

Project Euler Problem 18

This time we will solve euler problem 18 by semi-bruteforce solution.
Problem description:
--------------------------------------------------------------------------------------
By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.
3
7 5
2 4 6
8 5 9 3

That is, 3 + 7 + 4 + 9 = 23.
Find the maximum total from top to bottom of the triangle below:
75
95 64
17 47 82
18 35 87 10
20 04 82 47 65
19 01 23 75 03 34
88 02 77 73 07 63 67
99 65 04 28 06 16 70 92
41 41 26 56 83 40 80 70 33
41 48 72 33 47 32 37 16 94 29
53 71 44 65 25 43 91 52 97 51 14
70 11 33 28 77 73 17 78 39 68 17 57
91 71 52 38 17 14 91 43 58 50 27 29 48
63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
----------------------------------------------------------------------------------------
Solution in C# is more or less short and fast (calculates answer in 1,1 ms):



using System;

class Program
{
static long MaxTotalFromTriangle()
{
long[][] triangle = new long[15][];
long max = 0;
triangle[0] = new long[] { 75 };
triangle[1] = new long[] { 95, 64 };
triangle[2] = new long[] { 17, 47, 82 };
triangle[3] = new long[] { 18, 35, 87, 10 };
triangle[4] = new long[] { 20, 04, 82, 47, 65 };
triangle[5] = new long[] { 19, 01, 23, 75, 03, 34 };
triangle[6] = new long[] { 88, 02, 77, 73, 07, 63, 67 };
triangle[7] = new long[] { 99, 65, 04, 28, 06, 16, 70, 92 };
triangle[8] = new long[] { 41, 41, 26, 56, 83, 40, 80, 70, 33 };
triangle[9] = new long[] { 41, 48, 72, 33, 47, 32, 37, 16, 94, 29 };
triangle[10] = new long[] { 53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14 };
triangle[11] = new long[] { 70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57 };
triangle[12] = new long[] { 91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48 };
triangle[13] = new long[] { 63, 66, 04, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31 };
triangle[14] = new long[] { 04, 62, 98, 27, 23, 09, 70, 98, 73, 93, 38, 53, 60, 04, 23 };

for (int i = 1; i < triangle.Length; i++)
{
for (int j = 0; j < triangle[i].Length; j++)
{
// Accumulating maximum total
if (j == 0)
{
triangle[i][j] += triangle[i - 1][j];
}
else if (j == triangle[i].Length - 1)
{
triangle[i][j] += triangle[i - 1][triangle[i - 1].Length - 1];
}
else
{
triangle[i][j] += Math.Max(triangle[i - 1][j], triangle[i - 1][j - 1]);
}
// Finding maximum from last row
if (i == triangle.Length - 1)
{
if (triangle[i][j] > max) max = triangle[i][j];
}
}
}
return max;
}

static void Main(string[] args)
{
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
long ans = MaxTotalFromTriangle();
sw.Stop();
Console.WriteLine("Total sum {0}; cpu time {1} ms", ans, sw.Elapsed.TotalMilliseconds);
Console.ReadLine();
}
}



Also this solution is universal and can calculate bigger triangles (lets say 100 rows triangles and more) with a reasonable time.

Have fun!!

1 comment:

  1. Hi,
    I thought you might be interested in the solution to Problem 18 that I've written up, using LINQ and the Aggregate method.

    Sam

    ReplyDelete

Comment will be posted after comment moderation.
Thank you for your appreciation.