Last active
September 17, 2015 10:08
-
-
Save phamtm/45b74302819576231562 to your computer and use it in GitHub Desktop.
A solver for Sudoku
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
public class SudokuSolver { | |
int[] board = new int[81]; | |
char[] in = null; | |
boolean[][] findLimits() { | |
boolean[][] ok = new boolean[81][9]; | |
for (int i = 0; i < 81; i++) { | |
for (int j = 0; j < 9; j++) { | |
ok[i][j] = true; | |
} | |
} | |
for (int i = 0; i < 81; i++) { | |
limitOthersFrom(i, ok); | |
} | |
return ok; | |
} | |
int nextMove(boolean[][] ok) { | |
int minval = 100, minidx = 0; | |
for (int idx = 0; idx < 81; idx++) { | |
int numChoices = countChoices(idx, ok); | |
if (numChoices > 0 && numChoices < minval) { | |
minval = numChoices; | |
minidx = idx; | |
} | |
} | |
return minidx; | |
} | |
void limitOthersFrom(int idx, boolean[][] ok) { | |
int r = idx / 9; | |
int c = idx % 9; | |
if (board[idx] == -1) { | |
return; | |
} | |
int br = r/3; | |
int bc = c/3; | |
int val = board[idx]; | |
// limit itself | |
for (int i = 0; i < 9; i++) { | |
ok[idx][i] = false; | |
} | |
// limit row | |
for (int cc = 0; cc < 9; cc++) { | |
ok[r * 9 + cc][val] = false; | |
} | |
// limit col | |
for (int rr = 0; rr < 9; rr++) { | |
ok[rr * 9 + c][val] = false; | |
} | |
// limit block | |
for (int i = 0; i < 9; i++) { | |
int rr = br*3 + i/3; | |
int cc = bc*3 + i%3; | |
ok[rr * 9 + cc][val] = false; | |
} | |
} | |
public void display() { | |
for (int i = 0; i < 9; i++) { | |
for (int j = 0; j < 9; j++) { | |
System.out.print((board[i * 9 + j] + 1) + " "); | |
} | |
System.out.println(); | |
} | |
System.out.println(); | |
} | |
public int countChoices(int idx, boolean[][] ok) { | |
int count = 0; | |
for (int i = 0; i < 9; i++) { | |
if (ok[idx][i]) { | |
count++; | |
} | |
} | |
return count; | |
} | |
public boolean solve() { | |
boolean[][] ok = findLimits(); | |
int idx = nextMove(ok); | |
if (countChoices(idx, ok) == 0) { | |
display(); | |
return true; | |
} | |
for (int i = 0; i < 9; i++) { | |
if (ok[idx][i]) { | |
board[idx] = i; | |
boolean res = solve(); | |
if (res) { | |
return true; | |
} | |
board[idx] = -1; | |
} | |
} | |
return false; | |
} | |
public void read(String in) { | |
if (in == null || in.length() != 81) { | |
throw new IllegalArgumentException(); | |
} | |
this.in = in.toCharArray(); | |
for (int idx = 0; idx < in.length(); idx++) { | |
char ch = in.charAt(idx); | |
if (ch >= '1' && ch <= '9') { | |
board[idx] = ch - '1'; | |
} else { | |
board[idx] = -1; | |
} | |
} | |
} | |
public static void main(String[] args) { | |
SudokuSolver ss = new SudokuSolver(); | |
String in = "......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3."; | |
ss.read(in); | |
long from = System.currentTimeMillis(); | |
ss.solve(); | |
long to = System.currentTimeMillis(); | |
float delta = (float)(to - from)/1000; | |
System.out.println(delta); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment