/**
 * Compute the number of paths from (1,1) to (n,n).  N is given on
 * the command line.  Is not very friendly about errors.  Uses
 * a two-dimensional array to keep track of previously computed
 * values.
 *
 * @author Samuel A. Rebelsky
 * @version 1.0 of October 1999
 */
public class NewNumPaths {
  /** The number of recursive calls. */
  protected long calls = 0;

  /**
   * A two dimensional array to keep track of the number of paths
   * from (x,y) to (n,n).  pathsFrom[x-1][y-1] gives the number
   * of paths from (x,y) to (n,n).  If it is not yet set at a
   * particular position, it has the value -1 in that position.
   */
  protected long[][] pathsFrom;

  /**
   * Compute the number of paths from (row,col) to (n,n).
   * (row,col) should not be (n,n).
   */
  public long numPaths(int row, int col, int n)
  {
    calls++;
    // Base cases:
    if ((row == n) || (col == n)) {
      return 1;
    }
    else {
      // Make sure that the array is initialized.
      if (pathsFrom == null) {
        pathsFrom = new long[n][n];
        for (int i = 0; i < n; ++i)
          for (int j = 0; j < n; ++j)
            pathsFrom[i][j] = -1;
      } // if the array is uninitialized
      // Is the array filled in for (row,col)?  If not, fill it in.
      if (pathsFrom[row-1][col-1] == -1) {
        pathsFrom[row-1][col-1] = 
          numPaths(row+1,col,n) + numPaths(row,col+1,n);
      }
      // Return the value from the array.
      return pathsFrom[row-1][col-1];
    } // "recursive" case
  } // numPaths(int, int, int)

  public static void main(String[] args) {
    SimpleOutput out = new SimpleOutput();
    int n = Integer.parseInt(args[0]);
    NewNumPaths helper = new NewNumPaths();
    long count = helper.numPaths(1,1,n);
    out.println("There are " + count + " paths to (" + n + "," + n + ")");
    out.println("  That took " + helper.calls + " calls.");
  } // main(String[])
} // NewNumPaths

