CodeWars 여든 세 번째 문제

Updated:

Sudoku Solution Validator

import java.util.Arrays;
public class SudokuValidator {
    public static boolean check(int[][] sudoku) {
      
      if(!isRowColumn(sudoku) || !isMatrix(sudoku)) {
        return false;
      }
      
      return true;
    }

  private static boolean isMatrix(int[][] sudoku) {
    
    for(int i = 0; i < 9; i+=3) {
      for(int j = 0; j < 9; j+=3) {
        if(!isThreeMatrix(i, j, sudoku)) {
          return false;
        }
      }
    }
    
    return true;
  }

  private static boolean isThreeMatrix(int i, int j, int[][] sudoku) {
    int[] check = new int[9];
    
    for(int x = i; x < i+3; x++) {
      for(int y = j; y < j+3; y++) {
        
        if(sudoku[x][y] < 1 || sudoku[x][y] > 10) {
          return false;
        }
        
        if(check[sudoku[x][y]-1] != 0) {
          return false;
        }
        
        check[sudoku[x][y]-1] = sudoku[x][y];
      }
    }
    
    return true;
  }

  private static boolean isRowColumn(int[][] sudoku) {
    int[] checkRow = new int[9];
    int[] checkColumn = new int[9];
    
    for(int i = 0; i < 9; i++) {
      for(int j = 0; j < 9; j++) {
        if(sudoku[i][j] < 1 || sudoku[i][j] > 10 || sudoku[j][i] < 1 || sudoku[j][i] > 10) {
          return false;
        }
        
        if(checkRow[sudoku[i][j]-1] != 0 || checkColumn[sudoku[j][i]-1] != 0) {
          return false;
        }
        
        checkRow[sudoku[i][j]-1] = sudoku[i][j];
        checkColumn[sudoku[j][i]-1] = sudoku[j][i];
      }
      
      Arrays.fill(checkRow, 0);
      Arrays.fill(checkColumn, 0);
    }
    
    return true;
  }
}
  • 내가 평소 좋아하는 게임인 스도쿠 문제 였다.
  • 스도쿠가 맞았는지 확인하는 메소드를 작성하는 것이었다.
  • 모든 각각의 행과 열이 1부터 9까지 하나씩 있어야 하고 3X3행렬 9개 안에서도 1부터 0까지 하나씩 있어야 했다.
  • 처음에는 행 검사 메소드, 열 검사 메소드, 3X3행렬 검사 메소드 이렇게 3개를 만들려고 했는데 행과 열을 검사흔 메소드는 코드 형태가 유사하여 합쳤다.
  • 다른 Best 코드들의 경우 여러 가지가 있었으나 아래가 가장 깔끔했다.
  • 나와 다른 점은 Set의 특징인 중복 add가 되지 않는 다는 점을 이용하여 풀었다는 점이다.

  • 그리고 가장 큰 카이점은 3X3 행렬을 검사하는 것 이었는데 나는 4중 for을 이용하였다.
  • 그러나 Best 코드의 경우 %의 성질을 이용하여 3 중 for으로만 해결 하였다. 다이나믹 코드였다.
  • 다음에 잘 써먹어야겠다.
public static boolean check(int[][] sudoku) {
    return checkForZeros(sudoku) ? checkRows(sudoku) && checkCols(sudoku) && checkSquares(sudoku) : false;
}

public static boolean checkForZeros(int[][] sudoku) {
    for(int[] row : sudoku)
        for(int val : row)
            if(val == 0)
                return false; 
    return true;
}

public static boolean checkRows(int[][] sudoku) {
    Set<Integer> set = new HashSet<Integer>();
    for(int[] row : sudoku){
        set.clear();

        for(int val : row)
            set.add(val); 

        if(set.size() != 9)
            return false;
    }
    return true;
}

public static boolean checkCols(int[][] sudoku) {
    Set<Integer> set = new HashSet<Integer>();
    for(int i = 0; i<9; i++) {
        set.clear();

        for(int j = 0; j<9; j++)
            set.add(sudoku[j][i]);

        if(set.size() != 9)
            return false;
    }
    return true;
}

public static boolean checkSquares(int[][] sudoku) {
    Set<Integer> set = new HashSet<Integer>();
    for(int i = 0; i<9; i++) {
        int a = i%3 * 3;
        int b = a+2;
        int c = 3 * (i/3);
        int d = c+2;
        set.clear();
        for(int j = a; j<=b; j++)
            for(int k = c; k<=d ; k++) 
                set.add(sudoku[j][k]);
        System.out.println(set);
        if(set.size() != 9)
            return false;
    }
    return true;
}