Project Euler : Maximum Sum Traversing Top To Bottom In A Triangle

The 18th and the 67th problems in Project Euler are one and the same. The only difference is in the input test case. The problem 18 has a smaller input and 67 has a large input. For the explanation purpose, I’ll consider problem 18. The code without any modification can be extended to 67th problem.

Given a triangle of numbers, the objective is to determine the maximum sum along paths descending from the apex of the triangle to the base. Consider the example:

3

7     4

2     4     6

8     5     9     3

The maximum sum occurs along the path 3-7-4-9.

The problem required us to determine the maximum sum for any given triangle. Also an interesting thing is mentioned about the problem, in case you were considering a brute force method of checking every path:

It is not possible to try every route to solve this problem (where the base of the triangle has 100 numbers), as there are 2^(99) altogether! If you could check one trillion (10^(12)) routes every second it would take over twenty billion years to check them all. There is an efficient algorithm to solve it. ;o)

Being forewarned, I never once gave a thought to the brute force solution.

This problem was not as tricky as they tried to sound it. The solution is quite easy to see. I’ll run you through the idea as it formed in my mind. I used the top-to-bottom approach for forming the idea and coming up with the solution, and then implemented the solution in bottom-to-top sweep. I hope you have realized that a greedy solution will not work here.

Consider the triangle given above. I’ll work out the maximum path for it from top to bottom.  We start with 3. We may choose either 7 or 4. To help make this choice, consider the two triangles with apex 7 and the other with 4. So we have two smaller triangles of height 3 each. Say the maximum length for the triangle with apex 7 is x and with apex 4 is y. If x > y, we choose 7 as the next on the path, else 4.

Thus, at every step we form two triangle of height 1 smaller, and choose the apex which has the larger sum. Implemented as it is will give us the recursive solution. To get an iterative solution to this problem, one could traverse from bottom-to-top. The bottom-to-top approach is also simple. It is greedy in approach.

Consider the penultimate row, specifically the triangle with 2 as apex and 8, 5 as the base. The maximum sum in this triangle is 2+8 =  10. Replace 2 with 10. Do the same for all the triangles formed with the penultimate layer as the apex. Thus our triangle reduces to

3

7     4

10     13     15

You know what to do next. Keep applying the same till the apex of the original triangle has the maximum sum.

I have implemented the bottom-to-top method so as to avoid recursion. Here is my code:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Problem_18 {
	private static int heightOfTree = 100;
	private final String fileName = "problem_67.in";
	private int[][] tree;

	public int maxValue() throws IOException {
		readTree();

		for (int i = Problem_18.heightOfTree - 2; i >= 0; i--)
			for (int j = 0; j <= i; j++)
				tree[i][j] += tree[i + 1][j] > tree[i + 1][j + 1] ? tree[i + 1][j] : tree[i + 1][j + 1];

		return tree[0][0];
	}

	private void readTree() throws IOException {
		tree = new int[Problem_18.heightOfTree][];

		BufferedReader bufferedReader = new BufferedReader(new FileReader(fileName));
		for (int i = 0; i < Problem_18.heightOfTree; i++) {
			tree[i] = new int[i + 1];
			String[] values = bufferedReader.readLine().split(" ");
			for (int j = 0; j <= i; j++)
				tree[i][j] = Integer.parseInt(values[j]);
		}
	}

	public static void main(String[] args) throws IOException {
		System.out.println(new Problem_18().maxValue());
	}
}

Popularity: 100% [?]

Related posts:

  1. Project Euler : Finding Minimal Sum Path In A Matrix
  2. Project Euler : Pascal Triangle To Find nCr
  3. Project Euler : First Triangle Number To Have Over Five Hundred Divisors
  4. Project Euler : Verifying Triangle Words
  5. Project Euler : Number Of Routes From One Corner To Another In A Grid

  • Zihao Yu

    Nice work!

  • jez

    Anuvrat ! – really great stuff ! very interested in prime distributions and am working on visualising them in spiral/spherical 3d surfaces and forms to assist us 'human' visual pattern finders in seeing the relations more clearly – especially interested in quad and octal groupings of primes …. my background is programming rather than maths but i go as deep as i have time and inclination for ! love to keep in touch and share a few thoughts ! keep going monsieur ! great work !

  • jez

    oops typo in my email….posting my right one ! j

  • Mouthgalya

    Excellent solution Anuvrat!!!! Very nice work….Keep posting such interesting problems..

  • publicstaticvoid

    Fabolous algorithm. If you were expected to print out a path to the console by displaying all the individual numbers that made up the maximum path, how would you go about that?

    • http://blog.singhanuvrat.com Anuvrat Singh

      Just thinking out aloud. Create another array to mimic the tree. All the elements are blank to begin with. Each iteration, whichever child is selected, tick that array element. Finally, the path will be the continuous sequence of ticks.

  • http://www.facebook.com/pinchhitter Chandra Shekhar

    Hi,

    What do you mean by saying the maximum length for the triangle with apex 7 or 4 ??

    • http://blog.singhanuvrat.com Anuvrat Singh

      Look at it recursively. Consider two triangles 7; 2,4; 8,5,9 and 4; 4,6; 5,9,3. If we know the maximum lengths for these two, then the overall maximum length for the original triangle will be 3 + larger of the maximum lengths for the two smaller traingles.

      • http://www.facebook.com/pinchhitter Chandra Shekhar

        Still I don’t understand the term “length”, and if you talking about the numbers of number in triangle then, what if the length is same?? as in your example ?

        • http://blog.singhanuvrat.com Anuvrat Singh

          Oh! By length I meant the maximum sum as required by the problem. So the maximum sum in the triangle 7; 2,4; 8,5,9 is 20 along the path 7-4-9 and for 4; 4,6; 5,9,3 is 19 along the path 4-6-9.

          • http://www.facebook.com/pinchhitter Chandra Shekhar

            Have you tried this recursive (top to bottom) solution? I think it will not work for bigger input.

          • http://blog.singhanuvrat.com Anuvrat Singh

            True. Could be. I do not really favor recursive solutions because they require stack to be maintained. But I always find it easier to first think of a recursive solution and then get to an iterative one from there. And that is what I did in this problem as well. :)

  • http://www.facebook.com/pinchhitter Chandra Shekhar

    Still I don’t understand the term “length”, and if you talking about the numbers of number in triangle then, what if the length is same?? as in your example ?

  • Anonymous

    Awesome! Thanks for this; I was going around in circles trying to figure out the solution ;-)

  • http://www.facebook.com/arraymac Randy A MacDonald

     APL does it without breaking a sweat, i.e. entering a second line of code. 
    As George Orwell said,  ”Never use a big word when a small one will do.”
     

     {?+2?/?}/(3)(7 4)(2 4 6)(8     5     9     3)

    • http://blog.singhanuvrat.com Anuvrat Singh

      Wow! I never heard of APL before. I need to check it out now. 

  • Balaji

    This problem can also be extended to a matrix and the same solution can be applied to the matrix configuration too. This question can now be added another constraint that you always start from one corner (be it left corner 0,0 ) and you reach the diagonal corner (n,n) . Now the optimal path can be found by sweeping the matrix diagonally from (n,n) to (0,0) . This is all easy.

    But how to find the kth optimal path ?(assuming that kth optimal path exists ) . The solution to this problem should fit both the matrix and triangle. Any idea ?