/* __ __ __ __ __ ___
* \ \ / / \ \ / / __/
* \ \/ / /\ \ \/ / /
* \____/__/ \__\____/__/.ɪᴏ
* ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ
*/
package io.vavr.collection.euler;
import io.vavr.Function3;
import io.vavr.collection.Vector;
import org.junit.Test;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
public class Euler67Test {
/**
* <strong>Problem 67: Maximum path sum II</strong>
* <p>
* 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.
* <pre>
* 3
* 7 4
* 2 4 6
* 8 5 9 3
* </pre>
* That is, 3 + 7 + 4 + 9 = 23.
* <p>
* Find the maximum total from top to bottom in p067_triangle.txt, a 15K text file containing a triangle with one-hundred rows.
* <p>
* <strong>NOTE</strong>: This is a much more difficult version of Problem 18.
* <p>
* See also <a href="https://projecteuler.net/problem=67">projecteuler.net problem 67</a>.
*/
@Test
public void shouldSolveProblem67() {
assertThat(solve("small_triangle.txt")).isEqualTo(23);
assertThat(solve("p067_triangle.txt")).isEqualTo(7273);
}
private static int solve(String fileName) {
return smart.apply(loadTriangle(fileName), 0, 0);
}
private final static Function3<Vector<Vector<Integer>>, Integer, Integer, Integer> smart = Function3.of(
(Vector<Vector<Integer>> tr, Integer row, Integer col) -> {
int value = tr.get(row).get(col);
if (row == tr.length() - 1) {
return tr.get(row).get(col);
} else {
return value + Math.max(Euler67Test.smart.apply(tr, row + 1, col), Euler67Test.smart.apply(tr, row + 1, col + 1));
}
}
).memoized();
static Vector<Vector<Integer>> loadTriangle(String fileName) {
return Vector.ofAll(
Utils.readLines(Utils.file(fileName)).map(line ->
Arrays.stream(line.split("\\s")).map(Integer::parseInt)
).map(s -> Vector.ofAll(s::iterator))
);
}
}