How to check if 2 elements are adjacent to one another in 2D array

Viewed 839

I'm trying to figure out how to take in 2 integer parameters, an initial integer referred to as "start" and a second integer referred to as "destination". I'm wanting to use both parameters from my method, first checking if the starting integer is within the matrix and then checking if the destination integer is adjacent within the 4 elements around it - (north, east, south, west).

Example 1:

example1

If the starting integer is (6), check whether the destination integer (7) is adjacent to the starting integer. If true then do something.

Example 2:

example1

In this case if the starting integer = 4 and the destination integer = 2. The program would not consider these elements adjacent.

Initialising array:

int[][] matrix = {{0,1,2,}, 
                  {3,4,5,}, 
                  {6,7,8}};

Check method:

public static  double check(int start, int destination)
{

    for(int row = 0; row < matrix.length; row++)
    {
        for(int col = 0; col < matrix[0].length; col++)
        {
            // check if the start integer is in the matrix
            if(matrix[row][col] == start)
            {
                // check if destination integer is adjacent to starting integer:
                if (destination is adjacent to start)
                {
                   // do something
                }

            }
        }
     }
}

Bear in mind, the matrix won't have duplicate numbers and will always stay the same.

How would I go about checking this?

I've spent a few hours looking at similar StackOverflow posts but I really can't seem to grasp the examples given. Could someone guide me through it?

3 Answers

If your start element is in the matrix there are 4 possible spots to check for your destination element: LEFT, RIGHT, UP, DOWN. You could just add a variable which is set by default to false and check the 4 spots keeping in mind to don't get out of bounds:

public static double check(int start, int destination) {
    for (int row = 0; row < matrix.length; row++) {
        for (int col = 0; col < matrix[0].length; col++) {
            // check if the start integer is in the matrix
            if (matrix[row][col] == start) {
                // check if destination integer is adjacent to starting integer:
                boolean destIsAdj = false;
                //left
                if (col - 1 > 0 && matrix[row][col-1] == destination) 
                    destIsAdj = true;
                //right
                else if (col + 1 < matrix[0].length && matrix[row][col+1] == destination) 
                    destIsAdj = true;
                //up
                else if (row - 1 > 0 && matrix[row-1][col] == destination) 
                    destIsAdj = true;
                //down
                else if (row + 1 < matrix.length && matrix[row+1][col] == destination) 
                    destIsAdj = true;

                if (destIsAdj){
                    // adjacent! do something
                }
                else {
                    // not adjacent! do something else
                }
            }
        }
    }
    return 0.0;
}

If the contents of the matrix is known to contain only the numbers in the range [min..max) within the dimensions rows x cols, it may be better to check if both start and destination belong to this range and that they have to be different (self-adjacent is ignored).

Using start value it is possible to calculate row and col values.

And last check if destination is in adjacent cells.

Note: the method should return boolean true if the start and destination are adjacent, false otherwise.

// default matrix 3x3, starting from 0
public static boolean check(int start, int destination) {
    return check(start, destination, 3);
}

// square matrix n x n, starting from 0
public static boolean check(int start, int destination, int n) {
    return check(start, destination, 0, n, n);
}

// rectangular matrix rows x cols, starting from 0
public static boolean check(int start, int destination, int rows, int cols) {
    return check(start, destination, 0, rows, cols);
}

// rectangular matrix rows x cols, starting from min
public static boolean check(int start, int destination, int min, int rows, int cols) {
    int max = min + rows * cols - 1;
    if (start < min || start > max || destination < min || destination > max || start == destination) {
        return false;
    }
    int rs = (start - min) / cols;
    int cs = (start - min) % cols;

    int rd = (destination - min) / cols;
    int cd = (destination - min) % cols;
    
    return ((rs == rd + 1 || rd == rs + 1) && (cs == cd))
        || ((cs == cd + 1 || cd == cs + 1) && (rs == rd));
}    

Test (printing the matrix, and the adjacency map):

public static void matrix(int min, int rows, int cols) {
    System.out.print(" | ");
    for (int i = 0; i < cols; i++) {
        System.out.printf("%2d  ", i);
    }
    System.out.println("\n" + "=".repeat(1 + cols * 4));

    int max = min + rows * cols;
    for (int i = 0; i < rows; i++) {
        System.out.print(i + "| ");
        for (int j = 0; j < cols; j++) {
            System.out.printf("%2d  ", min + cols * i + j);
        }
        System.out.println();
    }
}

public static void adjacency(int min, int rows, int cols) {
    int max = min + rows * cols;
    System.out.printf("Range: [ %2d, %2d)%n", min, max);
    System.out.print("  | ");
    for (int i = min; i < max; i++) {
        System.out.printf("%2d  ", i);
    }
    System.out.println("\n" + "=".repeat(4 + rows * cols * 4));
    for (int i = min; i < max; i++) {
        System.out.printf("%2d| ", i);
        for (int j = min; j < max; j++) {
            System.out.printf("%2s  ", check(i, j, min, rows, cols) ? "Y": ".");
        }
        System.out.println();
    }
}

