150 likes | 164 Views
Learn about programming concepts, binary search, Java constructs, and two-dimensional arrays. Explore the 15-Puzzle problem and representations of moves, tiles, and frames. Develop solutions and code in Java.
E N D
CS100J Lecture 17 • Previous Lecture • Programming concepts • Binary search • Application of the “rules of thumb” • Asymptotic complexity • Java Constructs • Conditional Expressions • This Lecture • Programming concepts • Two-dimensional arrays • Java Constructs • Constructors for two-dimensional arrays • Initializers for arrays • final • Reading • Lewis & Loftus Section 6.3 • Savitch, Section 6.5 Lecture 17
4 13 1 2 3 1 5 9 5 6 7 8 2 6 10 14 9 10 11 12 3 7 11 15 13 14 15 4 8 12 The 15 Puzzle (Sam Loyd 1878) • 15 numbered tiles in a 4-by-4 frame: final configuration initial configuration Problem. Given a sequence of “moves” as input, say whether or not the sequence of moves changes the initial configuration into the final configuration. Lecture 17
Representation of Moves • How should a move be represented in the input data? Move Name Means 1 moveDown fill the blank from above 2 moveUp fill the blank from below 3 moveRight fill the blank from left 4 moveLeft fill the blank from right 0 endMove end of data • Named Constants in Java final int endMove = 0; final int moveDown = 1; final int moveUp = 2; final int moveRight = 3; final int moveLeft = 4; Lecture 17
Representation of the Tiles • How should the tiles be represented? • We need 15 values to represent the tiles and one to represent the blank? // Use 1..15 for the tiles and 0 for blank. final int Blank = 0; or // Use 1..15 for the tiles and 16 for blank. final int Blank = 16; • Rule of Thumb. Choose uniform representations if at all possible Lecture 17
Representation of the Frame • We need 16 variables, one to represent the tile at each position in the frame. • We could use the declaration: int[] puz = new int[16]; to get variables puz[0], . . ., puz[15], but this is unwieldy and unnatural. • Rule of Thumb. Unless there is a compelling reason algorithmic reason to do otherwise, use data that is structured similarly to the physical device being simulated. • We use a two-dimensional array. Lecture 17
puz 0 1 2 3 0 1 2 3 Two Dimensional Arrays • Declaration of two-dimensional array: // Create 4-by-4 array named puz. int [][] puz = new int[4][4]; • which is equivalent to: // Create 4-by-4 array named puz. int [][] puz = new int[4][]; puz[0] = new int[4]; puz[1] = new int[4]; puz[2] = new int[4]; puz[3] = new int[4]; Lecture 17
Rows and Columns • Vocabulary • row-major order in a 2-D array is 1st row, then 2nd row, then 3rd row, etc. • column-major order in a 2-D array is1st column, then 2nd column, then 3rd column, etc. • The default interpretation of a 2-D array is to consider the first index the row, and the second index the column: • puz[r][c] is the variable in row r and column c • puz[r] is row r Lecture 17
Program Outline /* If the sequence of moves transforms the puzzle from the initial configuration into the final configuration, output “yes”, else output “no”. */ static void test() { TokenReader in = new TokenReader(System.in); final int Blank = 16; final int endMove = 0; final int moveDown = 1; final int moveUp = 2; final int moveRight = 3; final int moveLeft = 4; /* Let puz be the initial configuration, the integers 1..16 in row major order. */ . . . /* Update puz according to each move. */ . . . /* Say whether puz is final configuration, i.e., 1..16 in column major order. */ . . . } Lecture 17
Initialization • Solution 1: /* Let puz be the initial configuration, the integers 1..16 in row major order. */ int [][] puz = new int [4][4]; for (int r = 0; r < 4; r++) for (int c = 0; c < 4; c++) { puz[r][c] = ____________________; } • Solution 2: /* Let puz be the initial configuration, the integers 1..16 in row major order. */ int [][] puz = new int [4][4]; for (int r = 0; r < 4; r++) for (int c = 0; c < 4; c++) puz[r][c] = ____________________________; Lecture 17
Puzzle Updating • Rule of Thumb. Use relevant patterns. /* Update puz according to each move. */ int m; // current move m = in.readInt(); while ( m != endMove ) { // Process move m. . . . m = in.readInt(); } Lecture 17
puz[rowB-1] [colB-1] puz[rowB-1] [colB] puz[rowB-1] [colB+1] puz[rowB] [colB-1] puz[rowB] [colB] puz[rowB] [colB+1] puz[rowB+1] [colB-1] puz[rowB+1] [colB] puz[rowB+1] [colB+1] Relative Coordinate System • Introduce variables rowB, colB to track the blank. /* rowB,colB is position of blank, initially the lower-right hand corner. */ int rowB = 3; int colB = 3; • Picture the frame relative to the position of blank (in general, after the blank has moved around Lecture 17
Exhaustive Solution // Process move m. if ( m==moveDown ){ // fill from above puz[rowB][colB] = puz[rowB-1][colB]; puz[rowB-1][colB] = Blank; rowB--; } elseif ( m==moveUp ) { // fill from below puz[rowB][colB] = puz[rowB+1][colB]; puz[rowB+1][colB] = Blank; rowB++; } elseif ( m==moveRight) {// fill from left puz[rowB][colB] = puz[rowB][colB-1]; puz[rowB][colB-1] = Blank; colB--; } else {// fill from right puz[rowB][colB] = puz[rowB][colB+1]; puz[rowB][colB+1] = Blank; colB++; } Lecture 17
Puzzle Updating: Uniform Treatment • Rule of Thumb. Avoid case analysis if possible. /* Update puz according to each move. */ int m; // current move m = in.readInt(); while ( m != endMove ) { // Process move m. // Blank moves to rowNew, colNew. int rowNew = _________________________; int colNew = _________________________; puz[rowB][colB] = puz[rowNew][colNew]; puz[rowNew][colNew] = Blank; rowB = rowNew; colB = colNew; m = in.readInt(); } Lecture 17
Array Initializers • A 1-dimensional array can be initialized with: { comma-separated list of expressions } • Example: /* Offsets to new position of blank on move m are delatR[m] and deltaC[m]. */ int [] deltaR = {0, -1, 1, 0, 0}; int [] deltaC = {0, 0, 0, -1, 1}; • A 2-dimensional array can be initialized with: { comma-separated list of array-initializers } • Example (solution 3 for setting the initial configuration): int [][] puz = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,16} }; Lecture 17
Puzzle Updating: Final Version /* Update puz according to each move. */ /* Offsets to new position of blank on move m are delatR[m] and deltaC[m]. */ int [] deltaR = {0, -1, 1, 0, 0}; int [] deltaC = {0, 0, 0, -1, 1}; /* rowB,colB is position of blank, initially the lower-right hand corner. int rowB = 3; int colB = 3; int m; // current move m = in.readInt(); while ( m != endMove ) { // Process move m. // Blank moves to rowNew, colNew. int rowNew = rowB + deltaR[m]; int colNew = colB + deltaC[m]; puz[rowB][colB] = puz[rowNew][colNew]; rowB = rowNew; colB = colNew; m = in.readInt(); } puz[rowB][colB] = Blank; Lecture 17