Example #1
0
void Solver::findPossibleSlots(
        const int box,
        std::vector<std::stack<std::pair<int,int>>>& backTrackStack,
        const int num) {
    int highestRow = (box/3)*3; //Row of upper-left box
    int highestCol = (box%3)*3; //Column of upper-left box

    std::vector<std::pair<int,int>> shuffleVec;
    /* Reversed the order so first item on stack is the upper-leftmost slot */
    for(int rowIter = 2; rowIter >= 0; --rowIter) {
        for(int colIter = 2; colIter >= 0; --colIter) {
            bool existsRow = checkRow(highestRow + rowIter, num);
            bool existsCol = checkColumn(highestCol + colIter, num);
            if(!existsRow && !existsCol) {
                shuffleVec.push_back(std::make_pair(rowIter,colIter));
#ifdef DEBUG
                std::cout << "Adding possible slot " << rowIter << "," <<
                    colIter << " for " << num << std::endl;
#endif
            }
            else if(existsRow) break;
            else continue;
        }
    }
    std::random_device seedGen;
    std::mt19937 randGen(seedGen());
    std::shuffle(shuffleVec.begin(), shuffleVec.end(), randGen);
    for(auto p : shuffleVec) backTrackStack[num-1].push(p);
}
Example #2
0
void Solver::solveSemiSeed(const int semiSeed) {
    /* Create RNG */
    std::random_device seedGen;
    std::mt19937 randGen(seedGen());

    /* Generate semiSeed first */
    int highestRow = (semiSeed/3)*3; //Row of upper-left box
    int highestCol = (semiSeed%3)*3; //Column of upper-left box
    std::array<int, 9> nums = {1,2,3,4,5,6,7,8,9};
    std::shuffle(nums.begin(), nums.end(), randGen);
#ifdef DEBUG
    std::cout << "nums:" << std::endl;
    for(auto e : nums) std::cout << e << " ";
    std::cout << std::endl;
#endif
    for(int valIter = 0; valIter < 9; valIter++) {
        for(int boxIter = 0; boxIter < 9; boxIter++) {
            int currentRow = highestRow+boxIter/3;
            int currentCol = highestCol+boxIter%3;
            bool rowExists = checkRow(currentRow,nums[valIter]);
            bool colExists = checkColumn(currentCol,nums[valIter]);
            if(!rowExists && !colExists) {
                if(
                        !sudokuBoard[semiSeed].addNumber(
                            boxIter/3,
                            boxIter%3,
                            nums[valIter])
                  ) {
#ifdef DEBUG
                    std::cout << "Did not add " << nums[valIter] << " to semiSeed at "
                        << boxIter/3 << "," << boxIter%3 << std::endl;
#endif
                }
                else break;
            }
            else if(rowExists) boxIter+=2;
            else continue;
        }
    }

#ifdef DEBUG
    std::cout << "semiSeed values:" << std::endl;
    sudokuBoard[semiSeed].debugPrint();
#endif

}
Example #3
0
int main(int argc, char* argv[])
{
  size_t NumRows = pow(2, MyRow::NumCol);

  if (argc > 1) {
    NumRows = atoi(argv[1]);
  }

  std::mt19937 seedGen(getpid());
  std::uniform_int_distribution<uint32_t> numGen(0, MaxRangeForEachCol);

  typedef std::vector<MyRow> Table;

  Table table;

  // Enumerate all the combinations of possible columns
  for (uint32_t idx = 0; idx < NumRows; idx ++)
  {
    std::vector<uint32_t> arr;
    //std::generate_n(std::back_inserter(arr), MyRow::NumCol, [&] () -> uint32_t {return numGen(seedGen);});
    //
    //std::cout <<  "idx=" << idx << "{";
    for (uint32_t col = 0; col < MyRow::NumCol; col ++)
    {
      // if the bit-rep of i-th row has j-th bit set
      // set the j-th col for i-th row 
      auto bit = (((0x1 << col) & idx) >> col);
      //std::cout << bit << ",";
      arr.push_back(bit);
    }
    //std::cout << "}" << std::endl;

    MyRow a(arr);
    table.push_back(a);
  }

  // Sort table based on Morton code
  std::sort(table.begin(), table.end());

  // Print the rows sorted by Morton code
  for (auto& row : table) {
    std::cout << row << std::endl;
  }
}
Example #4
0
bool Solver::solve(const int box) {

    /* Create RNG */
    std::random_device seedGen;
    std::mt19937 randGen(seedGen());

    std::array<int, 9> nums = {1,2,3,4,5,6,7,8,9};
    std::shuffle(nums.begin(), nums.end(), randGen);
    bool isSolved = true;

#ifdef DEBUG
    std::cout << "solve2() random array" << std::endl;
    for(auto e : nums) std::cout << e << " ";
    std::cout << std::endl;
#endif

    /* Create backtrack stack */
    std::vector<std::stack<std::pair<int,int>>> backTrackStack(9);
    /* Find possible slots for each value */
    for(int number = 1; number <= 9; ++number) findPossibleSlots(box, backTrackStack, number);

    for(int numsIter = 0; numsIter < 9; ++numsIter) {
        int number = nums[numsIter]-1;

        if(backTrackStack[number].empty()) {
#ifdef DEBUG
            std::cout << "Empty at " << number+1 << std::endl;
#endif
            findPossibleSlots(box, backTrackStack, number+1);
            numsIter--;
            if(numsIter == -1) {
#ifdef DEBUG
                std::cout << "No solution possible for box " << box << std::endl;
#endif
                isSolved = false;
                break;
            }
            number = nums[numsIter]-1; //Since numsIter is already decremented
            auto slot = backTrackStack[number].top();
            int row = std::get<0>(slot);
            int col = std::get<1>(slot);
            sudokuBoard[box].removeNumber(row,col,number+1);
            backTrackStack[number].pop();
            numsIter--; //Decrement even further
            continue;
        }
        auto slot = backTrackStack[number].top();
        int row = std::get<0>(slot);
        int col = std::get<1>(slot);
#ifdef DEBUG1
        std::cout << "Adding " << number+1 << " at " << row << "," << col << std::endl;
#endif

        if(!sudokuBoard[box].addNumber(row, col, number+1)) {
#ifdef DEBUG1
            std::cout << "Rejected " << number+1 << " at " << row << "," << col << std::endl;
#endif
            /* Remove invalid slots */
            backTrackStack[number].pop();
            numsIter--;
            if(backTrackStack[number].empty()) {
#ifdef DEBUG
                std::cout << "Empty at " << number+1 << std::endl;
#endif
                findPossibleSlots(box, backTrackStack, number+1);
                number = nums[numsIter]-1; //Since numsIter is already decremented
                slot = backTrackStack[number].top();
                row = std::get<0>(slot);
                col = std::get<1>(slot);
                sudokuBoard[box].removeNumber(row,col,number+1);
                backTrackStack[number].pop();
                numsIter--; //Decrement even further
                if(numsIter <= -1) {
#ifdef DEBUG
                    std::cout << "No solution possible for box " << box << std::endl;
#endif
                    isSolved = false;
                    break;
                }
            }
        }
#ifdef DEBUG1
        else std::cout << "Added!" << std::endl;
#endif
    } //End of for-loop

    return isSolved;
}