Advertisement
mixeila

Untitled

Apr 22nd, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.78 KB | None | 0 0
  1.  
  2.  
  3. package assign3;
  4.  
  5. import java.util.*;
  6.  
  7. /*
  8. * Encapsulates a Sudoku grid to be solved.
  9. * CS108 Stanford.
  10. */
  11. public class Sudoku {
  12. // Provided grid data for main/testing
  13. // The instance variable strategy is up to you.
  14.  
  15. // Provided easy 1 6 grid
  16. // (can paste this text into the GUI too)
  17. public static final int[][] easyGrid = Sudoku.stringsToGrid(
  18. "1 6 4 0 0 0 0 0 2",
  19. "2 0 0 4 0 3 9 1 0",
  20. "0 0 5 0 8 0 4 0 7",
  21. "0 9 0 0 0 6 5 0 0",
  22. "5 0 0 1 0 2 0 0 8",
  23. "0 0 8 9 0 0 0 3 0",
  24. "8 0 9 0 4 0 2 0 0",
  25. "0 7 3 5 0 9 0 0 1",
  26. "4 0 0 0 0 0 6 7 9");
  27.  
  28.  
  29. // Provided medium 5 3 grid
  30. public static final int[][] mediumGrid = Sudoku.stringsToGrid(
  31. "530070000",
  32. "600195000",
  33. "098000060",
  34. "800060003",
  35. "400803001",
  36. "700020006",
  37. "060000280",
  38. "000419005",
  39. "000080079");
  40.  
  41. // Provided hard 3 7 grid
  42. // 1 solution this way, 6 solutions if the 7 is changed to 0
  43. public static final int[][] hardGrid = Sudoku.stringsToGrid(
  44. "3 7 0 0 0 0 0 8 0",
  45. "0 0 1 0 9 3 0 0 0",
  46. "0 4 0 7 8 0 0 0 3",
  47. "0 9 3 8 0 0 0 1 2",
  48. "0 0 0 0 4 0 0 0 0",
  49. "5 2 0 0 0 6 7 9 0",
  50. "6 0 0 0 2 1 0 4 0",
  51. "0 0 0 5 3 0 9 0 0",
  52. "0 3 0 0 0 0 0 5 1");
  53.  
  54.  
  55. public static final int SIZE = 9; // size of the whole 9x9 puzzle
  56. public static final int PART = 3; // size of each 3x3 part
  57. public static final int MAX_SOLUTIONS = 100;
  58.  
  59. // Provided various static utility methods to
  60. // convert data formats to int[][] grid.
  61.  
  62. /**
  63. * Returns a 2-d grid parsed from strings, one string per row.
  64. * The "..." is a Java 5 feature that essentially
  65. * makes "rows" a String[] array.
  66. * (provided utility)
  67. * @param rows array of row strings
  68. * @return grid
  69. */
  70. public static int[][] stringsToGrid(String... rows) {
  71. int[][] result = new int[rows.length][];
  72. for (int row = 0; row<rows.length; row++) {
  73. result[row] = stringToInts(rows[row]);
  74. }
  75. return result;
  76. }
  77.  
  78.  
  79. /**
  80. * Given a single string containing 81 numbers, returns a 9x9 grid.
  81. * Skips all the non-numbers in the text.
  82. * (provided utility)
  83. * @param text string of 81 numbers
  84. * @return grid
  85. */
  86. public static int[][] textToGrid(String text) {
  87. int[] nums = stringToInts(text);
  88. if (nums.length != SIZE*SIZE) {
  89. throw new RuntimeException("Needed 81 numbers, but got:" + nums.length);
  90. }
  91.  
  92. int[][] result = new int[SIZE][SIZE];
  93. int count = 0;
  94. for (int row = 0; row<SIZE; row++) {
  95. for (int col=0; col<SIZE; col++) {
  96. result[row][col] = nums[count];
  97. count++;
  98. }
  99. }
  100. return result;
  101. }
  102.  
  103.  
  104. /**
  105. * Given a string containing digits, like "1 23 4",
  106. * returns an int[] of those digits {1 2 3 4}.
  107. * (provided utility)
  108. * @param string string containing ints
  109. * @return array of ints
  110. */
  111. public static int[] stringToInts(String string) {
  112. int[] a = new int[string.length()];
  113. int found = 0;
  114. for (int i=0; i<string.length(); i++) {
  115. if (Character.isDigit(string.charAt(i))) {
  116. a[found] = Integer.parseInt(string.substring(i, i+1));
  117. found++;
  118. }
  119. }
  120. int[] result = new int[found];
  121. System.arraycopy(a, 0, result, 0, found);
  122. return result;
  123. }
  124.  
  125. // Provided -- the deliverable main().
  126. // You can edit to do easier cases, but turn in
  127. // solving hardGrid.
  128. public static void main(String[] args) {
  129. Sudoku sudoku;
  130. sudoku = new Sudoku(hardGrid);
  131.  
  132. System.out.println(sudoku); // print the raw problem
  133. int count = sudoku.solve();
  134. System.out.println("solutions:" + count);
  135. System.out.println("elapsed:" + sudoku.getElapsed() + "ms");
  136. System.out.println(sudoku.getSolutionText());
  137. }
  138.  
  139. private Spot[][] base;
  140. private ArrayList<Spot> spotList;
  141. private int[][] resultGrid;
  142. private long usedTime;
  143.  
  144.  
  145.  
  146. /**
  147. * Sets up based on the given ints.
  148. */
  149. public Sudoku(int[][] ints) {
  150. base = new Spot[SIZE][SIZE];
  151. spotList = new ArrayList<Spot>();
  152. for(int i=0; i<SIZE; i++) {
  153. for(int j=0; j<SIZE; j++) {
  154. base[i][j] = new Spot(i, j, ints[i][j]);
  155. if(base[i][j].value==0)
  156. spotList.add(base[i][j]);
  157. }
  158. }
  159. for(int i=0; i<SIZE; i++) {
  160. for(int j=0; j<SIZE; j++) {
  161. int currVar = getValidList(i, j).size();
  162. base[i][j].setVariance(currVar);
  163. }
  164. }
  165. Collections.sort(spotList, new sortByVariance());
  166. }
  167.  
  168. class sortByVariance implements Comparator<Spot> {
  169. public int compare(Spot first, Spot second) {
  170. return first.compareByVariance(second);
  171. }
  172. }
  173.  
  174. /**
  175. * Solves the puzzle, invoking the underlying recursive search.
  176. */
  177. public int solve() {
  178. long startTime = System.currentTimeMillis();
  179. mutableInt result = new mutableInt();
  180. getSolveNum(0, result);
  181. long endTime = System.currentTimeMillis();
  182. usedTime = endTime-startTime;
  183. return result.getValue();
  184. }
  185.  
  186. public void getSolveNum(int index, mutableInt result) {
  187. if(result.getValue()==100) return;
  188. if(index==spotList.size()) {
  189. if(resultGrid == null) {
  190. resultGrid = new int[SIZE][SIZE];
  191. for(int i=0; i<SIZE; i++) {
  192. for(int j=0; j<SIZE; j++) {
  193. resultGrid[i][j] = base[i][j].getValue();
  194. }
  195. }
  196. }
  197. result.setValue(result.getValue()+1);
  198. return;
  199. }
  200. Spot curr = spotList.get(index);
  201. ArrayList<Integer> variances = getValidList(curr.getRow(), curr.getColumn());
  202. for(int i=0; i<variances.size(); i++) {
  203. curr.setValue(variances.get(i));
  204. getSolveNum(index+1, result);
  205. }
  206. curr.setValue(0);
  207. }
  208.  
  209. public String getSolutionText() {
  210. if(resultGrid==null) return "";
  211. String result = "";
  212. for(int i=0; i<SIZE; i++) {
  213. for(int j=0; j<SIZE; j++) {
  214. result += resultGrid[i][j]+" ";
  215. }
  216. result +="\n";
  217. }
  218. return result;
  219. }
  220.  
  221. public long getElapsed() {
  222. return usedTime;
  223. }
  224.  
  225. private class Spot {
  226. private int value;
  227. private int column;
  228. private int row;
  229. private int variance;
  230.  
  231. public Spot(int row, int column, int value) {
  232. this.value = value;
  233. this.column = column;
  234. this.row = row;
  235. }
  236.  
  237. public void setValue(int value) {
  238. this.value = value;
  239. }
  240.  
  241. public int getValue() {
  242. return value;
  243. }
  244.  
  245. public int getRow() {
  246. return row;
  247. }
  248.  
  249. public int getColumn() {
  250. return column;
  251. }
  252.  
  253. public void setVariance(int variance) {
  254. this.variance = variance;
  255. }
  256.  
  257. public int getVariance() {
  258. return variance;
  259. }
  260.  
  261. public int compareByVariance(Spot second) {
  262. return this.variance-second.getVariance();
  263. }
  264. }
  265. public ArrayList<Integer> getValidList(int row, int column){
  266. ArrayList<Boolean> check = new ArrayList<Boolean>();
  267. for(int i=0; i<SIZE; i++) {
  268. check.add(false);
  269. }
  270. checkSquare(check, row, column);
  271. checkColumn(check, row, column);
  272. checkRow(check, row, column);
  273. ArrayList<Integer> result = new ArrayList<Integer>();
  274. for(int i=0; i<check.size(); i++) {
  275. if(!check.get(i)) result.add(i+1);
  276. }
  277. return result;
  278. }
  279. private void checkSquare(ArrayList<Boolean> arr, int row, int column) {
  280. for(int i=0; i<PART; i++) {
  281. int currRow = row-row%PART+i;
  282. for(int j=0; j<PART; j++) {
  283. int currCol = column-column%PART+j;
  284. int currValue = base[currRow][currCol].value;
  285. if(currValue!=0) arr.set(currValue-1, true);
  286. }
  287. }
  288. }
  289. private void checkRow(ArrayList<Boolean> arr, int row, int column) {
  290. int bound = row-row%PART;
  291. for(int i=0; i<bound; i++) {
  292. int currValue = base[i][column].value;
  293. if(currValue!=0)
  294. arr.set(currValue-1, true);
  295. }
  296. for(int i=bound+PART; i<SIZE; i++) {
  297. int currValue = base[i][column].value;
  298. if(currValue!=0)
  299. arr.set(currValue-1, true);
  300. }
  301. }
  302. private void checkColumn(ArrayList<Boolean> arr, int row, int column) {
  303. int bound = column-column%PART;
  304. for(int i=0; i<bound; i++) {
  305. int currValue = base[row][i].value;
  306. if(currValue!=0)
  307. arr.set(currValue-1, true);
  308. }
  309. for(int i=bound+PART; i<SIZE; i++) {
  310. int currValue = base[row][i].value;
  311. if(currValue!=0)
  312. arr.set(currValue-1, true);
  313. }
  314. }
  315.  
  316. private class mutableInt {
  317. private int value;
  318.  
  319. public mutableInt() {
  320. this.value = 0;
  321. }
  322.  
  323. public mutableInt(int value) {
  324. this.value = value;
  325. }
  326.  
  327. public int getValue() {
  328. return value;
  329. }
  330.  
  331. public void setValue(int value) {
  332. this.value = value;
  333. }
  334. }
  335.  
  336. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement