import java.io.*; // for I/O in main() only
import java.util.*; // for Random
/**
* ArrayChange instantiates an array of integer values that
* can be changed by selecting one of its members and supplying
* a new value for the selected element. Changes the value of
* the selected element, of all neighboring elements of equal value,
* and so on for neighbors of the neighbors. Example:
java ArrayChange 7 4 4
3 2 1 3 3 3 3
1 2 4 1 4 1 4
2 3 4 3 2 1 4
2 1 4 4 3 2 4
Select coordinate to zero (col row): 3 3
3 2 1 3 3 3 3
1 2 0 1 4 1 4
2 3 0 3 2 1 4
2 1 0 0 3 2 4
Select coordinate to zero (col row):
*
A 7 x 4 array of values ranging from 1 through 4
* was requested. User chose to zero the "4" at column 3, row 3.
* Three adjoining/connected "4"s were automatically zeroed as well.
* @author Tony Dahlman
*/
public class ArrayChange {
/** Two dimensional array of ArrayPoint objects. */
private ArrayPoint[][] array;
private static int cols, rows, colMax, rowMax;
/**
* Constructor sets number of rows and columns in the array of
* ArrayPoint objects, then randomly sets their values to be
* anything from 1 to the specified maximum value.
*/
public ArrayChange( int rows, int cols, int maxValue) {
Random r = new Random( new Date().getTime() );
array = new ArrayPoint[rows][cols];
for( int i=0; iArrayPoint object.
* @return the ArrayPoint object, if possible.
*/
ArrayPoint getStartPoint( String s ) {
s = s.trim();
int len = s.length();
try {
int col = new Integer(s.substring(0,1)).intValue();
int row = new Integer(s.substring(len-1,len)).intValue();
if( col > 0 && col <= cols && row > 0 && row <= rows )
return array[row-1][col-1];
} /* endtry */
catch ( Exception e ) {
e.printStackTrace();
return null;
} /* endcatch */
return null;
}
/**
* Given a point in the array, flood() first gets a list of adjacent
* points with equal value, then sets a new value for itself, and finally,
* it recursively calls itself to handle the list of neighboring points.
* Synchronized so value changes can complete before being checked by
* other recursive passes through this method.
* @param start an ArrayPoint object
* @param newVal the int value to which this ArrayPoint will be set
*/
synchronized void flood( ArrayPoint start, int newVal ) {
// get selected point's value, return if it already has changed
int startVal = start.getVal();
if( startVal == newVal )
return;
// get a list of neighbor points with same value as this point
ArrayPoint[] neighbors = new ArrayPoint[4];
int nDex = 0;
if( start.getRow() > 0 ) // not top row
if( array[start.getRow()-1][start.getCol()].getVal() == startVal )
neighbors[nDex++] = array[start.getRow()-1][start.getCol()];
if( start.getRow() < rowMax ) // not bottom row
if( array[start.getRow()+1][start.getCol()].getVal() == startVal )
neighbors[nDex++] = array[start.getRow()+1][start.getCol()];
if( start.getCol() > 0 ) // not left column
if( array[start.getRow()][start.getCol()-1].getVal() == startVal )
neighbors[nDex++] = array[start.getRow()][start.getCol()-1];
if( start.getCol() < colMax ) // not right column
if( array[start.getRow()][start.getCol()+1].getVal() == startVal )
neighbors[nDex++] = array[start.getRow()][start.getCol()+1];
// change this Point's value, return if no neighbors to handle
start.setVal( newVal );
if( nDex == 0 )
return;
// recursive call to flood any equal-value neighbors.
for( int i=0; i= 2 ) {
cols = new Integer( args[0] ).intValue();
if( cols < 1 ) cols = Math.abs(cols) + 1;
if( cols > 9 ) cols = 9;
rows = new Integer( args[1] ).intValue();
if( rows < 1 ) rows = Math.abs(rows) + 1;
if( rows > 9 ) rows = 9;
}
if( args.length == 3 ) {
range = new Integer( args[2] ).intValue();
if( range < 1 ) range = Math.abs(range) + 1;
if( range > 9 ) range = 9;
}
ArrayChange ac = new ArrayChange( rows, cols, range );
System.out.println( ac.conPrint(sep) );
BufferedReader ins = new BufferedReader(
new InputStreamReader( System.in ));
while (true) {
System.out.print("Select coordinate to zero (col row): ");
String input = ins.readLine();
if( input.length() < 1 ) {
ins.close();
System.exit(0);
}
ArrayPoint start = ac.getStartPoint( input );
if( start != null )
ac.flood( start, 0 );
System.out.println( ac.conPrint(sep) );
} /* endwhile */
}
}
/**
* An ArrayPoint is an element of an ArrayChange
* array. It is simply a data structure for one point of the array, plus
* appropriate setters and getters for its data.
*/
class ArrayPoint {
private int col;
private int row;
private int val;
public ArrayPoint( int row, int col, int val ) {
this.col = col;
this.row = row;
this.val = val;
}
void setVal( int val ) {
this.val = val;
}
int getVal() {
return val;
}
int getRow() {
return row;
}
int getCol() {
return col;
}
}