Advertisement
Guest User

Untitled

a guest
Apr 20th, 2018
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.56 KB | None | 0 0
  1. import jdk.internal.util.xml.impl.Pair;
  2.  
  3. import javax.swing.*;
  4. import java.util.*;
  5. import java.util.function.Consumer;
  6.  
  7. import static java.lang.Integer.highestOneBit;
  8. import static java.lang.Integer.min;
  9. import static java.util.Collections.sort;
  10.  
  11. /*
  12. * Encapsulates a Sudoku grid to be solved.
  13. * CS108 Stanford.
  14. */
  15. public class Sudoku {
  16. // Provided grid data for main/testing
  17. // The instance variable strategy is up to you.
  18.  
  19. // Provided easy 1 6 grid
  20. // (can paste this text into the GUI too)
  21. public static final int[][] easyGrid = Sudoku.stringsToGrid(
  22. "1 6 4 0 0 0 0 0 2",
  23. "2 0 0 4 0 3 9 1 0",
  24. "0 0 5 0 8 0 4 0 7",
  25. "0 9 0 0 0 6 5 0 0",
  26. "5 0 0 1 0 2 0 0 8",
  27. "0 0 8 9 0 0 0 3 0",
  28. "8 0 9 0 4 0 2 0 0",
  29. "0 7 3 5 0 9 0 0 1",
  30. "4 0 0 0 0 0 6 7 9");
  31.  
  32.  
  33. // Provided medium 5 3 grid
  34. public static final int[][] mediumGrid = Sudoku.stringsToGrid(
  35. "530070000",
  36. "600195000",
  37. "098000060",
  38. "800060003",
  39. "400803001",
  40. "700020006",
  41. "060000280",
  42. "000419005",
  43. "000080079");
  44.  
  45. // Provided hard 3 7 grid
  46. // 1 solution this way, 6 solutions if the 7 is changed to 0
  47. public static final int[][] hardGrid = Sudoku.stringsToGrid(
  48. "3 7 0 0 0 0 0 8 0",
  49. "0 0 1 0 9 3 0 0 0",
  50. "0 4 0 7 8 0 0 0 3",
  51. "0 9 3 8 0 0 0 1 2",
  52. "0 0 0 0 4 0 0 0 0",
  53. "5 2 0 0 0 6 7 9 0",
  54. "6 0 0 0 2 1 0 4 0",
  55. "0 0 0 5 3 0 9 0 0",
  56. "0 3 0 0 0 0 0 5 1");
  57.  
  58.  
  59. public static final int SIZE = 9; // size of the whole 9x9 puzzle
  60. public static final int PART = 3; // size of each 3x3 part
  61. public static final int MAX_SOLUTIONS = 100;
  62.  
  63. // Provided various static utility methods to
  64. // convert data formats to int[][] grid.
  65.  
  66. /**
  67. * Returns a 2-d grid parsed from strings, one string per row.
  68. * The "..." is a Java 5 feature that essentially
  69. * makes "rows" a String[] array.
  70. * (provided utility)
  71. *
  72. * @param rows array of row strings
  73. * @return grid
  74. */
  75. public static int[][] stringsToGrid(String... rows) {
  76. int[][] result = new int[rows.length][];
  77. for (int row = 0; row < rows.length; row++) {
  78. result[row] = stringToInts(rows[row]);
  79. }
  80. return result;
  81. }
  82.  
  83.  
  84. /**
  85. * Given a single string containing 81 numbers, returns a 9x9 grid.
  86. * Skips all the non-numbers in the text.
  87. * (provided utility)
  88. *
  89. * @param text string of 81 numbers
  90. * @return grid
  91. */
  92. public static int[][] textToGrid(String text) {
  93. int[] nums = stringToInts(text);
  94. if (nums.length != SIZE * SIZE) {
  95. throw new RuntimeException("Needed 81 numbers, but got:" + nums.length);
  96. }
  97.  
  98. int[][] result = new int[SIZE][SIZE];
  99. int count = 0;
  100. for (int row = 0; row < SIZE; row++) {
  101. for (int col = 0; col < SIZE; col++) {
  102. result[row][col] = nums[count];
  103. count++;
  104. }
  105. }
  106. return result;
  107. }
  108.  
  109.  
  110. /**
  111. * Given a string containing digits, like "1 23 4",
  112. * returns an int[] of those digits {1 2 3 4}.
  113. * (provided utility)
  114. *
  115. * @param string string containing ints
  116. * @return array of ints
  117. */
  118. public static int[] stringToInts(String string) {
  119. int[] a = new int[string.length()];
  120. int found = 0;
  121. for (int i = 0; i < string.length(); i++) {
  122. if (Character.isDigit(string.charAt(i))) {
  123. a[found] = Integer.parseInt(string.substring(i, i + 1));
  124. found++;
  125. }
  126. }
  127. int[] result = new int[found];
  128. System.arraycopy(a, 0, result, 0, found);
  129. return result;
  130. }
  131.  
  132.  
  133. // Provided -- the deliverable main().
  134. // You can edit to do easier cases, but turn in
  135. // solving hardGrid.
  136. public static void main(String[] args) {
  137. Sudoku sudoku;
  138. sudoku = new Sudoku(hardGrid);
  139. System.out.println(sudoku); // print the raw problem
  140. int count = sudoku.solve();
  141.  
  142. System.out.println("solutions:" + count);
  143. System.out.println("elapsed:" + sudoku.getElapsed() + "ms");
  144. System.out.println(sudoku.getSolutionText());
  145. }
  146.  
  147.  
  148. /**
  149. * Instance variables
  150. */
  151.  
  152. private int[] maskInRows;
  153. private int[] maskInCols;
  154. private int[] maskInSmlSqueares;
  155. private int[][] grid;
  156. private ArrayList<Spot> spots;
  157. private long timeSpentOnSolving;
  158. private String solutionText;
  159.  
  160.  
  161. /**
  162. * Sets up based on the given ints.
  163. */
  164. public Sudoku(int[][] ints) {
  165. solutionText = "";
  166. timeSpentOnSolving = 0;
  167.  
  168. spots = new ArrayList<>();
  169. maskInCols = new int[SIZE];
  170. maskInRows = new int[SIZE];
  171. maskInSmlSqueares = new int[SIZE];
  172. grid = new int[SIZE][SIZE];
  173.  
  174.  
  175. for (int i = 0; i < SIZE; i++) {
  176. for (int j = 0; j < SIZE; j++) {
  177. Spot curSpot = new Spot(i, j);
  178. curSpot.set(ints[i][j]);
  179. if (curSpot.getValue() == 0)
  180. spots.add(curSpot);
  181. grid[i][j] = ints[i][j];
  182. }
  183. }
  184.  
  185. sort(spots);
  186. }
  187.  
  188. /**
  189. * @param st
  190. */
  191. public Sudoku(String st) {
  192. this(textToGrid(st));
  193. }
  194.  
  195. /**
  196. *
  197. */
  198. private void fillSolutionText() {
  199. int[][] ans = new int[SIZE][SIZE];
  200.  
  201. for (int i = 0; i < SIZE; i++) {
  202. for (int j = 0; j < SIZE; j++) {
  203. ans[i][j] = grid[i][j];
  204. }
  205. }
  206.  
  207. for (Spot item : spots) {
  208. ans[item.getRow()][item.getColumn()] = item.getValue();
  209. }
  210. solutionText = gridToText(ans);
  211. }
  212.  
  213. /**
  214. * @param ind
  215. * @return
  216. */
  217. private int getAns(int ind) {
  218. if (ind >= spots.size()) {
  219. if (solutionText.length() == 0) {
  220. fillSolutionText();
  221. }
  222. return 1;
  223. }
  224. int ans = 0;
  225. Spot curSpot = spots.get(ind);
  226. for (int canPut : curSpot) {
  227. curSpot.set(canPut);
  228. ans = ans + getAns(ind + 1);
  229. curSpot.set(0);
  230. if (ans >= MAX_SOLUTIONS) return MAX_SOLUTIONS;
  231. }
  232. return ans;
  233. }
  234.  
  235. /**
  236. *
  237. * @param gr
  238. * @return
  239. */
  240. private String gridToText(int[][] gr) {
  241. StringBuilder res = new StringBuilder();
  242. for (int i = 0; i < SIZE; i++) {
  243. for (int j = 0; j < SIZE; j++) {
  244. res.append(gr[i][j] + (j < SIZE - 1 ? " " : "\n"));
  245. }
  246. }
  247. return res.toString();
  248. }
  249.  
  250. /**
  251. * Solves the puzzle, invoking the underlying recursive search.
  252. */
  253. public int solve() {
  254. long beforeRecursion = System.currentTimeMillis();
  255. int counter = getAns(0);
  256. long afterRecursion = System.currentTimeMillis();
  257. timeSpentOnSolving = afterRecursion - beforeRecursion;
  258. return counter;
  259. }
  260.  
  261. public String getSolutionText() {
  262. return solutionText;
  263. }
  264.  
  265. public long getElapsed() {
  266. return timeSpentOnSolving;
  267. }
  268.  
  269. /**
  270. * @return
  271. */
  272. @Override
  273. public String toString() {
  274. return gridToText(grid);
  275. }
  276.  
  277. /**
  278. * This is private Spot class, which is responsible on
  279. * Every 81 board cell
  280. * I't has his tests in SpotTest, but it must be modified
  281. * As public static
  282. */
  283. private class Spot implements Iterable<Integer>, Comparable {
  284. private int x;
  285. private int y;
  286. private int value;
  287.  
  288. public static final int markAll = 0x3FE;
  289.  
  290. /**
  291. * @param x
  292. * @param y
  293. */
  294. public Spot(int x, int y) {
  295. this.x = x;
  296. this.y = y;
  297. }
  298.  
  299. /**
  300. * @return
  301. */
  302.  
  303. public int getRow() {
  304. return x;
  305. }
  306.  
  307. /**
  308. * @return
  309. */
  310.  
  311. public int getColumn() {
  312. return y;
  313. }
  314.  
  315. /**
  316. * @return
  317. */
  318.  
  319. public int getSmallSquare() {
  320. int smallRow = getRow() / Sudoku.PART;
  321. int smallColl = getColumn() / Sudoku.PART;
  322. return smallRow * Sudoku.PART + smallColl;
  323. }
  324.  
  325. /**
  326. * @param value
  327. */
  328. private void fillMasks(int value) {
  329. maskInRows[getRow()] ^= (1 << value);
  330. maskInCols[getColumn()] ^= (1 << value);
  331. maskInSmlSqueares[getSmallSquare()] ^= (1 << value);
  332.  
  333. }
  334.  
  335. /**
  336. * @param value
  337. */
  338. public void set(int value) {
  339. if (this.value > 0)
  340. fillMasks(this.value);
  341. this.value = value;
  342. if (this.value > 0)
  343. fillMasks(this.value);
  344. }
  345.  
  346. /**
  347. * @return
  348. */
  349. public int getValue() {
  350. return value;
  351. }
  352.  
  353. /**
  354. * @return
  355. */
  356. public int getMarked() {
  357. int ans = maskInRows[getRow()] | maskInCols[getColumn()] | maskInSmlSqueares[getSmallSquare()];
  358. return ans;
  359. }
  360.  
  361. /**
  362. * @return
  363. */
  364. @Override
  365. public Iterator iterator() {
  366. Iterator it = new Iterator() {
  367. private Integer mask = getMarked() ^ markAll;
  368.  
  369. @Override
  370. public boolean hasNext() {
  371. return Integer.bitCount(mask) > 0;
  372. }
  373.  
  374. @Override
  375. public Object next() {
  376. Integer ans = 0;
  377. ans = Integer.numberOfTrailingZeros(mask);
  378. int prevMask = mask;
  379. mask = mask ^ (1 << ans);
  380. return ans;
  381. }
  382. };
  383. return it;
  384. }
  385.  
  386. /**
  387. * @param o
  388. * @return
  389. */
  390. @Override
  391. public int compareTo(Object o) {
  392. int othr = ((Spot) o).getMarked();
  393. int mine = this.getMarked();
  394.  
  395. if (Integer.bitCount(mine) < Integer.bitCount(othr)) return 1;
  396. if (Integer.bitCount(mine) > Integer.bitCount(othr)) return -1;
  397. return 0;
  398. }
  399. }
  400.  
  401. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement