1313#define BOARD_SIZE ((size_t) (SQUARE_SIDE * SQUARE_SIDE))
1414
1515typedef uint16_t Cell ;
16- static_assert (sizeof (Cell ) * 8 >= BOARD_SIZE , "Cell width not big enough!" );
16+ static_assert (sizeof (Cell ) * 8 > BOARD_SIZE , "Cell width not big enough!" );
1717
1818static const Cell UNKNOWN = (1 << BOARD_SIZE ) - 1 ;
1919
20- bool stop (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
21- bool isComplete (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
20+ void copyBoard (const Cell src [/*BOARD_SIZE*/ ][BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
21+ bool changed (const Cell src [/*BOARD_SIZE*/ ][BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
22+ bool isComplete (const Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
2223
2324void column (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t c , Cell * set [/*BOARD_SIZE*/ ]);
2425void row (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t r , Cell * set [/*BOARD_SIZE*/ ]);
2526void block (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t b , Cell * set [/*BOARD_SIZE*/ ]);
2627
27- bool solveByCells (Cell * cells [/*BOARD_SIZE*/ ]);
28- bool solveByPossibilities (Cell * cells [/*BOARD_SIZE*/ ]);
28+ bool solveNaked (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
2929
3030int bitNum (Cell c ) { for (int i = 0 ; ; ++ i ) if (1 << (i - 1 ) >= c ) return i ; }
31- void printBoard (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], bool pretty )
31+ void printBoard (const Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], bool pretty )
3232{
3333 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
3434 if (i > 0 && i % SQUARE_SIDE == 0 ) {
@@ -49,6 +49,8 @@ void printBoard(Cell board[/*BOARD_SIZE*/][BOARD_SIZE], bool pretty)
4949
5050static bool PRINT_DEBUG = false;
5151
52+ static int num_iters = 0 ;
53+
5254int main (int argc , char * argv [])
5355{
5456 const char * board_str ;
@@ -84,12 +86,46 @@ int main(int argc, char* argv[])
8486 }
8587 }
8688
89+ bool valid , complete ;
90+ Cell prev_board [BOARD_SIZE ][BOARD_SIZE ] = { { 0 } };
91+ while ((valid = solveNaked (board )) && !(complete = isComplete (board )) && changed (board , prev_board )) {
92+ for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
93+ for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
94+ Cell accum [BOARD_SIZE ][BOARD_SIZE ] = { { 0 } };
95+ for (Cell c = 1 ; c < UNKNOWN ; c <<= 1 ) {
96+ Cell guess [BOARD_SIZE ][BOARD_SIZE ];
97+ copyBoard (board , guess );
98+ guess [i ][j ] &= c ;
99+ if (guess [i ][j ] == 0 ) continue ;
100+ if (solveNaked (guess )) {
101+ for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
102+ for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
103+ accum [i ][j ] |= guess [i ][j ];
104+ }
105+ }
106+ }
107+ }
108+ if (changed (accum , board )) goto break_outer_l ;
109+ }
110+ }
111+ break_outer_l :;
112+ }
113+
114+ printf ("%s, %s result found! Took %i iterations.\n" ,
115+ valid ? "Valid" : "Invalid" , complete ? "Complete" : "Incomplete" , num_iters );
116+ printBoard (board , complete );
117+ }
118+
119+ bool solveByCells (Cell * cells [/*BOARD_SIZE*/ ]);
120+ bool solveByPossibilities (Cell * cells [/*BOARD_SIZE*/ ]);
121+
122+ bool solveNaked (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ])
123+ {
87124 typedef void (* GroupGetter )(Cell /*board*/ [][BOARD_SIZE ], size_t /*idx*/ , Cell * /*res*/ []);
88125 GroupGetter groupers [] = {column , row , block , NULL };
89126
90- int num_iters = 0 ;
91- bool valid = false;
92- while (!stop (board )) {
127+ Cell prev_board [BOARD_SIZE ][BOARD_SIZE ] = { { 0 } };
128+ while (changed (board , prev_board )) {
93129 ++ num_iters ;
94130 Cell * cells [BOARD_SIZE ];
95131 for (GroupGetter * groupCells = & groupers [0 ]; * groupCells != NULL ; ++ groupCells ) {
@@ -101,60 +137,42 @@ int main(int argc, char* argv[])
101137 printf ("Cells: %s %zd\n" ,
102138 * groupCells == column ? "Col" : * groupCells == row ? "Row" : "Block" , group_i + 1 );
103139 }
104- if (!solveByCells (cells )) goto invalid_soln_l ;
140+ if (!solveByCells (cells )) return false ;
105141
106142 if (PRINT_DEBUG ) {
107143 printBoard (board , false);
108144 printf ("Possibilites: %s %zd\n" ,
109145 * groupCells == column ? "Col" : * groupCells == row ? "Row" : "Block" , group_i + 1 );
110146 }
111- if (!solveByPossibilities (cells )) goto invalid_soln_l ;
147+ if (!solveByPossibilities (cells )) return false ;
112148 }
113149 }
114150 }
115- valid = true;
116- invalid_soln_l :;
117-
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 );
122- }
123-
124- void column (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t c , Cell * set [/*BOARD_SIZE*/ ])
125- {
126- for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) set [i ] = & board [i ][c ];
127- }
128-
129- void row (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t r , Cell * set [/*BOARD_SIZE*/ ])
130- {
131- for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) set [i ] = & board [r ][i ];
151+ return true;
132152}
133153
134- void block ( Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t b , Cell * set [/*BOARD_SIZE*/ ])
154+ void copyBoard ( const Cell src [/*BOARD_SIZE*/ ][BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][ BOARD_SIZE ])
135155{
136- const size_t s = SQUARE_SIDE ;
137- for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) set [i ] = & board [b / s * s + i / s ][b % s * s + i % s ];
156+ changed (src , dest );
138157}
139158
140- int countBits (Cell val );
141-
142- bool stop (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ])
159+ bool changed (const Cell src [/*BOARD_SIZE*/ ][BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ])
143160{
144- static Cell prev_board [BOARD_SIZE ][BOARD_SIZE ] = { { 0 } };
145- bool res = true;
161+ bool res = false;
146162 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
147163 for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
148- if (prev_board [i ][j ] != board [i ][j ]) {
149- res = false ;
150- prev_board [i ][j ] = board [i ][j ];
164+ if (src [i ][j ] != dest [i ][j ]) {
165+ res = true ;
166+ dest [i ][j ] = src [i ][j ];
151167 }
152168 }
153169 }
154170 return res ;
155171}
156172
157- bool isComplete (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ])
173+ int countBits (Cell val );
174+
175+ bool isComplete (const Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ])
158176{
159177 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
160178 for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
@@ -166,6 +184,22 @@ bool isComplete(Cell board[/*BOARD_SIZE*/][BOARD_SIZE])
166184 return true;
167185}
168186
187+ void column (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t c , Cell * set [/*BOARD_SIZE*/ ])
188+ {
189+ for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) set [i ] = & board [i ][c ];
190+ }
191+
192+ void row (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t r , Cell * set [/*BOARD_SIZE*/ ])
193+ {
194+ for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) set [i ] = & board [r ][i ];
195+ }
196+
197+ void block (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t b , Cell * set [/*BOARD_SIZE*/ ])
198+ {
199+ const size_t s = SQUARE_SIDE ;
200+ for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) set [i ] = & board [b / s * s + i / s ][b % s * s + i % s ];
201+ }
202+
169203bool solveByCells (Cell * cells [/*BOARD_SIZE*/ ])
170204{
171205 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
0 commit comments