@@ -18,16 +18,16 @@ static_assert(sizeof(Cell) * 8 >= BOARD_SIZE, "Cell width not big enough!");
1818static const Cell UNKNOWN = (1 << BOARD_SIZE ) - 1 ;
1919
2020bool stop (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
21- bool isValid (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
21+ bool isComplete (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
2222
2323void column (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t c , Cell * set [/*BOARD_SIZE*/ ]);
2424void row (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t r , Cell * set [/*BOARD_SIZE*/ ]);
2525void block (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t b , Cell * set [/*BOARD_SIZE*/ ]);
2626
27- void solveByCells (Cell * cells [/*BOARD_SIZE*/ ]);
28- void solveByPossibilities (Cell * cells [/*BOARD_SIZE*/ ]);
27+ bool solveByCells (Cell * cells [/*BOARD_SIZE*/ ]);
28+ bool solveByPossibilities (Cell * cells [/*BOARD_SIZE*/ ]);
2929
30- int bitNum (Cell c ) { for (int i = 0 ; ; ++ i ) if (( 1 << (i - 1 ) ) >= c ) return i ; }
30+ int bitNum (Cell c ) { for (int i = 0 ; ; ++ i ) if (1 << (i - 1 ) >= c ) return i ; }
3131void printBoard (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], bool pretty )
3232{
3333 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
@@ -84,37 +84,41 @@ int main(int argc, char* argv[])
8484 }
8585 }
8686
87- typedef void (* SetGetter )(Cell /*board*/ [][BOARD_SIZE ], size_t /*idx*/ , Cell * /*res*/ []);
88- SetGetter set_getters [] = {column , row , block , NULL };
87+ typedef void (* GroupGetter )(Cell /*board*/ [][BOARD_SIZE ], size_t /*idx*/ , Cell * /*res*/ []);
88+ GroupGetter groupers [] = {column , row , block , NULL };
8989
9090 int num_iters = 0 ;
91+ bool valid = false;
9192 while (!stop (board )) {
93+ ++ num_iters ;
9294 Cell * cells [BOARD_SIZE ];
93- for (SetGetter * getSet = & set_getters [0 ]; * getSet != NULL ; ++ getSet ) {
94- for (size_t set_i = 0 ; set_i < BOARD_SIZE ; ++ set_i ) {
95- (* getSet )(board , set_i , cells );
95+ for (GroupGetter * groupCells = & groupers [0 ]; * groupCells != NULL ; ++ groupCells ) {
96+ for (size_t group_i = 0 ; group_i < BOARD_SIZE ; ++ group_i ) {
97+ (* groupCells )(board , group_i , cells );
9698
9799 if (PRINT_DEBUG ) {
98100 printBoard (board , false);
99101 printf ("Cells: %s %zd\n" ,
100- * getSet == column ? "Col" : * getSet == row ? "Row" : "Block" , set_i + 1 );
102+ * groupCells == column ? "Col" : * groupCells == row ? "Row" : "Block" , group_i + 1 );
101103 }
102- solveByCells (cells );
104+ if (! solveByCells (cells )) goto invalid_soln_l ;
103105
104106 if (PRINT_DEBUG ) {
105107 printBoard (board , false);
106108 printf ("Possibilites: %s %zd\n" ,
107- * getSet == column ? "Col" : * getSet == row ? "Row" : "Block" , set_i + 1 );
109+ * groupCells == column ? "Col" : * groupCells == row ? "Row" : "Block" , group_i + 1 );
108110 }
109- solveByPossibilities (cells );
111+ if (! solveByPossibilities (cells )) goto invalid_soln_l ;
110112 }
111113 }
112- ++ num_iters ;
113114 }
115+ valid = true;
116+ invalid_soln_l :;
114117
115- const bool valid = isValid (board );
116- printf ("%s result found! Took %i iterations.\n" , valid ? "Valid" : "Invalid" , num_iters );
117- printBoard (board , valid );
118+ const bool complete = isComplete (board );
119+ printf ("%s, %s result found! Took %i iterations.\n" ,
120+ complete ? "Complete" : "Incomplete" , valid ? "valid" : "invalid" , num_iters );
121+ printBoard (board , complete );
118122}
119123
120124void column (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t c , Cell * set [/*BOARD_SIZE*/ ])
@@ -133,15 +137,15 @@ void block(Cell board[/*BOARD_SIZE*/][BOARD_SIZE], size_t b, Cell* set[/*BOARD_S
133137 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) set [i ] = & board [b / s * s + i / s ][b % s * s + i % s ];
134138}
135139
136- int countBits (uint16_t val );
140+ int countBits (Cell val );
137141
138142bool stop (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ])
139143{
140144 static Cell prev_board [BOARD_SIZE ][BOARD_SIZE ] = { { 0 } };
141145 bool res = true;
142146 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
143147 for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
144- if (prev_board [i ][j ] != board [i ][j ] && countBits ( board [ i ][ j ]) != 1 ) {
148+ if (prev_board [i ][j ] != board [i ][j ]) {
145149 res = false;
146150 prev_board [i ][j ] = board [i ][j ];
147151 }
@@ -150,7 +154,7 @@ bool stop(Cell board[/*BOARD_SIZE*/][BOARD_SIZE])
150154 return res ;
151155}
152156
153- bool isValid (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ])
157+ bool isComplete (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ])
154158{
155159 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
156160 for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
@@ -162,70 +166,80 @@ bool isValid(Cell board[/*BOARD_SIZE*/][BOARD_SIZE])
162166 return true;
163167}
164168
165- void solveByCells (Cell * cells [/*BOARD_SIZE*/ ])
169+ bool solveByCells (Cell * cells [/*BOARD_SIZE*/ ])
166170{
167171 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
168- bool subsets [ BOARD_SIZE ] = { false } ;
172+ Cell mask = 0 ;
169173 int num_subsets = 0 ;
170174
171- const uint16_t vals = * cells [i ];
175+ const Cell vals = * cells [i ];
172176 for (size_t j = i ; j < BOARD_SIZE ; ++ j ) {
173177 if ((* cells [j ] | vals ) == vals ) {
174- subsets [ j ] = true ;
178+ mask |= 1 << j ;
175179 ++ num_subsets ;
176180 }
177181 }
178182
179- if (countBits (vals ) == num_subsets ) {
183+ const int num_vals = countBits (vals );
184+ if (num_vals == num_subsets ) {
180185 bool changed = false;
181186 for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
182187 const Cell old = * cells [j ];
183- * cells [j ] &= subsets [ j ] ? vals : ~vals & UNKNOWN ;
188+ * cells [j ] &= (( 1 << j ) & mask ) ? vals : ~vals & UNKNOWN ;
184189 if (* cells [j ] != old ) changed = true;
185190 }
186- if (PRINT_DEBUG && changed ) printf ("Set of %i cells fulfilling %i.\n" , num_subsets , vals );
191+ if (PRINT_DEBUG && changed ) printf ("Set %i of cells fulfilling %i.\n" , mask , vals );
192+ } else if (num_vals < num_subsets ) {
193+ if (PRINT_DEBUG ) printf ("Set %i of cells overfulfill %i!\n" , mask , vals );
194+ return false;
187195 }
188196 }
197+ return true;
189198}
190199
191- uint16_t transposeBits (Cell * const cells [], size_t bit_i );
200+ Cell transposeBits (Cell * const cells [/*BOARD_SIZE*/ ], size_t bit_i );
192201
193- void solveByPossibilities (Cell * cells [/*BOARD_SIZE*/ ])
202+ bool solveByPossibilities (Cell * cells [/*BOARD_SIZE*/ ])
194203{
195204 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
196- uint16_t mask = 0 ;
205+ Cell mask = 0 ;
197206 int num_subsets = 0 ;
198207
199- const uint16_t vals = transposeBits (cells , i );
208+ const Cell vals = transposeBits (cells , i );
200209 for (size_t j = i ; j < BOARD_SIZE ; ++ j ) {
201210 if ((transposeBits (cells , j ) | vals ) == vals ) {
202211 mask |= 1 << j ;
203212 ++ num_subsets ;
204213 }
205214 }
206215
207- if (countBits (vals ) == num_subsets ) {
216+ const int num_vals = countBits (vals );
217+ if (num_vals == num_subsets ) {
208218 bool changed = false;
209219 for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
210220 const Cell old = * cells [j ];
211221 * cells [j ] &= ((1 << j ) & vals ) ? mask : ~mask & UNKNOWN ;
212222 if (* cells [j ] != old ) changed = true;
213223 }
214- if (PRINT_DEBUG && changed ) printf ("Set of %i possibilities fulfilled by %i.\n" , num_subsets , mask );
224+ if (PRINT_DEBUG && changed ) printf ("Set %i of possibilities fulfilled by %i.\n" , vals , mask );
225+ } else if (num_vals < num_subsets ) {
226+ if (PRINT_DEBUG ) printf ("Set %i of possibilities cannot be fulfilled by %i!\n" , vals , mask );
227+ return false;
215228 }
216229 }
230+ return true;
217231}
218232
219- int countBits (uint16_t val )
233+ int countBits (Cell val )
220234{
221235 int res = 0 ;
222236 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) if (val & (1 << i )) ++ res ;
223237 return res ;
224238}
225239
226- uint16_t transposeBits (Cell * const cells [], size_t bit_i )
240+ Cell transposeBits (Cell * const cells [/*BOARD_SIZE*/ ], size_t bit_i )
227241{
228- uint16_t res = 0 ;
242+ Cell res = 0 ;
229243 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) if (* cells [i ] & (1 << bit_i )) res |= 1 << i ;
230244 return res ;
231245}
0 commit comments