1

A friend gave me a class that tries to solve sudoku puzzels. Thing is the changes of the array inside the method is not reflected in the original array. Here's the code:

public static void solve(int array[][], int row, int col)   
    {   
        if( row > 8 )
        {
            printBoard(array); // this gives the correct result
            return;
        }
        if( array[row][col] != 0 )
            nextEmptyCell(array, row, col );
        else
        {
            for( int num = 1; num < 10; num++ )
            {
                if(validityRowColBox(array, row, col, num))
                {
                    array[row][col] = num;
                    nextEmptyCell(array, row, col);
                }
            }
            array[row][col] = 0;
        }
    }

    public static void nextEmptyCell(int array[][], int row, int col)
    {
        if( col < 8 )
            solve(array, row, col + 1 );
        else
            solve(array, row + 1, 0 );
    }

    //This boolean methods will checks the validity of the number for the given row, columns and its designated box.
    public static boolean validityRowColBox(int array[][], int row, int col, int num)
    {
        for(int c = 0; c <9; c++ )
        {
            if( array[row][c] == num )
                return false;// It return false if the number is already exist in the given row.
        }
        for(int r = 0; r <9; r++ )
        {
            if(array[r][col] == num )
                return false;// It return false if the number is already exist in the given columns.
        }
        row = (row / 3) * 3 ;
        col = (col / 3) * 3 ;
        for( int r = 0; r < 3; r++ )
        {
            for( int c = 0; c < 3; c++ )
            {
                if( array[row+r][col+c] == num )
                    return false;// It return false if the number is already exist in the designated box.
            }
        }
        return true;// Otherwise true.
    }

    // sample input
    public static int[][] easy ()
    {
        return new int[][]
                {{0,0,0,2,6,0,7,0,1},
            {6,8,0,0,7,0,0,9,0},
            {1,9,0,0,0,4,5,0,0},
            {8,2,0,1,0,0,0,4,0},
            {0,0,4,6,0,2,9,0,0},
            {0,5,0,0,0,3,0,2,8},
            {0,0,9,3,0,0,0,7,4},
            {0,4,0,0,5,0,0,3,6},
            {7,0,3,0,1,8,0,0,0}};
    }

    public static void main(String args[])
    {
        int inputArray[][] = easy();
        solve(inputArray,0,0);
        printBoard(inputArray); // items still the same!
    }
}

If I call the printBoard(array); function inside the method, the elements of the array appears to change. But when I call the printBoard(array); method in the main method on the original array, the changes are lost, the values are back to original again. I am extremely confused by this. None of the methods creates a new object so it should still point to the inputArray object. What's happening?

Edit: Here's the printBoard() method

public static void printBoard(int array[][])
{
    //This is the board method.  
    for (int row = 0; row < array.length; row++) 
    {
        if (row % 3 == 0)//If the row is divisible by 3 then print the plus(+) and minus(-) sign.
            System.out.println("+-------+-------+-------+");
        for (int col = 0; col < array[row].length; col++) {
            if (col % 3 == 0)// If the column is divisible by 3 then print the or(|) symbol. 
                System.out.print("| ");

            System.out.print(array[row][col]+ " ");
        }
        System.out.println("|");
    }
    System.out.println("+-------+-------+-------+");
}
Enzokie
  • 7,365
  • 6
  • 33
  • 39
lightning_missile
  • 2,821
  • 5
  • 30
  • 58

1 Answers1

1

The problem is that when you come back from the various recursive calls there is an instruction that modify the content of the array (see the comments):

for( int num = 1; num < 10; num++ )
{
    if(validityRowColBox(array, row, col, num))
    {
        array[row][col] = num;
        nextEmptyCell(array, row, col);    // after you finish you come back from here
    }
}
array[row][col] = 0;   // ...and this will change the solution you found

Apparently this cause the array to come back to his original state.

I didn't look how the program works but avoiding to execute that instruction if we found the solution will return the correct array, for example:

public static boolean solve(int array[][], int row, int col) {
    if (row > 8) {
        printBoard(array);
        return true;
    }
    if (array[row][col] != 0) {
        return nextEmptyCell(array, row, col);
    }

    for (int num = 1; num < 10; num++) {
        if (validityRowColBox(array, row, col, num)) {
            array[row][col] = num;
            if (nextEmptyCell(array, row, col)) {
                return true;          // if solution is found we just exit
            }
        }
    }

    array[row][col] = 0;

    return false;
}

public static boolean nextEmptyCell(int array[][], int row, int col) {
    if (col < 8) {
        return solve(array, row, col + 1);
    }
    return solve(array, row + 1, 0);
}
Loris Securo
  • 7,538
  • 2
  • 17
  • 28