// Static methods int VirtualSudokuBoard::squareIndex(BoardSize& size, int row, int col) throw(SudokuException, InvalidDimension) { if (size != NINE) { throw SudokuException("square index makes sense for board with size 9"); } if (NOT(VAL_IN_RANGE(row, 1, size))) { throw InvalidDimension(row); } if (NOT(VAL_IN_RANGE(col, 1, size))) { throw InvalidDimension(col); } int square = 1; while (row > 3) { row -= 3; square += 3; } while (col > 3) { col -= 3; square++; } return square; }
GM2* L::Make::generatorMatrix2 (int n, int dim) { init(); /* * Generator Matrix in Base 2 * * 0 - Sobol * 1 - Niederreiter * 2 - Niederreiter / Xing * 3 - Random * 4 - ShiftNet * 5 - Zero */ switch (n) { case 0: // Sobol case 1: // Niederreiter { if (dim > gm64[n]->getDimension()) throw InvalidDimension(dim); return new GM2 (DiscardDimensions (dim, *gm64 [n])); } case 2: // NX { if (dim == 0) return new GM2 (0); std::auto_ptr<GMGen> m (loadNiederreiterXing (dim < 4 ? 4 : dim)); return new GM2 (DiscardDimensions (dim, *m)); } case 3: // Random { GM2* m = new GM2 (dim); for (int d = 0; d < m->getDimension(); ++d) { for (int r = 0; r < m->getM(); ++r) for (int b = 0; b < m->getPrec(); ++b) m->setd(d, r, b, mt->equidist (2)); } return m; } case 4: // ShiftNet { if (dim > 39) throw InvalidDimension(dim); GM2* m = new GM2 (dim, dim); initShiftNet (*m); return m; } case 5: // Zero return new GM2 (dim); } throw GeneratorMatrixDoesNotExist (n); }
int VirtualSudokuBoard::getEntry(int row, int col) const throw(OpenSudoku::InvalidDimension) { if (NOT(VAL_IN_RANGE(row, 1, this->boardSize))) { throw InvalidDimension(row); } if (NOT(VAL_IN_RANGE(col, 1, this->boardSize))) { throw InvalidDimension(col); } return this->board[row - 1][col - 1]; }
// Mutable methods void VirtualSudokuBoard::update(int row, int col, int ele) throw(OpenSudoku::InvalidDimension, OpenSudoku::InvalidBoxEntry) { if (NOT(VAL_IN_RANGE(row, 1, this->boardSize))) { throw InvalidDimension(row); } if (NOT(VAL_IN_RANGE(col, 1, this->boardSize))) { throw InvalidDimension(col); } if (NOT(VAL_IN_RANGE(ele, 0, this->boardSize))) { throw InvalidBoxEntry(row, col, ele); } this->board[row - 1][col - 1] = ele; }
int VirtualSudokuBoard::boxIndex(BoardSize& size, int row, int col) throw(SudokuException, InvalidDimension) { if (size != NINE) { throw SudokuException("box index makes sense for board with size 9"); } if (NOT(VAL_IN_RANGE(row, 1, size))) { throw InvalidDimension(row); } if (NOT(VAL_IN_RANGE(col, 1, size))) { throw InvalidDimension(col); } return (((row - 1) * 9) + col); }
T& VirtualSudokuBoard::iterateOverColumn(int column, T& intialVal, std::function<T&(T&, int, int, int)>& reducer) const throw(OpenSudoku::InvalidDimension) { if (NOT(VAL_IN_RANGE(column, 1, this->boardSize))) { throw InvalidDimension(column); } T& result = intialVal; for(int row = 1; row <= this->boardSize; ++row) { result = reducer(result, row, column, this->getEntry(row, column)); } return result; }
T& VirtualSudokuBoard::iterateOverSquare(int square, T& intialVal, std::function<T&(T&, int, int, int)>& reducer) const throw(OpenSudoku::InvalidDimension) { if (this->boardSize != NINE) { throw SudokuException("iterateOverSquare makes sense for board with size 9"); } if (NOT(VAL_IN_RANGE(square, 1, this->boardSize))) { throw InvalidDimension(square); } T& result = intialVal; int s_row = ((int) (square - 1) / 3) * 3, s_col = ((square - 1) % 3) * 3; for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { int row = i + s_row, column =j + s_col; result = reducer(result, row, column, this->getEntry(row, column)); } } return result; }
GMGen* L::Make::generatorMatrixGen (int n, int dim, int m) { init(); /* * Generator Matrix Gen * * xx * | * \____ 00 Faure (prime base >= dim) * 01 Sobol (base = 2) * 06 Niederreiter / Xing * 10 ShiftNet * 12 Faure (prime power base >= dim) * 14 Random * 15 Zero * xx base of Niederreiter Matrix */ switch (n) { case 0: // Faure { const int b = Prime::next (dim); GMGen* p = (m == -1 ) ? new GMGen (b, dim) : new GMGen (b, dim, m); initFaure (*p); return p; } case 1: // Sobol { if (dim > gm64[0]->getDimension()) throw InvalidDimension(dim); if (m > int(gm64[0]->getM())) throw GM_CopyM(m, gm64[0]->getM()); return new GMGen (DiscardDimensions (dim, AdjustM (m, *gm64 [0]))); } case 6: // NX { if (dim == 0) return new GMGen (2, 0); std::auto_ptr<GMGen> p (loadNiederreiterXing (dim < 4 ? 4 : dim)); if (m > int(p->getM())) throw GM_CopyM(m, p->getM()); GMGen* pp = new GMGen (DiscardDimensions (dim, AdjustM (m, *p))); return pp; } case 10: // shift net { std::auto_ptr<GM2> p (generatorMatrix2 (4, dim)); return new GMGen (AdjustM (m, *p)); } case 12: // generalized faure { int b = dim; while (! Prime::isPrimePower (b)) ++b; GMGen* p = (m == -1 ) ? new GMGen (b, dim) : new GMGen (b, dim, m); initFaure (*p); return p; } case 14: // Random, base 2 { GMGen* p = (m == -1 ) ? new GMGen (2, dim) : new GMGen (2, dim, m); for (int d = 0; d < p->getDimension(); ++d) { for (int r = 0; r < p->getM(); ++r) for (int b = 0; b < p->getPrec(); ++b) p->setd(d, r, b, mt->equidist (2)); } return p; } case 15: return (m == -1 ) ? new GMGen (2, dim) : new GMGen (2, dim, m); default: if (n >= 1 && n < 100 && Prime::isPrimePower (n)) // Niederreiter { GMGen* p = (m == -1 ) ? new GMGen (n, dim) : new GMGen (n, dim, m, m); initNiederreiter (*p); return p; } } throw GeneratorMatrixDoesNotExist (n); }