Skip to content

Instantly share code, notes, and snippets.

@markjgap
Last active August 29, 2015 14:14
Show Gist options
  • Save markjgap/c799a720a5facf986fd6 to your computer and use it in GitHub Desktop.
Save markjgap/c799a720a5facf986fd6 to your computer and use it in GitHub Desktop.
Java program solves a Sudoku puzzle. It is able to target empty squares, search for all possible answers and apply an algorithm to determine the correct solution to complete the puzzle.
/*
* Java program used to solve a Sudoku puzzle. It is able to target empty squares, search for all possible answers
* and apply an algorithm to determine the correct solution to complete the puzzle.
*/
import java.util.*;
import java.io.*;
public class Sudoku {
public static void main (String[] args) {
// verifies if text file included in command line.
if (args.length < 1) {
System.out.println("Missing Sudoku File!");
System.out.println("Usage: java Sudoku <filename_1>.txt <filename_2>.txt ... <filename_n>.txt");
return;
}
for(int len = 0; len<args.length; len++){
List<Integer> boardInitVal = new ArrayList<Integer>();
int board[][] = new int[9][9]; // initialize board size
String fileName = new String(args[len]);
System.out.println("=======================");
System.out.println(fileName + "\n");
try { // try to load in external text file
File file = new File(fileName);
Scanner fileScanner = new Scanner(file);
while (fileScanner.hasNextInt()){
int num = fileScanner.nextInt();
boardInitVal.add(num);
}
fileScanner.close();
}
catch (FileNotFoundException e){
System.out.println("File " + fileName + " not found!");
e.printStackTrace();
}
// loops through and sets initial values to board
int index = 0;
for (int i=0; i<9; i++){
for (int j=0; j<9; j++){
board[i][j] = boardInitVal.get(index);
index++;
}
}
printBoard(board); //print board before solution
int runAgain = 0;
do{
runAgain = 0;
for (int i=0; i<9; i++){
for (int j=0; j<9; j++){
if (board[i][j] == 0){
List<Integer> numRange = Arrays.asList(1,2,3,4,5,6,7,8,9);
Set<Integer> range = new HashSet<Integer>();
Set<Integer> h = new HashSet<Integer>();
Set<Integer> v = new HashSet<Integer>();
Set<Integer> s = new HashSet<Integer>();
h = searchHorizontal(i,j, board); // returns all used integers in horizontal row
v = searchVertical(i,j, board); // returns all used integers in vertical row
s = searchSection(i,j, board); // returns all used integers in 3x3 section
h.addAll(v); // combines horizontal with vertical
h.addAll(s); // combines horizonal/vertical with 3x3 section
range.addAll(numRange); // list of 1-9 integers to compare with taken integers
range.removeAll(h); // finds all possible solutions
if(range.size()==1){ // if empty square has only 1 solution in range
board[i][j] = range.hashCode(); // fill it with that solution
runAgain = 1;
}
}
}
}
} while(runAgain==1); // Can not find solution using "easy" method algorithm
int solved = isSolved(board);
if(solved == 0){
System.out.println("Can not solve " + fileName);
System.out.println("Not an \"Easy\" Sudoku Puzzle");
System.out.println("=======================");
continue;
}
// if board has solution, prints solved board
else {
System.out.println("Solution to " + fileName + "\n");
printBoard(board);
System.out.println("=======================");
// writes solution to text file
try {
String outputFile = fileName.split("[.]")[0];
outputFile += "_sol.txt";
PrintWriter writer = new PrintWriter(outputFile);
for(int i = 0; i<9; i++){
for(int j = 0; j<9; j++){
writer.print(board[i][j]+ " ");
}
writer.println();
}
writer.close();
}
catch (IOException e){
System.out.println("Error: Could not saved a solutions file");
e.printStackTrace();
return;
}
}
}
}
////////// methods //////////
/*
* Checks to see if board has been completely solved. If there are any 0's
* thenboard is unsolved. 0's are meant as an empty square.
* @param board - a 2D array that represents a 9x9 sudoku board
* @return - 0 if unsolved board. 1 if solved board.
*/
public static int isSolved(int[][] board){
for(int i=0; i<9; i++){
for(int j=0; j<9; j++){
if(board[i][j] == 0){
return 0;
}
}
}
return 1;
}
/*
* Prints the sudoku board
* @param board - a 2D array that represents a 9x9 sudoku board
*/
public static void printBoard(int[][] board){
int horLine = 0;
int vertLine = 1;
for (int i=0; i<9; i++){
if(horLine%3==0 && horLine%9!=0){
System.out.println("----------------------");
}
horLine++;
for (int j=0; j<9; j++){
System.out.print(board[i][j] + " ");
if(vertLine%3==0 && vertLine%9!=0){
System.out.print("| ");
}
vertLine++;
}
System.out.println();
}
System.out.println();
}
/*
* Gathers all integers from a particular row
* @param x - the x cooridinate of an empty square
* @param y - the y cooridinate of an empty square
* @param board - a 2D array that represents a 9x9 sudoku board
* @return - a set of integers from a particular row
*/
public static Set<Integer> searchHorizontal(int x, int y, int[][] board){
Set<Integer> horizontalSet = new HashSet<Integer>();
for(int j = 0; j<9; j++){
horizontalSet.add(board[x][j]);
}
return horizontalSet;
}
/*
* Gathers all integers from a particular column
* @param x - the x cooridinate of an empty square
* @param y - the y cooridinate of an empty square
* @param board - a 2D array that represents a 9x9 sudoku board
* @return - a set of integers from a particular column
*/
public static Set<Integer> searchVertical(int x, int y, int[][] board){
Set<Integer> verticalSet = new HashSet<Integer>();
for(int i = 0; i<9; i++){
verticalSet.add(board[i][y]);
}
return verticalSet;
}
/*
* Gathers all integers from a particular 3x3 section
* @param x - the x cooridinate of an empty square
* @param y - the y cooridinate of an empty squarde
* @param board - a 2D array that represents a 9x9 sudoku board
* @return - a set of integers from a particular section
*/
public static Set<Integer> searchSection(int i, int j, int[][] board){
Set<Integer> sectionSet = new HashSet<Integer>();
int xPos = i < 3 ? 0 : i < 6 ? 3 : 6; // finds the x position of the first square of a section
int yPos = j < 3 ? 0 : j < 6 ? 3 : 6; // finds the y position of the first square of a section
for(int x1 = xPos; x1 < xPos+3; x1++){
for(int y1 = yPos; y1 < yPos+3; y1++){
sectionSet.add(board[x1][y1]);
}
}
return sectionSet;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment