0

I'm trying to code a method which checks for duplicates on my Sudoku board. Currently, my method getFrontier() always returns true, and I've come to learn that it's because it's only checking for one value rather than an array or values. I use the method 3 times in squareCheck(), rowCheck() and columnCheck(). Is there any way to code the method so it would retain the previous value which was input and then check it against the new value?

My current code:

  public class validCheck {

public boolean isSolved(int[][][] board)
{
    for(int index = 0; index < board.length;index++)
    {
        for(int r = 0; r < board[0].length; r++)
        {
            for(int c = 0; c < board[0].length;c++)
            {
                if(board[index][r][c] == 0)
                  return false;
            }
        }
    }
    return true;
} 


 public boolean getFrontier(int value)
{
 Set<Integer> reserve = new HashSet<>();

 for(int n = 1; n < 10; n++)
 {
     if(value == n && reserve.contains(n))
         return false;

     else if(value == n) reserve.add(n);     
 }
return true;
}

public boolean squareCheck(int[][][] board, int index)
{
    for(int r = 0; r < board[0].length; r++)
    {
        for(int c = 0; c < board[0].length; c++)
        {
            if(!getFrontier(board[index][r][c]))
            {
                System.out.println("Square error at ["+index + r + c +"]");
                return false;
            }
        }
    }

    return true;

}

 public boolean isValid(int[][][] board)
 {     
     if(isSolved(board))
     {
        for(int i = 0; i < board.length; i++)
        {
            for(int r = 0; r < board[0].length;r++)
            {
                for(int c = 0; c < board[0].length;c++)
                {
                    if(!rowCheck(board,i,r) || !columnCheck(board,i,c) || !squareCheck(board,i))
                    {
                        return false;
                    }
                }
            }
        }
     }

     return true;

 }

 public boolean columnCheck(int[][][] board, int index, int col)
 {
     int target = 0;     

     if(index <=2)
     {
         target = index + 6;
     }
     else if(index > 2 && index < 6)
    {
        target = index +3;
        index = index - 3;
    }
     else if (index > 5)
     {
         target = index;
         index = index - 6;
     }

     while(index <= target)
     {
         for(int r = 0; r < board[0].length;r++)
         {

            if(!getFrontier(board[index][r][col]))
            {
                System.out.println("Column error at " + index + r + col);
                return false;    
            } 

         }
         index = index + 3;
     }
     return true;


 }


 public boolean rowCheck(int[][][] board, int index, int row)
 {
     int target = 0;

     if(index <= 2)
     {
         index = 0;
         target = 2;
     }
     else if (index <= 5)
     {
         index = 3;
         target  = 5;
     }
     else if(index <= 8)
     {
         index = 6;
         target = 8;
     }

     while(index <= target)
     {
            for(int c = 0; c < board[0].length; c++)
            {
                   if(!getFrontier(board[index][row][c]))
                   {
                       System.out.println("Row error at "+index+row+c);
                       return false;
                   }
             }
             index++;
      }

      return true;

     }


 }

Usage:

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


validCheck checker = new validCheck();

       if(checker.isValid(solved))
            System.out.println(true);

       else System.out.println(false);
}

