Whoops, this file didn't get comments
This commit is contained in:
parent
7e84d09250
commit
049fa3405a
@ -32,7 +32,7 @@ void puzzle_undo_propagate_constraints(
|
||||
);
|
||||
|
||||
// Return true if cell is bound to something other than '.'.
|
||||
bool puzzle_is_complete(puzzle_t* puzzle, uint8_t cell);
|
||||
bool puzzle_cell_is_complete(puzzle_t* puzzle, uint8_t cell);
|
||||
|
||||
// Bind cell to some value, including '.'
|
||||
void puzzle_set_cell(puzzle_t* puzzle, uint8_t cell, tile_t tile);
|
||||
@ -75,11 +75,12 @@ void puzzle_solve(puzzle_t* puzzle) {
|
||||
|
||||
bool puzzle_solve1(puzzle_t* puzzle) {
|
||||
// find best cell to start from
|
||||
// (which is the cell with the fewest options)
|
||||
uint8_t best_cell_noptions = 255;
|
||||
uint8_t best_cell = 255;
|
||||
|
||||
for (uint8_t cell = 0; cell < N_CELLS; cell++) {
|
||||
if (puzzle_is_complete(puzzle, cell)) {
|
||||
if (puzzle_cell_is_complete(puzzle, cell)) {
|
||||
continue;
|
||||
}
|
||||
puzzle_options_t *options = &puzzle->options[cell];
|
||||
@ -91,10 +92,13 @@ bool puzzle_solve1(puzzle_t* puzzle) {
|
||||
}
|
||||
|
||||
if (best_cell == 255) {
|
||||
return true; // solved!
|
||||
// no valid starting cell: continue!
|
||||
return true;
|
||||
}
|
||||
|
||||
{
|
||||
// try every option that's still available (those from 1-9) that appear
|
||||
// in the options set that we have
|
||||
uint8_t cell = best_cell;
|
||||
puzzle_options_t *options = &puzzle->options[cell];
|
||||
for (char digit = '1'; digit <= (char) '9'; digit++) {
|
||||
@ -107,6 +111,9 @@ bool puzzle_solve1(puzzle_t* puzzle) {
|
||||
puzzle_propagate_constraints(puzzle, cell, tile, &result);
|
||||
|
||||
if (result.viable) {
|
||||
// puzzle_propagate_constraints may have created a situation
|
||||
// where there is no need to even try the next branch, as it is
|
||||
// known to be unsolvable
|
||||
puzzle_set_cell(puzzle, cell, tile);
|
||||
if (puzzle_solve1(puzzle)) {
|
||||
return true;
|
||||
@ -116,6 +123,7 @@ bool puzzle_solve1(puzzle_t* puzzle) {
|
||||
puzzle_undo_propagate_constraints(puzzle, tile, &result);
|
||||
}
|
||||
|
||||
// we didn't explicitly clear this earlier, so clear this here
|
||||
puzzle_set_cell(puzzle, cell, tile_new('.'));
|
||||
}
|
||||
|
||||
@ -127,13 +135,18 @@ void puzzle_check_solution(puzzle_t* puzzle) {
|
||||
tile_t original = puzzle->input_board[cell];
|
||||
tile_t solved = puzzle->solved_board[cell];
|
||||
|
||||
// every cell must be populated
|
||||
if (solved.value == '.') {
|
||||
crash("invalid solution (empty cell)");
|
||||
}
|
||||
|
||||
// new cells must have the same value as the old cell in their position
|
||||
if (original.value != '.' && original.value != solved.value) {
|
||||
crash("invalid solution (changed original cell)");
|
||||
}
|
||||
|
||||
// there must be no cases where the interference graph sees
|
||||
// two neighbors with the same tile value
|
||||
cellset_t *interference_row = &interference.rows[cell];
|
||||
for (uint8_t other_i = 0; other_i < interference_row->count; other_i++) {
|
||||
uint8_t other = interference_row->cells[other_i];
|
||||
@ -153,10 +166,13 @@ void puzzle_propagate_constraints(
|
||||
cellset_init(&result->cells);
|
||||
result->viable = true;
|
||||
|
||||
// find every row that cell interferes with
|
||||
// for every incomplete cell in that row, remove this tile value
|
||||
// from the options
|
||||
cellset_t *interference_row = &interference.rows[cell];
|
||||
for (uint8_t other_i = 0; other_i < interference_row->count; other_i++) {
|
||||
uint8_t other = interference_row->cells[other_i];
|
||||
if (puzzle_is_complete(puzzle, other)) {
|
||||
if (puzzle_cell_is_complete(puzzle, other)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -164,6 +180,7 @@ void puzzle_propagate_constraints(
|
||||
if (puzzle_options_remove(options, tile)) {
|
||||
cellset_add(&result->cells, other);
|
||||
|
||||
// if there is no possible value for a cell, then we picked wrong
|
||||
if (puzzle_options_is_empty(options)) {
|
||||
result->viable = false;
|
||||
break;
|
||||
@ -177,6 +194,7 @@ void puzzle_undo_propagate_constraints(
|
||||
tile_t tile,
|
||||
puzzle_propagate_result_t* result
|
||||
) {
|
||||
// we recorded every cell that was touched, so untouch those cells
|
||||
cellset_t *cells = &result->cells;
|
||||
for (uint8_t cell_i = 0; cell_i < cells->count; cell_i++) {
|
||||
uint8_t cell = cells->cells[cell_i];
|
||||
@ -184,7 +202,7 @@ void puzzle_undo_propagate_constraints(
|
||||
}
|
||||
}
|
||||
|
||||
bool puzzle_is_complete(puzzle_t* puzzle, uint8_t cell) {
|
||||
bool puzzle_cell_is_complete(puzzle_t* puzzle, uint8_t cell) {
|
||||
return puzzle->solved_board[cell].value != '.';
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user