void add_job(Puzzle *puz, dir_t k, line_t i, int depth, int bonus) { Job *job; int priority; int j, par; /* Check if it is already on the job list */ if ((j= puz->clue[k][i].jobindex) >= 0) { if (VJ || WL(puz->clue[k][i])) printf(" J: JOB ON %s %d ALREADY ON JOBLIST\n", CLUENAME(puz->type,k),i); /* Increase the priority of the job, bubbling it up the heap if * necessary */ puz->job[j].priority+= 4 + 25*bonus; if (puz->job[j].depth > depth) puz->job[j].depth= depth; while (j > 1 && puz->job[par= j/2].priority < puz->job[j].priority) { job_exchange(puz, j, par); j= par; } return; } /* Give higher priority to things on the edge */ priority= abs(puz->n[k]/2 - i) + 25*bonus - 10*depth; if (VJ || WL(puz->clue[k][i])) printf(" J: JOB ON %s %d ADDED TO JOBLIST DEPTH %d PRIORITY %d\n", CLUENAME(puz->type,k),i,depth,priority); /* Bubble things down until we find the spot to insert the new key */ j= ++puz->njob; while (j > 1 && puz->job[par= j/2].priority < priority) { job_move(puz, j, par); j= par; } /* Insert the new key */ puz->clue[k][i].jobindex= j; job= &puz->job[j]; job->priority= priority; job->depth= depth; job->dir= k; job->n= i; }
int line_solve(Puzzle *puz, Solution *sol, int contradicting) { extern dir_t cont_dir; extern line_t cont_line; dir_t dir; line_t i; int depth; while (next_job(puz, &dir, &i, &depth)) { nlines++; if ((VB && !VC) || WL(dir,i)) printf("*** %s %d\n",CLUENAME(puz->type,dir), i); if (VB || WL(dir,i)) dump_line(stdout,puz,sol,dir,i); if (contradicting && depth >= contradepth) { /* At max depth we just check if the line is solvable */ line_t *pos, *bcl; if (!left_solve(puz, sol, dir, i, 0, &pos, &bcl)) { if ((VC&&VV) || WL(dir,i)) printf("C: %s %d OK AT DEPTH %d\n", cluename(puz->type,dir),i,depth); } else { if ((VC&&VV) || WL(dir,i)) printf("C: %s %d FAILED AT DEPTH %d\n", cluename(puz->type,dir),i,depth); if (contradicting) { cont_dir= dir; cont_line= i; } return 0; } } else if (apply_lro(puz, sol, dir, i, depth + 1)) { /* Found a contradiction */ if (contradicting) { cont_dir= dir; cont_line= i; } return 0; } if (VJ) { printf("CURRENT JOBS:\n"); dump_jobs(stdout,puz); } } return 1; }
void add_jobs(Puzzle *puz, Solution *sol, int except, Cell *cell, int depth, bit_type *old) { dir_t k; line_t i, j; int lwork, rwork; /* While probing, we OR all bits set into our scratchpad. These values * should not be probed on later during this sequence. */ if (probing) fbit_or(propad(cell),cell->bit); if (!maylinesolve) return; for (k= 0; k < puz->nset; k++) if (k != except) { i= cell->line[k]; j= cell->index[k]; /* We only add the job only if either the saved left or right * solution for the line has been invalidated. */ if (VL || WL(puz->clue[k][i])) printf ("L: CHECK OLD SOLN FOR %s %d CELL %d\n", CLUENAME(puz->type,k),i,j); lwork= left_check(&puz->clue[k][i], j, cell->bit); rwork= right_check(&puz->clue[k][i], j, cell->bit); if (lwork || rwork) { add_job(puz, k, i, depth, newedge(puz, sol->line[k][i], j, old, cell->bit) ); if (!VJ && WL(puz->clue[k][i])) dump_jobs(stdout,puz); } } }
int undo(Puzzle *puz, Solution *sol, int leave_branch) { Hist *h; Clue *clue; Cell **line; dir_t k; int is_branch; line_t i; while (puz->nhist > 0) { h= HIST(puz, puz->nhist-1); /* Invalidate any saved positions for lines crossing undone cell. * We can't just have the fact that nhist < stamp mean the line is * invalid, because we might backtrack and then advance past stamp * again before we recheck the line. */ for (k= 0; k < puz->nset; k++) { i= h->cell->line[k]; clue= &(puz->clue[k][i]); line= sol->line[k][i]; if ((VL && VU) || WL(*clue)) printf("U: CHECK %s %d", CLUENAME(puz->type,k),i); left_undo(puz, clue, line, h->cell->index[k], h->bit); right_undo(puz, clue, line, h->cell->index[k], h->bit); if ((VL && VU) || WL(*clue)) printf("\n"); } is_branch= h->branch; if (!is_branch || !leave_branch) { /* If undoing a solved cell, decrement completion count */ if (h->cell->n == 1) solved_a_cell(puz, h->cell, -1); /* Restore saved value */ h->cell->n= h->n; fbit_cpy(h->cell->bit, h->bit); if (VU || WC(h->cell)) { printf("U: UNDOING CELL "); for (k= 0; k < puz->nset; k++) printf(" %d",h->cell->line[k]); printf(" TO "); dump_bits(stdout,puz,h->cell->bit); printf(" (%d)\n",h->cell->n); } puz->nhist--; } if (is_branch) return 0; } return 1; }