Any help will be greatly be appreciated!!!

  • What is the expected behaviour of the method? How is it different from the actual behaviour? – pvg Dec 23 '16 at 18:32
  • 1
    i would suggest using a 2D array since you have to check that an entire column and an entire row is sequential when verifying a valid sudoku board – RAZ_Muh_Taz Dec 23 '16 at 18:35
  • What is `getFrontier`'s purpose? "Frontier" to me means the Western U.S. in the 1800s, or something similar, so the method name isn't helpful, and there aren't any comments. Since that's the method where you seem to want to use a `HashSet`, I'd need to know what you want this method to do in order to help. – ajb Dec 23 '16 at 18:36
  • Sorry, about the name, my teacher kinda recommended. I want to use the method to check for duplicates and for the numbers 1-9. The method is later used in my squareCheck(), rowCheck() and columnCheck() methods. –  Dec 23 '16 at 18:39
  • I'd would've also like to use 2D array since it would've have been a lot easier, however my teacher expects us to use a 3D array for this project –  Dec 23 '16 at 18:40
  • @pvg when I use the method it outputs "Row error at 000" and the whole board to be "false" even though it isn't –  Dec 23 '16 at 18:41
  • I'm sorry, but what does work wrong? I tested your code, the array has duplicates and it returns "false". – Ihor Dobrovolskyi Dec 23 '16 at 18:42
  • That doesn't seem to have anything to do with your question though. Is your question 'my code doesn't work, fix it?'. Because that's not a good SO question. If you have a specific question, try to explain it clearly. And edit your question to include the explanation. – pvg Dec 23 '16 at 18:45
  • @ИгорьДобровольський I want to use the method to check for duplicates in each row, column and 3x3 grid. However, the method always returns "Row error at 000" "false" even though that isn't the case if you look at the board above. I use the method in the other methods(look at my first comment!). –  Dec 23 '16 at 18:47
  • Possible duplicate of [Java Array, Finding Duplicates](http://stackoverflow.com/questions/3951547/java-array-finding-duplicates) – pvg Dec 23 '16 at 18:53
  • this a duplicate of the zillions of questions about using a hashset to find dupes. I've linked one. Your problem is you're just giving your method a number, checking if a brand new empty set contains the number and finding out it doesn't. You need to put all the things you want to dupe-check in the set. – pvg Dec 23 '16 at 18:54
  • How is `getFrontier` supposed to find duplicates, when you pass one single number into it? Is `getFrontier(3)` a duplicate? Or `getFrontier(9)`? When you want to check for dupes, then you need collect all numbers from a row, a column or a square and not a single number from "somewhere". – Tom Dec 23 '16 at 18:55

1 Answers1

0

Here is what I would do to find a valid board config in a 2D sudoku board. I would use a HashSet for a row and another for the column, as long as we never encounter repeats and the values contain 1 to the length of the array we know the board is valid.

    int [][] board = {{1,2,3}, 
                      {2,3,1}, 
                      {3,1,2}
                      };
    HashSet<Integer> rowDuplicates = new HashSet<>();
    HashSet<Integer> colDuplicates = new HashSet<>();
    boolean invalidBoard = false;

    for(int i = 0 ; i < board.length; i++)
    {
        for(int j = 0; j < board[i].length; j++)
        {
            if(rowDuplicates.contains(board[i][j]) || colDuplicates.contains(board[j][i]))
            {
                //this board is not valid
                invalidBoard = true;
            }
            else
            {
                rowDuplicates.add(board[i][j]);
                colDuplicates.add(board[j][i]);
            }
        }

        //now check they contain the correct numbers from 1 to the size of the array
        if(colDuplicates.size() == rowDuplicates.size())
        {
            for(int index = 0; index < colDuplicates.size(); index++)
            {
                if(!(colDuplicates.contains(index + 1) && rowDuplicates.contains(index + 1)))
                {
                    invalidBoard = true;
                    break;
                }
            }
        }
        else
        {
            invalidBoard = true;    
        }
        colDuplicates.clear();
        rowDuplicates.clear();

    }

    System.out.println("invalid board: " + invalidBoard);

You should be able to expand this to your 3D array but you can see how much easier it is to use HashSets to verify a valid 2D array Sudoku board.

RAZ_Muh_Taz
  • 4,059
  • 1
  • 13
  • 26
  • Thank you for taking the time to type that all out!! I got an idea after looking at your code too, so thank you! I really wish I could just use a 2D array, but I have to use a 3D one... –  Dec 23 '16 at 19:11
  • yeah i know but hopefully this will help you understand the logic needed to verify a Sudoku board using HashSets and you can use this to expand it to the 3D array @JAVANOOB – RAZ_Muh_Taz Dec 23 '16 at 19:13