Tag Archive for 'add'

Project Euler : Finding Minimal Sum Path In A Matrix

The problem 81 of Project Euler gives a square matrix and requires one to find the minimal sum path. Specifically, it only required the sum of the numbers on the path. The question immediately reminded me of problem 67 and I set out solving with the same logic.

The logic has been explained in the following post of mine: Project Euler : Maximum Sum Traversing Top To Bottom In A Triangle.

The following lines of code did the work for me:

    public static int getMinimalSumPath(int[][] numbers) {
        int dimension = numbers.length - 1;
        for (int x = dimension; x >= 0; x--)
            for (int y = dimension; y >= 0; y--) {
                if (x == dimension && y == dimension) continue;
                int val1 = x < dimension ? numbers[x + 1][y] : Integer.MAX_VALUE;
                int val2 = y < dimension ? numbers[x][y + 1] : Integer.MAX_VALUE;
                numbers[x][y] += val1 < val2 ? val1 : val2;
            }

        return numbers[0][0];
    }

Popularity: 14% [?]

Paagal Google

Paagal Google

Paagal Google

Popularity: 2% [?]

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% [?]

Project Euler : Adding 100 50-Digit Numbers

The problem number 13 asked to find the first 1o digits of the sum of 100 50-digit numbers. Well, it was a pretty straight forward task. I think the purpose of this problem was to build an adder to add any large numbers. So I created a new class called BigNumber which stores the numbers as an arraylist of integers.

Here is my code:

public class Problem_13 {
	private static int s_numberOfDataRows = 100;

	public String addNumbers() throws IOException {
		BigNumber[] numbers = readNumbersFromFile();
		return BigNumber.add(50, numbers).toString();
	}

	private BigNumber[] readNumbersFromFile() throws IOException {
		String fileName = "problem_13.in";
		BigNumber[] numbers = new BigNumber[Problem_13.s_numberOfDataRows];

		BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(fileName)));
		for (int i = 0; i < Problem_13.s_numberOfDataRows; i++)
			numbers[i] = new BigNumber(bufferedReader.readLine());

		return numbers;
	}

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

class BigNumber {
	ArrayList<Integer> m_digits;

	public BigNumber(String number) {
		int lengthOfNumber = number.length();
		m_digits = new ArrayList<Integer>(lengthOfNumber);
		for (int i = lengthOfNumber - 1; i >= 0; i--)
			m_digits.add(number.charAt(i) - '0');
	}

	public BigNumber(int sizeOfBigNumber) {
		m_digits = new ArrayList<Integer>(sizeOfBigNumber);
	}

	public int getDigitAtIndex(int index) {
		return index < m_digits.size() ? m_digits.get(index) : 0;
	}

	public void insertDigit(int position, int digit) {
		m_digits.add(position, digit);
	}

	public String toString() {
		int size = m_digits.size();
		StringBuffer number = new StringBuffer(size);
		for (int i = 0; i < size; i++)
			number.insert(0, getDigitAtIndex(i));

		return number.toString();
	}

	public static BigNumber add(int maxLength, BigNumber... numbers) {
		BigNumber sum = new BigNumber(maxLength);

		int carry = 0;
		for (int i = 0; i < maxLength; i++) {
			int partialSum = carry;
			for (BigNumber number : numbers)
				partialSum += number.getDigitAtIndex(i);
			sum.insertDigit(i, partialSum % 10);
			carry = partialSum / 10;
		}

		if (carry != 0)
			sum.insertDigit(maxLength, carry);

		return sum;
	}
}

Popularity: 14% [?]