Beispiel #1
0
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;
}
Beispiel #2
0
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);
	}
      }
    } 
  }
}
Beispiel #3
0
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);
	}
      }
    } 
  }
}
Beispiel #4
0
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);
      }
    } 
  }
}
Beispiel #5
0
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);  
}
Beispiel #6
0
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();
}
Beispiel #7
0
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;
}