Last active
August 29, 2015 14:25
-
-
Save jiahaoliuliu/05838fd5a0300ae05fbb to your computer and use it in GitHub Desktop.
Sudoku checker. Simple checker for Sudoku with complexity O(N^2)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.jiahaoliuliu.sudokuchecker; | |
import java.util.ArrayList; | |
import java.util.HashSet; | |
import java.util.Set; | |
/** | |
* A class to check the if the content of a Sudoku is correct or not. The complexity of the algorithm | |
* has been kept to O(N^2), instead of O(N^3) for the cube check. | |
* | |
* @author Jiahaoliuliu | |
* @main [email protected] | |
* @blog jiahaoliuliu.com | |
* @Twitter @jiahaoliuliu | |
* Created on 20th of July 2015 | |
*/ | |
public class SudokuChecker { | |
/** | |
* The final sum of the row, column or so of Sudoku. This is used to check if a row, a column | |
* and a single cube (3x3) is correct or not. | |
*/ | |
private static final int ROW_SUM = 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9; | |
// The size of the cube. This value can be changed to change the size of the cube. | |
// If so, the value of ROW_SUM must be changed as well. | |
private static final int CUBE_SIZE = 3; | |
// Variable used to test the row and column checker | |
private static int[][] sudoku = new int[][]{ | |
// Row 1 | |
{1, 2, 3, 4, 5, 6, 7, 8, 9}, | |
// Row 2 | |
{2, 3, 4, 5, 6, 7, 8, 9, 1}, | |
// Row 3 | |
{3, 4, 5, 6, 7, 8, 9, 1, 2}, | |
// Row 4 | |
{4, 5, 6, 7, 8, 9, 1, 2, 3}, | |
// Row 5 | |
{5, 6, 7, 8, 9, 1, 2, 3, 4}, | |
// Row 6 | |
{6, 7, 8, 9, 1, 2, 3, 4, 5}, | |
// Row 7 | |
{7, 8, 9, 1, 2, 3, 4, 5, 6}, | |
// Row 8 | |
{8, 9, 1, 2, 3, 4, 5, 6, 7}, | |
// Row 9 | |
{9, 1, 2, 3, 4, 5, 6, 7, 8} | |
}; | |
// Variable used to test the cube checker | |
private static int[][] sudoku2 = new int[][]{ | |
// Row 1 | |
{ 0, 1, 2, 3, 4, 5, 6, 7, 8}, | |
// Row 2 | |
{10, 11, 12, 13, 14, 15, 16, 17, 18}, | |
// Row 3 | |
{20, 21, 22, 23, 24, 25, 26, 27, 28}, | |
// Row 4 | |
{30, 31, 32, 33, 34, 35, 36, 37, 38}, | |
// Row 5 | |
{40, 41, 42, 43, 44, 45, 46, 47, 48}, | |
// Row 6 | |
{50, 51, 52, 53, 54, 55, 56, 57, 58}, | |
// Row 7 | |
{60, 61, 62, 63, 64, 65, 66, 67, 68}, | |
// Row 8 | |
{70, 71, 72, 73, 74, 75, 76, 77, 78}, | |
// Row 9 | |
{80, 81, 82, 83, 84, 85, 86, 87, 88} | |
}; | |
public static void main(String[] args) { | |
System.out.println("Checking sudoku"); | |
//Assuming all the column and all the rows have the same size (Sudoku = 9x9 cube) | |
int rowNumber = sudoku.length; | |
int columnNumber = sudoku[0].length; | |
// Check for the rows | |
ROW_MAIN_FOR: for (int i = 0; i < rowNumber; i++) { | |
Set<Integer> content = new HashSet<Integer>(); | |
int[] row = sudoku[i]; | |
for (int j = 0; j < columnNumber; j++) { | |
content.add(row[j]); | |
} | |
if (!areContentValid(content)) { | |
System.out.println("The follow content is not valid. " + content); | |
break ROW_MAIN_FOR; | |
} | |
} | |
// Check for the columns. | |
// Get the size of the cube | |
COLUMN_MAIN_FOR: for (int i = 0; i < columnNumber; i++) { | |
Set<Integer> content = new HashSet<Integer>(); | |
for (int j = 0; j < rowNumber; j++) { | |
content.add(sudoku[j][i]); | |
} | |
if (!areContentValid(content)) { | |
break COLUMN_MAIN_FOR; | |
} | |
} | |
// Checking for the cubes | |
// Assuming that the size of the Sudoku is multiple of 3(CUBE_SIZE) | |
// Prepare the data | |
ArrayList<HashSet<Integer>> cubes = new ArrayList<HashSet<Integer>>(); | |
for (int i = 0; i < rowNumber; i++) { | |
for (int j = 0; j < columnNumber; j++) { | |
// The cube number is calculated based on the position of the item. | |
// i / CUBE_SIZE gives the entire number of the cube, without rest. This value multiply by CUBE_SIZE gives the row of the cube | |
// (not the row of the item). Then add j / CUBE_SIZE gives the column of the cube (not the column of the item). | |
int cubeNumber = (i/CUBE_SIZE)*CUBE_SIZE + (j/CUBE_SIZE); | |
System.out.println("The element " + i + ", " + j + " belongs to the cube " + cubeNumber); | |
HashSet<Integer> cube; | |
if (cubes.size() <= cubeNumber || cubes.get(cubeNumber) == null) { | |
cube = new HashSet<Integer>(); | |
cubes.add(cubeNumber, cube); | |
} else { | |
cube = cubes.get(cubeNumber); | |
} | |
cube.add(sudoku[i][j]); | |
} | |
} | |
// Check them | |
for (int i = 0; i < cubes.size(); i++) { | |
HashSet<Integer> cube = cubes.get(i); | |
if (!areContentValid(cube)) { | |
System.out.println("The cube number " + i + " is not valid. It's content is " + cube); | |
break; | |
} | |
} | |
System.out.println("Check complete. The data is valid"); | |
} | |
/** | |
* Check if the content is valid or not. | |
* A content is valid if for the values between 1 and 9, both incluse, the sum of them | |
* is the same as the sum of 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9; | |
*/ | |
private static boolean areContentValid(Set<Integer> content) { | |
int result = 0; | |
for (Integer i : content) { | |
if (i >= 1 && i <= 9) { | |
result += i; | |
} | |
} | |
return result == ROW_SUM; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment