import java.util.Random; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.Scanner; /* This class includes static methods to ** (1) Create a two-dimensional array of integers having specified numbers ** of rows and columns and in which the values ascend within each row ** and each column. Also specified are a lower bound on the minimum ** value in the array and the maximum difference between an element and ** the larger of its two immediate predecessors. ** (2) Print a representation of a specified two-dimensional array (assumed ** to be increasing along rows and columns) to a specified file. ** (3) Read, from a specified file, a representation (whose format must be ** consistent with that produced in (2)) of a two-dimensional array. ** ** Author: R. McCloskey ** Date: 2018-2022 */ public class TwoDimArrayMaker { // constructor // ----------- /* Returns a newly-generated 2-dimensional array of integers having these ** properties: ** --The number of rows and columns, respectively, is indicated by the ** first two parameters. ** --The 3rd parameter provides a lower bound on the minimum value in the ** array. ** --The 4th and 5th parameters, respectively, provide lower and upper ** bounds, respectively, on the difference between each element and the ** larger of its two immediate predecessors. (The immediate predecessors ** of ary[i][j] are ary[i-1][j] and ary[i][j-1].) ** --The 6th parameter is used as a seed for the pseudo-random number ** generator (an instance of java.util.Random) that is used for producing ** the values occupying the array. (If the specified seed is -1, no seed ** is specified.) ** ** pre: 0 < numRows && 0 < numCols && 0 <= minGap <= maxGap */ public static int[][] make(int numRows, int numCols, int minVal, int minGap, int maxGap, long seed) { Random rand; if (seed == -1) { rand = new Random(); } else { rand = new Random(seed); } int[][] ary = new int[numRows][numCols]; // Place value into location (0,0) ary[0][0] = minVal + rand.nextInt(maxGap+1); int maxMinDelta = maxGap - minGap + 1; // Fill row zero. for (int j=1; j != numCols; j++) { ary[0][j] = ary[0][j-1] + minGap + rand.nextInt(maxMinDelta); } // Fill column zero. for (int i=1; i != numRows; i++) { ary[i][0] = ary[i-1][0] + minGap + rand.nextInt(maxMinDelta); } // Fill remaining rows. for (int i=1; i != numRows; i++) { for (int j=1; j != numCols; j++) { int largerPred = Math.max(ary[i-1][j], ary[i][j-1]); ary[i][j] = largerPred + minGap + rand.nextInt(maxMinDelta); } } return ary; } /* Does the same thing as method above, but the client need not ** specify a seed for the pseudorandom number generator. */ public static int[][] make(int numRows, int numCols, int minVal, int minGap, int maxGap) { return make(numRows, numCols, minVal, minGap, maxGap, -1L); } /* Same as method above, but uses 0, 1, and 5 as the "default" values ** for lower bound of values in array, the minimum gap, and the maximum gap. */ public static int[][] make(int numRows, int numCols) { return make(numRows, numCols, 0, 1, 5); } /* Prints a representation of the specified array into the specified file. ** The first line has the number of rows and columns. ** Each remaining line is one row of the array. ** pre: ary[][] is rectangular (not jagged) */ public static void printToFile(File f, int[][] ary) throws FileNotFoundException { PrintWriter pw = new PrintWriter(f); int numRows = ary.length; int numCols = ary[0].length; // On first line, put size of array (# rows and # cols). pw.printf("%d %d\n", numRows, numCols); // For each column, based upon its min and max values, find proper // formatting string to use in using printf() to print values in // that column, so that columns are nicely lined up in the file. String[] formatter = new String[numCols]; for (int j=0; j != numCols; j++) { int lenOfMin = Integer.toString(ary[0][j]).length(); int lenOfMax = Integer.toString(ary[numRows-1][j]).length(); formatter[j] = "%" + Math.max(lenOfMin, lenOfMax) + "d "; } // On each subsequent line, print one row of the array for (int i=0; i != numRows; i++) { for (int j=0; j != numCols; j++) { pw.printf(formatter[j], ary[i][j]); } pw.printf("\n"); } pw.close(); } /* Returns a two-dimensional array, as read from the specified file, ** the contents of which must be in the same format as that produced ** by the printToFile() method */ public static int[][] readFromFile(File f) throws FileNotFoundException { Scanner in = new Scanner(f); int numRows = in.nextInt(); int numCols = in.nextInt(); int[][] ary = new int[numRows][numCols]; for (int i=0; i != numRows; i++) { String line = in.nextLine(); Scanner lineScanner = new Scanner(line); for (int j=0; j != numCols; j++) { ary[i][j] = lineScanner.nextInt(); } lineScanner.close(); } return ary; } /* Interprets the command line arguments as specifying ** (1) name of file into which to print an array, ** (2) number of rows in the array, ** (3) number of columns in the array, ** (4) lower bound on min value in array, ** (5) lower bound on the difference between each element ** and the larger of its immediate predecessors, and ** (6) upper bound on the difference between each element ** and the larger of its immediate predecessors. ** ** A new array of the specified size is generated using make() and ** then, using printToFile(), it is printed to the file with the ** specified name. */ public static void main(String[] args) throws FileNotFoundException { String fileName = args[0]; int m = Integer.parseInt(args[1]); int n = Integer.parseInt(args[2]); int minVal = Integer.parseInt(args[3]); int minGap = Integer.parseInt(args[4]); int maxGap = Integer.parseInt(args[5]); int[][] a = make(m, n, minVal, minGap, maxGap); printToFile(new File(fileName), a); } }