116 lines
3.0 KiB
116 lines
3.0 KiB
import java.util.Arrays; |
|
import java.util.Scanner; |
|
import java.io.FileReader; |
|
import java.io.BufferedReader; |
|
import java.io.FileNotFoundException; |
|
|
|
/* |
|
* |
|
To fix: |
|
don't use the sum of the subtree, |
|
use the EXPECTATION: |
|
|
|
E(subtree) = E(level1)+E(level2)+... |
|
|
|
E(level1) = one possibility |
|
E(level2) = (1/2)(outcome1) + (1/2)(outcome2) |
|
E(level3) = (1/4)(outcome1) + (1/4)(outcome2) + (1/4)(outcome3) + (1/4)(outcome4) |
|
|
|
*/ |
|
|
|
public class Path { |
|
|
|
public static final String FILE = "tri_test2.txt"; |
|
|
|
/** Find the maximum path down a triangle. |
|
* |
|
* Strategy: add up the marginal sums of each diagonal, |
|
* divide by the total number of entries, |
|
* and use those measures to make decisions about which |
|
* directions to move in. |
|
*/ |
|
public static void main(String[] args) throws FileNotFoundException { |
|
System.out.println(navigateMaxPath()); |
|
} |
|
|
|
|
|
/** Navigate the triangle one step at a time, making decisions as we go about which direction to move. */ |
|
public static int navigateMaxPath() throws FileNotFoundException { |
|
int[][] triangle = loadTriangle(); |
|
int dim = triangle.length; |
|
|
|
int crawl = 0; |
|
int rr = 0, cc = 0; |
|
while(rr<dim && cc<dim) { |
|
System.out.println("Incrementing max path by "+triangle[rr][cc]); |
|
if(rr+1<dim && cc+1<dim){ |
|
System.out.println(" Left child: " +triangle[rr+1][cc] +" Sum "+subtreeSum(rr+1,cc, triangle)); |
|
System.out.println(" Right child: "+triangle[rr+1][cc+1]+" Sum "+subtreeSum(rr+1,cc+1,triangle)); |
|
} |
|
crawl += triangle[rr][cc]; |
|
if(goLeft(rr,cc,triangle)) { |
|
rr++; |
|
} else { |
|
rr++; cc++; |
|
} |
|
} |
|
|
|
return crawl; |
|
} |
|
|
|
public static boolean goLeft(int i, int j, int[][] triangle) { |
|
int leftSubtreeSum = subtreeSum( i+1, j, triangle); |
|
int rightSubtreeSum = subtreeSum( i+1, j+1, triangle); |
|
int dim = triangle.length; |
|
// break ties by value, but skip last row |
|
if(leftSubtreeSum==rightSubtreeSum && i+1>dim) { |
|
return (triangle[i+1][j] > triangle[i+1][j+1]); |
|
} else { |
|
return leftSubtreeSum > rightSubtreeSum; |
|
} |
|
} |
|
|
|
|
|
public static int subtreeSum(int r, int c, int[][] triangle) { |
|
int sum = 0; |
|
int dim = triangle.length; |
|
for(int i=0; r+i<dim; i++){ |
|
for(int j=0; j<=i; j++) { |
|
sum += triangle[r+i][c+j]; |
|
} |
|
} |
|
return sum; |
|
} |
|
|
|
|
|
/** Load a triangle from a file. */ |
|
public static int[][] loadTriangle() throws FileNotFoundException { |
|
int nlines = countLines(); |
|
int[][] triangle = new int[nlines][nlines]; |
|
Scanner s = new Scanner(new BufferedReader(new FileReader(FILE))); |
|
int r = 0; |
|
while(s.hasNextLine()) { |
|
String line = s.nextLine(); |
|
Scanner ls = new Scanner(line); |
|
int c = 0; |
|
while(ls.hasNextInt()) { |
|
int num = ls.nextInt(); |
|
triangle[r][c] = num; |
|
c++; |
|
} |
|
r++; |
|
} |
|
return triangle; |
|
} |
|
|
|
/** Count the number of lines in the triangle file. */ |
|
public static int countLines() throws FileNotFoundException { |
|
Scanner s = new Scanner(new BufferedReader(new FileReader(FILE))); |
|
int lines = 0; |
|
while(s.hasNextLine()) { |
|
s.nextLine(); |
|
lines++; |
|
} |
|
return lines; |
|
} |
|
} |