static puzzle_t *search(puzzle_t *puz) { if (!propogate(puz)) { return NULL; } if (solved(puz)) { return puz; } // find best candidate square_t *best = find_search_candidate(puz); char *old_vals = strndup(best->vals, NUM_DIGITS); assert(strlen(old_vals) == strlen(best->vals)); int val; for (val = 0; val < strlen(old_vals); val++) { puzzle_t *copy = copy_puzzle(puz); assert(copy != puz); copy->squares[best->row][best->col].vals[0] = old_vals[val]; copy->squares[best->row][best->col].vals[1] = '\0'; puzzle_t *return_puz; if ((return_puz = search(copy)) != NULL) { if (!solved(copy)) { //free_puzzle(copy); if ((puz != return_puz) && (puz != copy)) { free_puzzle(puz); } else if ((copy != puz) && (copy != return_puz)) { free_puzzle(copy); } } //free_puzzle(copy); return return_puz; } free_puzzle(copy); } return NULL; }
//function to recursively solve sudoku oldgrid by guessing and backtracking int guess(char oldgrid[9][9][10]) { char i,j,k; for(i=0;i<9;++i) for(j=0;j<9;++j) if(!oldgrid[i][j][0]) for(k=1;k<10;++k) if(oldgrid[i][j][k]) { char newgrid[9][9][10]; //guessing guessed(oldgrid,newgrid,i,j,k); //solving according to guess solve(newgrid); //checking if solved if(solved(newgrid)) { output(newgrid); return 1; } //guessing recursively if(guess(newgrid)) return 1; //eliminating guess oldgrid[i][j][k]=0; solve(oldgrid); } return 0; }
static void setSolution(Data * d, Work * w, Sol * sol, Info * info) { idxint l = d->n + d->m + 1; setx(d, w, sol); sety(d, w, sol); sets(d, w, sol); if (info->statusVal == 0 || info->statusVal == SOLVED) { pfloat tau = w->u[l - 1]; pfloat kap = ABS(w->v[l - 1]); if (tau > INDETERMINATE_TOL && tau > kap) { info->statusVal = solved(d, sol, info, tau); } else { if (calcNorm(w->u, l) < INDETERMINATE_TOL * SQRTF((pfloat) l)) { info->statusVal = indeterminate(d, sol, info); } else { pfloat bTy = innerProd(d->b, sol->y, d->m); pfloat cTx = innerProd(d->c, sol->x, d->n); if (bTy < cTx) { info->statusVal = infeasible(d, sol, info); } else { info->statusVal = unbounded(d, sol, info); } } } } else if (info->statusVal == INFEASIBLE) { info->statusVal = infeasible(d, sol, info); } else { info->statusVal = unbounded(d, sol, info); } }
int plane_neg(t_ray *ray) { double a; double b; double c; a = 0; b = M_IJ(&(ray->dir), 2, 0); c = M_IJ(&(ray->start), 2, 0); ray->dist = solved(a, b, c,ray); return(0); }
int main(int argc,char **argv) { if((argc!=2)||(strlen(argv[1])!=81)) { printf("[USAGE] %s [INT[81]]\n",argv[0]); return -1; } char grid[9][9][10]; initialize(grid); input(grid,argv[1]); solve(grid); if(solved(grid)) output(grid); else guess(grid); return 0; }
int cylinder_neg(t_ray *ray) { double a; double b; double c; a = M_IJ(&(ray->dir), 0, 0) * M_IJ(&(ray->dir), 0, 0) + M_IJ(&(ray->dir), 1, 0) * M_IJ(&(ray->dir), 1, 0); b = 2 * M_IJ(&(ray->dir), 0, 0) * M_IJ(&(ray->start), 0, 0) + 2 * M_IJ(&(ray->dir), 1, 0) * M_IJ(&(ray->start), 1, 0); c = M_IJ(&(ray->start), 0, 0) * M_IJ(&(ray->start), 0, 0) + M_IJ(&(ray->start), 1, 0) * M_IJ(&(ray->start), 1, 0) - 1; ray->dist = solved(a, b, c,ray); return(0); }
bool Board::checkSolved() { Tile *tempTile; Tile *neighbourTile; for (int x = 0; x < boardSize.width(); x++) { for (int y = 0; y < boardSize.height(); y++) { // Go through each tile tempTile = tileArray[y*boardSize.height() + x]; if (tempTile->getEdgecount() >= 1) { // If this tile has one or more edges, it has to be checked for (int e = 1; e < 16; e *= 2) { // For this tile, check all 4 edges if (tempTile->hasEdge(e)) { // For each edge, check if it is matched with its neighbour switch(e) { case EDGE_UP: if (y == 0) { return false; } // is at edge of the board neighbourTile = tileArray[(y-1)*boardSize.height() + x]; if (!neighbourTile->hasEdge(EDGE_DOWN)) {return false;} break; case EDGE_RIGHT: if (x == boardSize.width()) { return false; } neighbourTile = tileArray[(y)*boardSize.height() + (x+1)]; if (!neighbourTile->hasEdge(EDGE_LEFT)) {return false;} break; case EDGE_DOWN: if (y == boardSize.height()) {return false; } neighbourTile = tileArray[(y+1)*boardSize.height() + x]; if (!neighbourTile->hasEdge(EDGE_UP)) {return false;} break; case EDGE_LEFT: if (x == 0) {return false; } neighbourTile = tileArray[y*boardSize.height() + (x-1)]; if (!neighbourTile->hasEdge(EDGE_RIGHT)) {return false;} break; } } } } else { // Tile has no edges to be connected } } } emit solved(); deactivate(); return true; }
int main(int argc, char **argv) { int i = 0, j = 0, k = 0; alloc_puzzle(); read_in(); printf("\n\nPuzzle as read in:\n"); print_puzzle(); alloc_cand(); while (!solved()) { if (i == 2) { printf("\nno luck after 20 iterations...\nis the puzzle solvable?\nexiting...\n"); free_mem(); exit(EXIT_SUCCESS); } i++; cand(); printf("\nPuzzle after iteration #%d\n", i); print_puzzle(); /* if (i == 50) { printf("num candidates\n"); for (j = 0; j < N; j++) for (k = 0; k < N; k++) printf("%d_%d: %d\n", j, k, puz_can[j][k][0]); } */ reset(); } /* cand(); printf("\nPuzzle after one candidacy:\n"); print_puzzle(); reset(); cand(); printf("\nPuzzle after two candidacies:\n"); print_puzzle(); reset(); cand(); printf("\nPuzzle after three candidacies:\n"); print_puzzle(); */ return EXIT_SUCCESS; }
int solve_step(t_pos *pos) { int moves[MAX_MOVES * 2]; int count = find_moves(pos, moves); int i, cell_id, value, ret, cur_status; //print_moves(count, moves); for (i = 0; i < count; ++i) { cell_id = moves[2 * i]; value = moves[2 * i + 1]; ret = OPEN; play_move(pos, cell_id, value); cur_status = solved(pos); if (cur_status != OPEN) { ret = cur_status; } else if (solve_step(pos) == SOLVED) { ret = SOLVED; } undo_move(pos, cell_id, value); if (ret == SOLVED) { return ret; } } return IMPOSSIBLE; }
int main (int argc, char *argv[]) { puzzle best_soln; int best_cost; int i; puzzle s, t, u; int lbsf; initialize_heap(); get_puzzle(&s); startTime = clock()/1000; print_puzzle(s); insert_heap(s); best_cost = 999; lbsf = 0; while(heap_size > 0) { u = delete_heap(); if (u.lower_bound > lbsf) { lbsf = u.lower_bound; } if (u.lower_bound >= best_cost) break; if (solved(u)) { if (u.lower_bound < best_cost) { s = u; best_cost = u.lower_bound; } } else { for (i = 0; i < possible_moves[u.hole]; i++) { t = make_move (u, i); insert_heap (t); } } } print_solution (s); printf("Finished in %i milliseconds.\n", clock()/1000 - startTime); }
void puzzle(int board[5][5], int blocks) { if (blocks > 8) { return; } if (solved(board)) { printf("Solution found! Blocks: %d \n",blocks); antal++; int i,j; for (i=0; i<5; i++) { for (j=0; j<5; j++) { printf("%d ",board[i][j]); } printf("\n"); } //return; exit(0); } else { int k,m; for (k=0; k<5; k++) { for (m=0; m<5; m++) { // prova bit A if (test(board,ABLOCK,k,m)) { //if (board[k][m+1] == 0 && board[k+1][m] == 0 && board[k+1][m+1] == 0) { board[k][m+1] = 1; board[k+1][m] = 1; board[k+1][m+1] = 1; puzzle(board,blocks+1); board[k][m+1] = 0; board[k+1][m] = 0; board[k+1][m+1] = 0; } // prova bit B //if (board[k][m] == 0 && board[k+1][m] == 0 && board[k+1][m+1] == 0) { if (test(board,BBLOCK,k,m)) { board[k][m] = 2; board[k+1][m] = 2; board[k+1][m+1] = 2; puzzle(board,blocks+1); board[k][m] = 0; board[k+1][m] = 0; board[k+1][m+1] = 0; } // prova bit C if (test(board,CBLOCK,k,m)) { //if (board[k][m] == 0 && board[k][m+1] == 0 && board[k+1][m+1] == 0) { board[k][m] = 3; board[k][m+1] = 3; board[k+1][m+1] = 3; puzzle(board,blocks+1); board[k][m] = 0; board[k][m+1] = 0; board[k+1][m+1] = 0; } // prova bit D if (test(board,DBLOCK,k,m)) { //if (board[k][m] == 0 && board[k][m+1] == 0 && board[k+1][m] == 0) { board[k][m] = 4; board[k][m+1] = 4; board[k+1][m] = 4; puzzle(board,blocks+1); board[k][m] = 0; board[k][m+1] = 0; board[k+1][m] = 0; } } } } }
Sudoku SudokuSolver::solve_impl(const Sudoku& sudoku, bool randomized) const { if (!sudoku.is_valid()) { throw std::runtime_error("solve(): Invalid sudoku"); } const SudokuType& type = sudoku.type(); unsigned n = type.n(); auto pack = [&](unsigned a, unsigned b) -> unsigned { return a * n + b; }; auto id_cell = [&](unsigned x, unsigned y) -> unsigned { return pack(x, y); }; auto id_col = [&](unsigned x, unsigned d) -> unsigned { return type.size() + pack(x, d); }; auto id_row = [&](unsigned y, unsigned d) -> unsigned { return 2 * type.size() + pack(y, d); }; auto id_region = [&](unsigned i, unsigned d) -> unsigned { return 3 * type.size() + pack(i, d); }; std::vector<unsigned> cell_taken(type.size()); std::vector<unsigned> col_taken(type.size()); std::vector<unsigned> row_taken(type.size()); std::vector<unsigned> region_taken(type.size()); for (unsigned i = 0; i < type.size(); ++i) { if (sudoku[i] != 0) { unsigned x = i % n; unsigned y = i / n; unsigned d = sudoku[i] - 1; ++cell_taken[pack(x, y)]; ++col_taken[pack(x, d)]; ++row_taken[pack(y, d)]; ++region_taken[pack(type.region(x, y), d)]; } } std::vector<std::vector<unsigned>> matrix; for (unsigned i = 0; i < n; ++i) { for (unsigned j = 0; j < n; ++j) { if (cell_taken[pack(i, j)]) matrix.push_back({id_cell(i, j)}); if (col_taken[pack(i, j)]) matrix.push_back({id_col(i, j)}); if (row_taken[pack(i, j)]) matrix.push_back({id_row(i, j)}); if (region_taken[pack(i, j)]) matrix.push_back({id_region(i, j)}); } } std::unordered_map<unsigned, unsigned> row_position, row_digit; for (unsigned y = 0; y < n; ++y) { for (unsigned x = 0; x < n; ++x) { for (unsigned d = 0; d < n; ++d) { if (cell_taken[pack(x, y)] || col_taken[pack(x, d)] || row_taken[pack(y, d)] || region_taken[pack(type.region(x, y), d)]) { continue; } unsigned row_index = matrix.size(); row_position[row_index] = y * n + x; row_digit[row_index] = d; matrix.push_back({ id_cell(x, y), id_col(x, d), id_row(y, d), id_region(type.region(x, y), d) }); } } } AlgorithmDLX dlx(ExactCoverProblem(4 * type.size(), matrix)); auto options = AlgorithmDLX::Options(); if (randomized) { static std::random_device rd; static auto engine = std::mt19937(rd()); options.choose_random_column = randomized; options.random_engine = &engine; } options.max_solutions = randomized ? 1 : 2; auto result = dlx.search(options); auto solutions = std::vector<Sudoku>(); for (const auto& rows : result.solutions) { Sudoku solved(sudoku); for (auto i : rows) { auto pos = row_position.find(i); if (pos != row_position.end()) { solved[pos->second] = row_digit[i] + 1; } } solutions.push_back(std::move(solved)); } if (solutions.empty()) { throw std::runtime_error("No solution"); } if (solutions.size() > 1) { throw std::runtime_error("Multiple solutions"); } return solutions[0]; }