package test.anlyze.test9Matrix; import java.util.Iterator; import java.util.LinkedList; import java.util.Stack; public class Test9 { public static void main(String[] args) { String[] sdata = new String[] { " 7 8 ", " 4 3 ", " 9 1", "6 5 ", " 1 3 4 ", " 5 1 7", "5 2 6 ", " 3 8 9 ", " 7 2"}; int[] data = new int[81]; for (int row = 0; row < 9; row++) { char[] rowData = sdata[row].toCharArray(); for (int j = 0; j < 9; j++) { if(rowData[j]!=' '){ data[row * 9 + j] = rowData[j] - '0' ; }else{ data[row * 9 + j] = 0; } } } tryResolve(data); } static class Item { public Item(int row, int column, int value) { this.row = row; this.column = column; this.value = value; } int row; int column; int value; ItemStatus status; @Override public String toString() { return "[" + row + "," + column + "] -> " + value + "(" + status + ")"; } public boolean canbe() { return status == ItemStatus.ForceOK || status == ItemStatus.OK; } } static enum ItemStatus { ForceOK, ForceTryFailure, OK, MaybeOK, MaybeNot } static int[] tryResolve(int[] data) { long startNano = System.nanoTime(); LinkedList<Item> e; boolean succeed = true; @SuppressWarnings("unchecked") LinkedList<Item>[] buf = new LinkedList[81]; for (int row = 0; row < 9; row++) { for (int column = 0; column < 9; column++) { buf[row * 9 + column] = new LinkedList<Item>(); buf[row * 9 + column].add(new Item(row, column, data[row * 9 + column])); } } printGraph("Init status", buf); OuterFor: for (int row = 0; row < 9; row++) { for (int column = 0; column < 9; column++) { e = buf[row * 9 + column]; if (e.getFirst().value != 0) continue; Item i = e.pop(); e.clear(); e.push(i); for (int d = 1; d <= 9; d++) { if (maybe(buf, d, row, column)) { Item it = new Item(row, column, d); it.status = ItemStatus.MaybeOK; e.add(it); } } if (e.size() == 2) { e.pop(); System.out.println("exclude(" + row + "," + column + ") : " + e.getFirst().value); e.getFirst().status = ItemStatus.OK; row = -1; column = 0; continue OuterFor; } } } printGraph("before last try", buf); Stack<Item> sa = new Stack<Test9.Item>(); OuterFor: for (int row = 0; row < 9; row++) { for (int column = 0; column < 9; column++) { e = buf[row * 9 + column]; Iterator<Item> ii = e.listIterator(1); int cnt = 0; while (ii.hasNext()) { Item i = ii.next(); if (i.status == ItemStatus.ForceOK) break; if (i.status == ItemStatus.OK) break; if (i.status == ItemStatus.MaybeOK) { cnt++; } } if (cnt != 2) continue; ii = e.listIterator(1); while (ii.hasNext()) { Item i = ii.next(); if (i.status == ItemStatus.MaybeOK) { sa.push(i); } } break OuterFor; } } if (!sa.isEmpty()) { sa.peek().status = ItemStatus.ForceOK; } MainFor: for (int c = 0; c < 1000 && !sa.isEmpty(); c++) { printGraph("Step[" + (c + 1) + "] Start parce when set " + sa.peek().toString(), buf); for (int row = 0; row < 9; row++) { for (int column = 0; column < 9; column++) { e = buf[row * 9 + column]; Iterator<Item> ii = e.listIterator(1); while (ii.hasNext()) { Item item = ii.next(); if (item.status == ItemStatus.ForceOK || item.status == ItemStatus.ForceTryFailure) { } else { item.status = ItemStatus.MaybeNot; } } } } succeed = true; OuterFor: for (int row = 0; row < 9; row++) { InnerFor: for (int column = 0; column < 9; column++) { e = buf[row * 9 + column]; if (e.getFirst().value != 0) continue; Iterator<Item> ii = e.listIterator(1); while (ii.hasNext()) { Item item = ii.next(); if (item.status == ItemStatus.ForceOK) { continue InnerFor; } else if (item.status == ItemStatus.OK) { continue InnerFor; } } int cnt = 0; Item lastOk = null; ii = e.listIterator(1); while (ii.hasNext()) { Item item = ii.next(); if (maybe(buf, item.value, row, column)) { item.status = ItemStatus.MaybeOK; lastOk = item; cnt++; } else { item.status = ItemStatus.MaybeNot; } } if (cnt == 1) { lastOk.status = ItemStatus.OK; row = -1; column = 0; succeed = true; continue OuterFor; } else { succeed = false; } if (cnt == 0) { System.out.println("Fail At " + e.getFirst()); printStack(sa); while (!sa.isEmpty()) { if (sa.peek().status == ItemStatus.ForceOK) { Item item = sa.pop(); item.status = ItemStatus.MaybeOK; } else { sa.peek().status = ItemStatus.ForceOK; printStack(sa); row = -1; column = 0; continue MainFor; } } printGraph("Exception", buf); break MainFor; } } } if (succeed) { break MainFor; } printGraph("Finish parce when set : " + sa.peek().toString(), buf); OuterFor: for (int tryDeep = 2; tryDeep < 9; tryDeep++) { for (int row = 0; row < 9; row++) { for (int column = 0; column < 9; column++) { e = buf[row * 9 + column]; Iterator<Item> ii = e.listIterator(1); int cnt = 0; while (ii.hasNext()) { Item i = ii.next(); if (i.status == ItemStatus.ForceOK) { cnt = 0; break; } else if (i.status == ItemStatus.OK) { cnt = 0; break; } else if (i.status == ItemStatus.MaybeOK) { cnt++; } } if (cnt != tryDeep) continue; ii = e.listIterator(1); while (ii.hasNext()) { Item i = ii.next(); if (i.status == ItemStatus.MaybeOK) { sa.push(i); } } sa.peek().status = ItemStatus.ForceOK; System.out.println("Add path"); printStack(sa); break OuterFor; } } } } long endNano = System.nanoTime(); System.out.println(""); System.out.print("\n---- Cost " + (endNano - startNano) / 1000000 + " ms"); if (succeed) { System.out.println("**************************************"); System.out.println("* *"); System.out.println("* SUCCEED *"); System.out.println("* *"); System.out.println("**************************************"); printGraph("", buf); } else { System.out.println("**************************************"); System.out.println("* *"); System.out.println("* FAILURE *"); System.out.println("* *"); System.out.println("**************************************"); } return new int[0]; } static void printStack(Stack<Item> sa) { System.out.println("=========Stack<Item> sa========"); for (Item i : sa) { System.out.println(" >> " + i.toString() + "'" + i.status); } } static boolean maybe(LinkedList<Item>[] buf, int d, int checkedRow, int checkedColumn) { LinkedList<Item> e; for (int row = 0; row < 9; row++) { if (checkedRow == row) continue; e = buf[row * 9 + checkedColumn]; if (e.getFirst().value == d) { return false; } for (Item item : e) { if (item.value == d && item.canbe()) { return false; } } } for (int column = 0; column < 9; column++) { if (checkedColumn == column) continue; e = buf[checkedRow * 9 + column]; if (e.getFirst().value == d) { return false; } for (Item item : e) { if (item.value == d && item.canbe()) { return false; } } } int subGridStartRow = checkedRow - checkedRow % 3; int subGridStartColumn = checkedColumn - checkedColumn % 3; for (int row = subGridStartRow; row < subGridStartRow + 3; row++) { for (int column = subGridStartColumn; column < subGridStartColumn + 3; column++) { e = buf[row * 9 + column]; if (checkedColumn == column) continue; if (e.getFirst().value == d) { return false; } for (Item item : e) { if (item.value == d && item.canbe()) { return false; } } } } return true; } static void printGraph(String msg, LinkedList<Item>[] buf) { System.out.print("\n================================================\n" + msg); for (int row = 0; row < 9; row++) { System.out.println("\n"); InnerFor: for (int column = 0; column < 9; column++) { System.out.print("\t"); LinkedList<Item> e = buf[row * 9 + column]; if (e.size() == 1) System.out.print("[" + e.getFirst().value + "]"); else { for (Item t : e) { if (t.status == ItemStatus.ForceOK ) { System.out.print("<" + t.value + ">"); continue InnerFor; } } for (Item t : e) { if (t.status == ItemStatus.OK) { System.out.print("(" + t.value + ")"); continue InnerFor; } } for (Item t : e) { if (t.status == ItemStatus.MaybeOK) System.out.print("" + t.value + ""); } for (Item t : e) { if (t.status == ItemStatus.MaybeNot) System.out.print("-" + t.value + ""); } } } } } }