@@ -17,15 +17,14 @@ static_assert(sizeof(Cell) * 8 > BOARD_SIZE, "Cell width not big enough!");
1717
1818static const Cell UNKNOWN = (1 << BOARD_SIZE ) - 1 ;
1919
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 ]);
2220bool isComplete (const Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
21+ bool isDifferent (const Cell lhs [/*BOARD_SIZE*/ ][BOARD_SIZE ], const Cell rhs [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
22+ bool isChanged (const Cell src [/*BOARD_SIZE*/ ][BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
23+ void copyBoard (const Cell src [/*BOARD_SIZE*/ ][BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
24+ void accumulate (const Cell src [/*BOARD_SIZE*/ ][BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
2325
24- void column (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t c , Cell * set [/*BOARD_SIZE*/ ]);
25- void row (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t r , Cell * set [/*BOARD_SIZE*/ ]);
26- void block (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t b , Cell * set [/*BOARD_SIZE*/ ]);
27-
28- bool solveNaked (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
26+ typedef struct LinkedCell { struct LinkedCell * prev ; size_t row ; size_t col ; } LinkedCell ;
27+ bool solveAtDepth (int depth , LinkedCell * prev , Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
2928
3029int bitNum (Cell c ) { for (int i = 0 ; ; ++ i ) if (1 << (i - 1 ) >= c ) return i ; }
3130void printBoard (const Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], bool pretty )
@@ -86,36 +85,80 @@ int main(int argc, char* argv[])
8685 }
8786 }
8887
89- bool valid , complete ;
9088 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- }
89+ bool valid = false, complete = false;
90+ int max_depth = 0 ;
91+ while (isChanged (board , prev_board )) {
92+ for (int depth = 0 ; depth <= BOARD_SIZE * BOARD_SIZE ; ++ depth ) {
93+ if (depth > max_depth ) max_depth = depth ;
94+ /*if (PRINT_DEBUG)*/ printf ("Solving @ depth %i.\n" , depth );
95+
96+ valid = solveAtDepth (depth , NULL , board );
97+ if (!valid || isDifferent (board , prev_board )) break ;
11098 }
111- break_outer_l :;
99+ complete = isComplete (board );
100+ if (!valid || complete ) break ;
112101 }
113102
114- printf ("%s, %s result found! Took %i iterations.\n" ,
115- valid ? "Valid" : "Invalid" , complete ? "Complete" : "Incomplete" , num_iters );
103+ printf ("%s, %s result found! Took %i iterations, max search depth %i .\n" ,
104+ valid ? "Valid" : "Invalid" , complete ? "Complete" : "Incomplete" , num_iters , max_depth );
116105 printBoard (board , complete );
117106}
118107
108+ int countBits (Cell val );
109+
110+ bool guessPossibilities (LinkedCell * guessable , Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ],
111+ Cell accum [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
112+
113+
114+ bool solveAtDepth (int depth , LinkedCell * prev , Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ])
115+ {
116+ if (depth == 0 ) {
117+ Cell accum [BOARD_SIZE ][BOARD_SIZE ] = { { 0 } };
118+ if (!guessPossibilities (prev , board , accum )) return false;
119+ if (/*PRINT_DEBUG && */ isChanged (accum , board )) printf ("Made progress!\n" );
120+ return true;
121+ }
122+ const bool has_prev = prev != NULL ;
123+ for (size_t i = has_prev ? prev -> row : 0 ; i < BOARD_SIZE ; ++ i ) {
124+ for (size_t j = has_prev ? prev -> col : 0 ; j < BOARD_SIZE ; ++ j ) {
125+ if (has_prev && i == prev -> row && j == prev -> col ) continue ;
126+ if (countBits (board [i ][j ] <= 1 )) continue ;
127+ LinkedCell cell = { .prev = prev , .row = i , .col = j };
128+ if (!solveAtDepth (depth - 1 , & cell , board )) return false;
129+ }
130+ }
131+ return true;
132+ }
133+
134+ bool solveNaked (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ]);
135+
136+ bool guessPossibilities (LinkedCell * guessable , Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ],
137+ Cell accum [/*BOARD_SIZE*/ ][BOARD_SIZE ])
138+ {
139+ if (guessable == NULL ) {
140+ Cell guess [BOARD_SIZE ][BOARD_SIZE ];
141+ copyBoard (board , guess );
142+ bool valid = solveNaked (guess );
143+ if (valid ) accumulate (guess , accum );
144+ return valid ;
145+ }
146+ bool any_valid = false;
147+ Cell * cell = & board [guessable -> row ][guessable -> col ];
148+ const Cell orig = * cell ;
149+ for (Cell c = 1 ; c <= UNKNOWN ; c <<= 1 ) {
150+ if (!(c & orig )) continue ;
151+ * cell = c ;
152+ if (guessPossibilities (guessable -> prev , board , accum )) any_valid = true;
153+ }
154+ * cell = orig ;
155+ return any_valid ;
156+ }
157+
158+ void column (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t c , Cell * set [/*BOARD_SIZE*/ ]);
159+ void row (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t r , Cell * set [/*BOARD_SIZE*/ ]);
160+ void block (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t b , Cell * set [/*BOARD_SIZE*/ ]);
161+
119162bool solveByCells (Cell * cells [/*BOARD_SIZE*/ ]);
120163bool solveByPossibilities (Cell * cells [/*BOARD_SIZE*/ ]);
121164
@@ -125,7 +168,7 @@ bool solveNaked(Cell board[/*BOARD_SIZE*/][BOARD_SIZE])
125168 GroupGetter groupers [] = {column , row , block , NULL };
126169
127170 Cell prev_board [BOARD_SIZE ][BOARD_SIZE ] = { { 0 } };
128- while (changed (board , prev_board )) {
171+ while (isChanged (board , prev_board )) {
129172 ++ num_iters ;
130173 Cell * cells [BOARD_SIZE ];
131174 for (GroupGetter * groupCells = & groupers [0 ]; * groupCells != NULL ; ++ groupCells ) {
@@ -151,12 +194,29 @@ bool solveNaked(Cell board[/*BOARD_SIZE*/][BOARD_SIZE])
151194 return true;
152195}
153196
154- void copyBoard (const Cell src [ /*BOARD_SIZE*/ ][ BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ])
197+ bool isComplete (const Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ])
155198{
156- changed (src , dest );
199+ for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
200+ for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
201+ if (countBits (board [i ][j ]) != 1 ) {
202+ return false;
203+ }
204+ }
205+ }
206+ return true;
157207}
158208
159- bool changed (const Cell src [/*BOARD_SIZE*/ ][BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ])
209+ bool isDifferent (const Cell lhs [/*BOARD_SIZE*/ ][BOARD_SIZE ], const Cell rhs [/*BOARD_SIZE*/ ][BOARD_SIZE ])
210+ {
211+ for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
212+ for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
213+ if (lhs [i ][j ] != rhs [i ][j ]) return true;
214+ }
215+ }
216+ return false;
217+ }
218+
219+ bool isChanged (const Cell src [/*BOARD_SIZE*/ ][BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ])
160220{
161221 bool res = false;
162222 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
@@ -170,18 +230,18 @@ bool changed(const Cell src[/*BOARD_SIZE*/][BOARD_SIZE], Cell dest[/*BOARD_SIZE*
170230 return res ;
171231}
172232
173- int countBits (Cell val );
233+ void copyBoard (const Cell src [/*BOARD_SIZE*/ ][BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ])
234+ {
235+ isChanged (src , dest );
236+ }
174237
175- bool isComplete (const Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ])
238+ void accumulate (const Cell src [ /*BOARD_SIZE*/ ][ BOARD_SIZE ], Cell dest [/*BOARD_SIZE*/ ][BOARD_SIZE ])
176239{
177240 for (size_t i = 0 ; i < BOARD_SIZE ; ++ i ) {
178241 for (size_t j = 0 ; j < BOARD_SIZE ; ++ j ) {
179- if (countBits (board [i ][j ]) != 1 ) {
180- return false;
181- }
242+ dest [i ][j ] |= src [i ][j ];
182243 }
183244 }
184- return true;
185245}
186246
187247void column (Cell board [/*BOARD_SIZE*/ ][BOARD_SIZE ], size_t c , Cell * set [/*BOARD_SIZE*/ ])
0 commit comments