Test:

int min = -4, rows = 3, cols = 4;
matrix(min, rows, cols);
adjacency(min, rows, cols);

Output:

 |  0   1   2   3  
=================
0| -4  -3  -2  -1  
1|  0   1   2   3  
2|  4   5   6   7  
Range: [ -4,  8)
  | -4  -3  -2  -1   0   1   2   3   4   5   6   7  
====================================================
-4|  .   Y   .   .   Y   .   .   .   .   .   .   .  
-3|  Y   .   Y   .   .   Y   .   .   .   .   .   .  
-2|  .   Y   .   Y   .   .   Y   .   .   .   .   .  
-1|  .   .   Y   .   .   .   .   Y   .   .   .   .  
 0|  Y   .   .   .   .   Y   .   .   Y   .   .   .  
 1|  .   Y   .   .   Y   .   Y   .   .   Y   .   .  
 2|  .   .   Y   .   .   Y   .   Y   .   .   Y   .  
 3|  .   .   .   Y   .   .   Y   .   .   .   .   Y  
 4|  .   .   .   .   Y   .   .   .   .   Y   .   .  
 5|  .   .   .   .   .   Y   .   .   Y   .   Y   .  
 6|  .   .   .   .   .   .   Y   .   .   Y   .   Y  
 7|  .   .   .   .   .   .   .   Y   .   .   Y   .  

for min = 0, rows = 3, cols = 3:

Range: [  0,  9)
  |  0   1   2   3   4   5   6   7   8  
========================================
 0|  .   Y   .   Y   .   .   .   .   .  
 1|  Y   .   Y   .   Y   .   .   .   .  
 2|  .   Y   .   .   .   Y   .   .   .  
 3|  Y   .   .   .   Y   .   Y   .   .  
 4|  .   Y   .   Y   .   Y   .   Y   .  
 5|  .   .   Y   .   Y   .   .   .   Y  
 6|  .   .   .   Y   .   .   .   Y   .  
 7|  .   .   .   .   Y   .   Y   .   Y  
 8|  .   .   .   .   .   Y   .   Y   .  

Here is an example that might gives an idea. But you still have to do some coding though.

public class Main
{
    private static final int MAX_COLUMNS = 3; //matrix[0].length

    public static void main(String[] args)
    {
        final int[][] matrix = {
            { 1, 2, 3 },
            { 4, 5, 6 },
            { 7, 8, 9 },
        };

        for(int i=1; i <= 9; ++i) {
            final int start = i;
            //final int target = 7;

            final int row = getRow(start - 1);
            final int column = getColumn(start - 1);

            final int left = getLeft(matrix, row, column);
            final int top = getTop(matrix, row, column);
            final int right = getRight(matrix, row, column);
            final int bottom = getBottom(matrix, row, column);

            System.out.printf("[%d] L: %2d, T: %2d, R: %2d, B: %2d%n", start, left, top, right, bottom);

            //[1] L: -1, T: -1, R:  2, B:  4
            //[2] L:  1, T: -1, R:  3, B:  5
            //[3] L:  2, T: -1, R: -1, B:  6
            //[4] L: -1, T:  1, R:  5, B:  7
            //[5] L:  4, T:  2, R:  6, B:  8
            //[6] L:  5, T:  3, R: -1, B:  9
            //[7] L: -1, T:  4, R:  8, B: -1
            //[8] L:  7, T:  5, R:  9, B: -1
            //[9] L:  8, T:  6, R: -1, B: -1
        }
    }

    private static final int getColumn(final int index)
    {
        return (index % MAX_COLUMNS);
    }

    private static final int getRow(final int index)
    {
        return (index / MAX_COLUMNS);
    }
    
    private static final int getLeft(final int[][] matrix, final int row, final int column)
    {
        if(column == 0) return -1;
        return matrix[row][column - 1];
    }
    
    private static final int getTop(final int[][] matrix, final int row, final int column)
    {
        if(row == 0) return -1;
        return matrix[row - 1][column];
    }
    
    private static final int getRight(final int[][] matrix, final int row, final int column)
    {
        if(column == (MAX_COLUMNS - 1)) return -1;
        return matrix[row][column + 1];
    }
    
    private static final int getBottom(final int[][] matrix, final int row, final int column)
    {
        if(row == (matrix.length - 1)) return -1;
        return matrix[row + 1][column];
    }

  // Unused in this example. In case someone need it.
    private static final int getIndex(final int row, final int column)
    {
        return row * MAX_COLUMNS + column;
    }

}
Related