11package com .company ;
22
3- class solver implements Runnable {
4- //Choose a box with minimum empty values - MVP(minimum value remaining) heuristic
5- //Reduce the domain of each box by prechecking the already fixed value in the box
3+ import java . awt .*;
4+ import java . util .*;
5+ import java . util . List ;
66
7- public void run (){
8- if (getResult ())
7+ class solver implements Runnable { //Implemented as a Thread to avoid freezing and maximum efficiency for GUI with heavy operation
8+ //Chooses a box with MINIMUM VALUES REMAINING (It acts as a heuristic which optimizes the search for the solution
9+ ArrayList <Point > sortedPoints = new ArrayList <>(); //It stores the sorted points according
10+ // to box with least number of values unfilled
11+ public void run (){ //acts as a constructor for the class, works with Thread.start function
12+ setSortedPoints (); //sets sorted point
13+ if (getResult ()) //calls the solving function
914 Main .gui .sud .printArray ();
1015
1116 }
17+ /*
18+ This function creates a map for all the 9 boxes
19+ Sorts them, and creates a new arraylist of points which are sorted according to the boxes
20+ */
21+ private void setSortedPoints (){
22+ HashMap <String ,Integer > box_size = new HashMap <>(); //creates a map with default frequency one
23+ box_size .put ("00" ,0 );
24+ box_size .put ("03" ,0 );
25+ box_size .put ("06" ,0 );
26+
27+ box_size .put ("30" ,0 );
28+ box_size .put ("33" ,0 );
29+ box_size .put ("36" ,0 );
30+
31+ box_size .put ("60" ,0 );
32+ box_size .put ("63" ,0 );
33+ box_size .put ("66" ,0 );
34+ /*
35+ Below loop, calculates the size of each of unfilled elements in each box
36+ */
37+ for (int i =0 ; i <Main .points .size (); i ++) {
38+ String s = Integer .toString (boxRowCol ((int )Main .points .get (i ).getX ()));
39+ s +=Integer .toString (+boxRowCol ((int )Main .points .get (i ).getY ()));
40+ //System.out.println(s);
41+
42+ switch (s ) {
43+ case "00" :box_size .put ("00" ,box_size .get ("00" )+1 ); break ;
44+ case "03" :box_size .put ("03" ,box_size .get ("03" )+1 );break ;
45+ case "06" :box_size .put ("06" ,box_size .get ("06" )+1 );break ;
46+
47+ case "30" :box_size .put ("30" ,box_size .get ("30" )+1 );break ;
48+ case "33" :box_size .put ("33" ,box_size .get ("33" )+1 );break ;
49+ case "36" :box_size .put ("36" ,box_size .get ("36" )+1 );break ;
50+
51+ case "60" :box_size .put ("60" ,box_size .get ("60" )+1 );break ;
52+ case "63" :box_size .put ("63" ,box_size .get ("63" )+1 );break ;
53+ case "66" :box_size .put ("66" ,box_size .get ("66" )+1 );break ;
54+ }
55+ }
56+
57+ box_size = sortByValue (box_size ); //This function sorts the hash map by value
58+
59+ /*
60+ Below loop sets the sortedpoints arraylist
61+ */
62+ for (String key :box_size .keySet ())
63+ for (int i =0 ; i <Main .points .size (); i ++) {
64+ String s = Integer .toString (boxRowCol ((int ) Main .points .get (i ).getX ()));
65+ s += Integer .toString (+boxRowCol ((int ) Main .points .get (i ).getY ()));
66+ if (s .equals (key )){
67+ sortedPoints .add (new Point ((int )Main .points .get (i ).getX (),(int )Main .points .get (i ).getY ()));
68+ }
69+
70+ }
71+ }
72+ /*
73+ This function is soleley used for sorting the MAP by using list and default collections fucntions
74+ */
75+ private static HashMap <String , Integer > sortByValue (HashMap <String , Integer > map_sorting )
76+ {
77+ // Create a list from elements of HashMap
78+ List <Map .Entry <String , Integer > > list =
79+ new LinkedList <>(map_sorting .entrySet ());
80+
81+
82+ list .sort (Comparator .comparing (Map .Entry ::getValue ));
83+
84+
85+ HashMap <String , Integer > temp = new LinkedHashMap <>();
86+ for (Map .Entry <String , Integer > aa : list ) {
87+ temp .put (aa .getKey (), aa .getValue ());
88+ }
89+ return temp ;
90+ }
91+ /*
92+ This is the MAIN function which solves the sudoku by using sortedpoints arraylist and constraints
93+ */
1294 private boolean getResult (){
1395 if (checkSolved ()) {
1496 return true ;
1597 }
16- int row_num = -1 ;
17- int col_num = -1 ;
18- for (int i =0 ; i <9 ; i ++)
19- for (int j =0 ; j <9 ; j ++){
20- if (Main .sudoku_array [i ][j ] == 0 ){
21- row_num =i ;
22- col_num =j ;
23- }
98+ int row_num = -1 ,col_num = -1 ;
99+ /*
100+ sets col, row to get started
101+ */
102+ for (Point pointIndex : sortedPoints ) {
103+ if (Main .sudoku_array [(int ) pointIndex .getX ()][(int ) pointIndex .getY ()] == 0 ) {
104+ row_num = (int ) pointIndex .getX ();
105+ col_num = (int ) pointIndex .getY ();
106+ break ;
24107 }
108+ }
25109
110+ /*
111+ it check for constraint and refreshes GUI after every move
112+ */
26113 for (int i =1 ; i <=9 ; i ++){
27114 if (checkConstraint (i ,row_num ,col_num )){
28115
@@ -47,21 +134,30 @@ private boolean getResult(){
47134 return false ;
48135
49136 }
137+ /*
138+ adds delay
139+ */
50140 private void timer (){
51141 try {
52- Thread .sleep (1 );
142+ Thread .sleep (5 ); //CHANGE DELAY TIME HERE , SET minimum 5ms for noticable difference and faster result
53143 //Thread.sleep(10000);
54144 } catch (InterruptedException e ) {
55145 e .printStackTrace ();
56146 }
57147 }
148+ /*
149+ It checks weather the sudoku has been solved or not
150+ */
58151 private boolean checkSolved (){
59152 for (int i = 0 ; i < 9 ; i ++)
60153 for (int j = 0 ; j < 9 ; j ++)
61154 if (Main .sudoku_array [i ][j ] == 0 )
62155 return false ;
63156 return true ;
64157 }
158+ /*
159+ it checks constraint on rows, cols and boxes
160+ */
65161 private boolean checkConstraint (int value , int row_num ,int col_num ){
66162 /*
67163 Below for loop checks for the given value in row and col specified
@@ -84,6 +180,9 @@ private boolean checkConstraint(int value, int row_num,int col_num){
84180 //if every constraint is satisfied
85181 return true ;
86182 }
183+ /*
184+ Returns box number
185+ */
87186 private int boxRowCol (int num ){
88187 if (num ==0 ||num ==1 ||num ==2 )
89188 return 0 ;
0 commit comments