Clause* QueryInterface::computeClauseFromCandidates() { Clause* clause = new Clause(); unsigned int j = 0; for( unsigned int i = 0; i < candidates.size(); i++ ) { Var v = candidates[ j ] = candidates[ i ]; assert( !solver.isUndefined( v ) ); if( !solver.isTrue( v ) ) continue; if( solver.getDecisionLevel( v ) == 0 ) addAnswer( v ); else { clause->addLiteral( Literal( v, NEGATIVE ) ); j++; } } candidates.shrink( j ); clause->setCanBeDeleted( false ); printCandidates(); return clause; }
void checkTriplesInCol(sudoku* s, int col){ int y1, y2, y3; for (y1=0; y1<9; ++y1){ for (y2=y1+1; y2<9; ++y2){ for (y3=y2+1; y3<9; ++y3){ // combine three cells int i1 = getIndex(col, y1); int i2 = getIndex(col, y2); int i3 = getIndex(col, y3); int combi = (s->candidates[i1] | s->candidates[i2] | s->candidates[i3]) & ~1; printf ("Testing col %d: %d, %d, %d => %d, %d, %d => %d\n", col, y1, y2, y3, s->candidates[i1], s->candidates[i2], s->candidates[i3], combi); if (countBits(combi)==3){ // "backup fields" int b1, b2, b3; b1 = s->candidates[i1]; b2 = s->candidates[i2]; b3 = s->candidates[i3]; int i; for (i=1; i<=9; ++i){ if (isCandidate(i, combi) && s->fields[i1]!=0 && s->fields[i2]!=0 && s->fields[i3]!=0){ printf ("Found a triple in col %d: %d, %d, %d => %d\n", col, y1, y2, y3, combi); removeCandidatesInCol(s, y1, col, i); } } s->candidates[i1] = b1; s->candidates[i2] = b2; s->candidates[i3] = b3; printCandidates(s); } } } } }
void checkTriplesInRow(sudoku* s, int row){ int x1, x2, x3; for (x1=0; x1<9; ++x1){ for (x2=x1+1; x2<9; ++x2){ for (x3=x2+1; x3<9; ++x3){ // combine three cells int i1 = getIndex(x1, row); int i2 = getIndex(x2, row); int i3 = getIndex(x3, row); int combi = (s->candidates[i1] | s->candidates[i2] | s->candidates[i3]) & ~1; printf ("Testing row %d: %d, %d, %d => %d, %d, %d => %d\n", row, x1, x2, x3, s->candidates[i1], s->candidates[i2], s->candidates[i3], combi); if (countBits(combi)==3){ // "backup fields" int b1, b2, b3; b1 = s->candidates[i1]; b2 = s->candidates[i2]; b3 = s->candidates[i3]; int i; for (i=1; i<=9; ++i){ if (isCandidate(i, combi) && s->fields[i1]!=0 && s->fields[i2]!=0 && s->fields[i3]!=0){ printf ("Found a triple in row %d: %d, %d, %d => %d\n", row, x1, x2, x3, combi); removeCandidatesInRow(s, row, x1, i); } } s->candidates[i1] = b1; s->candidates[i2] = b2; s->candidates[i3] = b3; printCandidates(s); } } } } }
void checkPairsInRow(sudoku* s, int row){ int x1, x2; for (x1=0; x1<9; ++x1){ for (x2=x1+1; x2<9; ++x2){ // combine two cells int i1 = getIndex(x1, row); int i2 = getIndex(x2, row); int combi = (s->candidates[i1] | s->candidates[i2]) & ~1; printf ("Testing row %d: %d, %d, => %d, %d => %d\n", row, x1, x2, s->candidates[i1], s->candidates[i2], combi); if (countBits(combi)==2 && s->fields[i1]==0 && s->fields[i2]==0){ // "backup fields" int b1, b2; b1 = s->candidates[i1]; b2 = s->candidates[i2]; int i; for (i=1; i<=9; ++i){ if (isCandidate(i, combi) && s->fields[i1]!=0 && s->fields[i2]!=0){ printf ("Found a pair in row %d: %d, %d, => %d\n", row, x1, x2, combi); removeCandidatesInRow(s, row, x1, i); } } s->candidates[i1] = b1; s->candidates[i2] = b2; printCandidates(s); } } } }
int solve(sudoku* s){ fixGivens(s); if (fixSingletons(s)) printf("Singletons found.\n"); if (fixPairs(s)) printf("Pairs found.\n"); if (fixTriples(s)) printf("Triples found.\n"); printCandidates(s); backtrack(s); }
void QueryInterface::reduceCandidates() { unsigned int j = 0; for( unsigned int i = 0; i < candidates.size(); i++ ) { Var v = candidates[ j ] = candidates[ i ]; assert( !solver.isUndefined( v ) ); if( !solver.isTrue( v ) ) continue; if( solver.getDecisionLevel( v ) == 0 ) addAnswer( v ); else j++; } candidates.shrink( j ); printCandidates(); }
int fixPairs(sudoku* s){ int* indices; int pair; int i; int row, col; int findings=0; // pairs in rows? for(row=0; row<9; ++row){ for (i=0; i<36; ++i){ indices=pairIndices[i]; if ((s->fields2d[row][indices[0]]==0) && (s->fields2d[row][indices[1]]==0)){ // TODO: why does this segfault? pair=(s->candidates2d[row][indices[0]] | s->candidates2d[row][indices[1]]); debugprintf("Row %d, cols %d and %d (%u, %u) have %d candidates in sum:\n", row, indices[0], indices[1], s->candidates2d[row][indices[0]], s->candidates2d[row][indices[1]], countBits(pair)); int j; for (j=1; j<10; ++j){ if ((1u<<j)&pair){ debugprintf("%d, ", j); } } debugprintf("\n"); if (countBits(pair)==2){ debugprintf("Fixing pair in row %d (cols %d, %d)\n", row, indices[0], indices[1]); findings += fixPairInRow(s, row, indices[0], indices[1]); #if DEBUG==1 printCandidates(s); #endif } } } } // pairs in columns? for(col=0; col<9; ++col){ for (i=0; i<36; ++i){ indices=pairIndices[i]; if ((s->fields2d[indices[0]][col]==0) && (s->fields2d[indices[1]][col]==0)){ // TODO: why does this segfault? pair=(s->candidates2d[indices[0]][col] | s->candidates2d[indices[1]][col]); debugprintf("Col %d, rows %d and %d (%u, %u) have %d candidates in sum:\n", col, indices[0], indices[1], s->candidates2d[indices[0]][col], s->candidates2d[indices[1]][col], countBits(pair)); int j; for (j=1; j<10; ++j){ if ((1u<<j)&pair){ debugprintf("%d, ", j); } } debugprintf("\n"); if (countBits(pair)==2){ debugprintf("Fixing pair in col %d (rows %d, %d)\n", col, indices[0], indices[1]); findings += fixPairInCol(s, col, indices[0], indices[1]); #if DEBUG==1 printCandidates(s); #endif } } } } // do we need additional rounds? if (findings){ fixPairs(s); return 1; } return 0; }