diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cda075..2ff33aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.13) project(dlx) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/common/Element.cpp b/common/Element.cpp index 2f031a6..f7dff9c 100644 --- a/common/Element.cpp +++ b/common/Element.cpp @@ -1,5 +1,3 @@ -#include - #include "Element.hpp" using namespace std; diff --git a/common/Element.hpp b/common/Element.hpp index 3ddbc1d..d7b488c 100644 --- a/common/Element.hpp +++ b/common/Element.hpp @@ -1,6 +1,8 @@ #ifndef ELEMENT_H #define ELEMENT_H +#include + class Header; class Element diff --git a/common/Matrix.cpp b/common/Matrix.cpp index 0d30f64..d20dcd7 100644 --- a/common/Matrix.cpp +++ b/common/Matrix.cpp @@ -1,3 +1,7 @@ +#include "Matrix.hpp" + +#include "Element.hpp" + #include #include #include @@ -5,9 +9,6 @@ #include #include -#include "Matrix.hpp" -#include "Element.hpp" - using namespace std; diff --git a/common/Matrix.hpp b/common/Matrix.hpp index 289bf62..fca9762 100644 --- a/common/Matrix.hpp +++ b/common/Matrix.hpp @@ -1,13 +1,10 @@ #ifndef MATRIX_H #define MATRIX_H -#include -#include -#include -#include - #include "Element.hpp" +#include + class Matrix { diff --git a/common/Puzzle.cpp b/common/Puzzle.cpp index 27201c9..3c65e93 100644 --- a/common/Puzzle.cpp +++ b/common/Puzzle.cpp @@ -1,10 +1,9 @@ -#include -#include - #include "Puzzle.hpp" #include "Matrix.hpp" +#include + using namespace std; diff --git a/common/Puzzle.hpp b/common/Puzzle.hpp index 86477d9..02a1b55 100644 --- a/common/Puzzle.hpp +++ b/common/Puzzle.hpp @@ -1,12 +1,13 @@ #ifndef PUZZLE_H #define PUZZLE_H -#include - #include "Matrix.hpp" +#include + class Element; + class Puzzle { public: @@ -18,7 +19,7 @@ class Puzzle protected: virtual void init() = 0; - virtual void print(std::vector& solution) = 0; + virtual void print(std::vector const& solution) = 0; struct SubGoal { Matrix matrix; diff --git a/main.cpp b/main.cpp index 03ceed3..c3e776e 100644 --- a/main.cpp +++ b/main.cpp @@ -1,9 +1,3 @@ -#include -#include -#include -#include -#include - #include "Iq.hpp" #include "Pentominoes.hpp" #include "Pyramid.hpp" @@ -14,6 +8,12 @@ #include "boost/any.hpp" #include "boost/program_options.hpp" +#include +#include +#include +#include +#include + using namespace std; namespace po = boost::program_options; diff --git a/queens/Queens.cpp b/queens/Queens.cpp index eee5895..a8d4c53 100644 --- a/queens/Queens.cpp +++ b/queens/Queens.cpp @@ -76,7 +76,7 @@ void Queens::init() } -void Queens::print(vector& solution) +void Queens::print(vector const& solution) { static int count = 0; @@ -92,7 +92,7 @@ void Queens::print(vector& solution) cout << "#" << ++count << ":" << endl; for(int f=0; f(r, f)) ? "\u265b " : "\u30fb"); + cout << (queens.count(pair(r, f)) ? "\u265b " : "\u30fb"); } cout << endl; } diff --git a/queens/Queens.hpp b/queens/Queens.hpp index 387c6f4..8652375 100644 --- a/queens/Queens.hpp +++ b/queens/Queens.hpp @@ -1,13 +1,14 @@ #ifndef QUEENS_H #define QUEENS_H -#include - #include "Puzzle.hpp" +#include + class Element; class Matrix; + class Queens : public Puzzle { public: @@ -17,7 +18,7 @@ class Queens : public Puzzle private: void init() override; - void print(std::vector& solution) override; + void print(std::vector const& solution) override; int n; diff --git a/sudoku/Sudoku.cpp b/sudoku/Sudoku.cpp index 14466f5..24b6370 100644 --- a/sudoku/Sudoku.cpp +++ b/sudoku/Sudoku.cpp @@ -1,8 +1,8 @@ +#include "Sudoku.hpp" + #include #include -#include "Sudoku.hpp" - using namespace std; @@ -87,7 +87,7 @@ void Sudoku::init() } -void Sudoku::print(std::vector& solution) +void Sudoku::print(std::vector const& solution) { int board[9][10]={0}; for(auto& e: solution) { diff --git a/sudoku/Sudoku.hpp b/sudoku/Sudoku.hpp index a44659c..6b1bef0 100644 --- a/sudoku/Sudoku.hpp +++ b/sudoku/Sudoku.hpp @@ -3,6 +3,7 @@ #include "Puzzle.hpp" + class Sudoku : public Puzzle { public: @@ -12,7 +13,7 @@ class Sudoku : public Puzzle private: void init() override; - void print(std::vector& solution) override; + void print(std::vector const& solution) override; }; diff --git a/tiling/CMakeLists.txt b/tiling/CMakeLists.txt index 616072e..ba9c51c 100644 --- a/tiling/CMakeLists.txt +++ b/tiling/CMakeLists.txt @@ -1,6 +1,8 @@ add_library(tiling OBJECT Iq.cpp Iq.hpp + Ortho2d.cpp + Ortho2d.hpp Pentominoes.cpp Pentominoes.hpp Pyramid.cpp diff --git a/tiling/Iq.cpp b/tiling/Iq.cpp index ba1a79f..7d8be76 100644 --- a/tiling/Iq.cpp +++ b/tiling/Iq.cpp @@ -1,159 +1,28 @@ -#include -#include -#include -#include -#include - #include "Iq.hpp" #include "boost/algorithm/string.hpp" -using namespace std; - - -class IqCell -{ -public: - - int rOffset; - int cOffset; - - IqCell(int row, int col) - : rOffset(row), cOffset(col) - { - } - - bool operator<(IqCell const& rhs) const - { - if (rOffset < rhs.rOffset) return true; - if (rOffset > rhs.rOffset) return false; - if (cOffset < rhs.cOffset) return true; - if (cOffset > rhs.cOffset) return false; - return false; - } - - std::string name() const - { - ostringstream str; - str << setfill('0') << setw(2) << rOffset << setw(2) << cOffset; - return str.str(); - } - -}; - - -class IqPiece -{ -public: - - string name; - vector cells; - - bool operator<(IqPiece const& rhs) const - { - if (name < rhs.name) return true; - if (name > rhs.name) return false; - if (cells < rhs.cells) return true; - if (cells > rhs.cells) return false; - return false; - } - -}; - - -namespace { - -vector pieces = { - {"T", {{0,0},{0,1},{0,2},{1,1}}}, - {"I", {{0,0},{0,1},{0,2}}}, - {"L", {{0,0},{0,1},{0,2},{1,0}}}, - {"S", {{0,0},{0,1},{1,1},{1,2}}}, - {"O", {{0,0},{0,1},{1,0},{1,1}}}, - {"R", {{0,0},{0,1},{1,1}}}, - {"P0", {{0,0}}}, - {"P1", {{0,0}}}, - {"P2", {{0,0}}}, -}; - -} // anonymous namespace - - -void Iq::addPieceAspects(IqPiece const& piece, set& aspects) -{ - auto aspect = piece; - for(int flip=0; flip<2; ++flip) { - for(int rot=0; rot<4; ++rot) { - if (aspectFilter(piece, flip, rot)) continue; - sort(aspect.cells.begin(), aspect.cells.end()); - int minrow = numeric_limits::max(); - int mincol = numeric_limits::max(); - for(auto const& cell: aspect.cells) { - minrow = min(minrow, cell.rOffset); - mincol = min(mincol, cell.cOffset); - } - for(auto& cell: aspect.cells) { - cell.rOffset -= minrow; - cell.cOffset -= mincol; - } - aspects.insert(aspect); - for(auto& cell: aspect.cells) { - auto temp = cell.rOffset; - cell.rOffset = cell.cOffset; - cell.cOffset = -temp; - } - } - for(auto& cell: aspect.cells) { - cell.rOffset = -cell.rOffset; - } - } -} - - -void Iq::addAspectPlacements( - IqPiece const& aspect, - set const& board, - vector & placements) -{ - for(auto const& pos: board) { - auto placement = aspect; - bool fit = true; - for(auto& cell: placement.cells) { - cell.rOffset += pos.rOffset; - cell.cOffset += pos.cOffset; - if (board.count(cell) == 0) { - fit = false; - break; - } - } - if (fit & !placementFilter(aspect, pos)) { - placements.push_back(placement); - } - } -} - - -bool Iq::aspectFilter(IqPiece const& piece, int flip, int rot) -{ - return false; -} - +#include +#include +#include -bool Iq::placementFilter(IqPiece const& aspect, IqCell const& pos) -{ - if ((aspect.name == "P0") && ((pos.cOffset != c0) || (pos.rOffset != r0))) { - return true; - } else if ((aspect.name == "P1") && ((pos.cOffset != c1) || (pos.rOffset != r1))) { - return true; - } else if ((aspect.name == "P2") && ((pos.cOffset != c2) || (pos.rOffset != r2))) { - return true; - } else { - return false; - } -} +using namespace std; void Iq::init() { + static vector pieces = { + {"T", {{0,0},{0,1},{0,2},{1,1}}}, + {"I", {{0,0},{0,1},{0,2}}}, + {"L", {{0,0},{0,1},{0,2},{1,0}}}, + {"S", {{0,0},{0,1},{1,1},{1,2}}}, + {"O", {{0,0},{0,1},{1,0},{1,1}}}, + {"R", {{0,0},{0,1},{1,1}}}, + {"P0", {{0,0}}}, + {"P1", {{0,0}}}, + {"P2", {{0,0}}} + }; + cout << "┌───────┬───┬───────┐" << endl; cout << "│ A B │ │ D E │" << endl; cout << "│ └───┴───┐ │" << endl; @@ -174,47 +43,42 @@ void Iq::init() boost::to_upper(line); sort(line.begin(), line.end()); - string p0 = "ABFGHILQ"; - string p1 = "DEJOTXY"; - string p2 = "MNPRUVW"; + string t0 = "ABFGHILQ"; + string t1 = "DEJOTXY"; + string t2 = "MNPRUVW"; - string i0; - string i1; - string i2; + string p0; + string p1; + string p2; - set_intersection(line.begin(), line.end(), p0.begin(), p0.end(), back_inserter(i0)); - set_intersection(line.begin(), line.end(), p1.begin(), p1.end(), back_inserter(i1)); - set_intersection(line.begin(), line.end(), p2.begin(), p2.end(), back_inserter(i2)); + set_intersection(line.begin(), line.end(), t0.begin(), t0.end(), back_inserter(p0)); + set_intersection(line.begin(), line.end(), t1.begin(), t1.end(), back_inserter(p1)); + set_intersection(line.begin(), line.end(), t2.begin(), t2.end(), back_inserter(p2)); - if ((i0.size() != 1) || (i1.size() != 1) || (i2.size() != 1)) { + if ((p0.size() != 1) || (p1.size() != 1) || (p2.size() != 1)) throw runtime_error("not one letter from each track"); - } - r0 = (i0[0]-'A') / 5; - c0 = (i0[0]-'A') % 5; - r1 = (i1[0]-'A') / 5; - c1 = (i1[0]-'A') % 5; - r2 = (i2[0]-'A') / 5; - c2 = (i2[0]-'A') % 5; + p0r = (p0[0]-'A') / 5; + p0c = (p0[0]-'A') % 5; + p1r = (p1[0]-'A') / 5; + p1c = (p1[0]-'A') % 5; + p2r = (p2[0]-'A') / 5; + p2c = (p2[0]-'A') % 5; cout << endl; subGoals.emplace_back(); auto& sg = subGoals.back(); - set aspects; + set aspects; for(auto const& piece: pieces) { addPieceAspects(piece, aspects); } - set board; - for(auto r=0; r<5; ++r) { - for(auto c=0; c<5; ++c) { - board.insert(IqCell(r, c)); - } - } + set board; + buildBoard(board, 5, 5); - vector placements; + vector placements; for(auto const& aspect: aspects) { addAspectPlacements(aspect, board, placements); } @@ -236,50 +100,9 @@ void Iq::init() } -void Iq::print(vector& solution) +bool Iq::placementFilter(Piece const& aspect, Cell const& pos) { - static int count = 0; - - static const string corner[16] = { - "\u0020", "\u2575", "\u2574", "\u2518", - "\u2576", "\u2514", "\u2500", "\u2534", - "\u2577", "\u2502", "\u2510", "\u2524", - "\u250c", "\u251c", "\u252c", "\u253c" - }; - - map board; - int rmax = 0; - int cmax = 0; - - for(auto const& re: solution) { - auto pe = re; - for(; pe->col->name.length() > 2; pe=pe->l); - for(auto ce=pe->r; ce!=pe; ce=ce->r) { - int r = stoi(ce->col->name.substr(0,2)) + 1; - int c = stoi(ce->col->name.substr(2,2)) + 1; - rmax = max(rmax, r); - cmax = max(cmax, c); - board[IqCell(r,c)] = pe->col->name; - } - } - - cout << "#" << ++count << ":" << endl; - for(int r=1; r<=rmax+1; ++r) { - for(int c=1; c<=cmax+1; ++c) { - cout << corner[ - ((board[IqCell(r-1, c-1)] != board[IqCell(r-1, c )]) ? 1 : 0) + - ((board[IqCell(r-1, c-1)] != board[IqCell(r, c-1)]) ? 2 : 0) + - ((board[IqCell(r-1, c )] != board[IqCell(r, c )]) ? 4 : 0) + - ((board[IqCell(r, c-1)] != board[IqCell(r, c )]) ? 8 : 0) - ]; - cout << ((board[IqCell(r-1, c)] != board[IqCell(r, c)]) - ? "\u2500\u2500\u2500" : "\u0020\u0020\u0020"); - } - cout << endl; - for(int c=1; c<=cmax+1; ++c) { - cout << ((board[IqCell(r, c-1)] != board[IqCell(r, c)]) ? "\u2502" : "\u0020"); - cout << "\u0020\u0020\u0020"; - } - cout << endl; - } + return ((aspect.name == "P0") && ((pos.cOffset != p0c) || (pos.rOffset != p0r))) + || ((aspect.name == "P1") && ((pos.cOffset != p1c) || (pos.rOffset != p1r))) + || ((aspect.name == "P2") && ((pos.cOffset != p2c) || (pos.rOffset != p2r))); } diff --git a/tiling/Iq.hpp b/tiling/Iq.hpp index c6477bc..0c38b12 100644 --- a/tiling/Iq.hpp +++ b/tiling/Iq.hpp @@ -1,39 +1,21 @@ #ifndef IQ_H #define IQ_H -#include -#include +#include "Ortho2d.hpp" -#include "Puzzle.hpp" -class IqCell; -class Element; -class IqPiece; - - -class Iq : public Puzzle +class Iq : public Ortho2d { protected: void init() override; - void print(std::vector& solution) override; - - bool aspectFilter(IqPiece const& piece, int flip, int rot); - bool placementFilter(IqPiece const& aspect, IqCell const& pos); + bool placementFilter(Piece const& aspect, Cell const& pos) override; private: - void addPieceAspects(IqPiece const& piece, std::set& aspects); - - void addAspectPlacements( - IqPiece const& aspect, - std::set const& board, - std::vector& placements - ); - - int r0, c0; - int r1, c1; - int r2, c2; + int p0r, p0c; + int p1r, p1c; + int p2r, p2c; }; diff --git a/tiling/Ortho2d.cpp b/tiling/Ortho2d.cpp new file mode 100644 index 0000000..5482621 --- /dev/null +++ b/tiling/Ortho2d.cpp @@ -0,0 +1,168 @@ +#include "Ortho2d.hpp" + +#include +#include +#include +#include +#include + +using namespace std; + + +Ortho2d::Cell::Cell(int row, int col) +: rOffset(row), cOffset(col) +{ +} + + +bool Ortho2d::Cell::operator<(Cell const& rhs) const +{ + if (rOffset < rhs.rOffset) return true; + if (rOffset > rhs.rOffset) return false; + if (cOffset < rhs.cOffset) return true; + if (cOffset > rhs.cOffset) return false; + return false; +} + + +std::string Ortho2d::Cell::name() const +{ + ostringstream str; + str << setfill('0') << setw(2) << rOffset << setw(2) << cOffset; + return str.str(); +} + + +bool Ortho2d::Piece::operator<(Piece const& rhs) const +{ + if (name < rhs.name) return true; + if (name > rhs.name) return false; + if (cells < rhs.cells) return true; + if (cells > rhs.cells) return false; + return false; +} + + +void Ortho2d::print(vector const& solution) +{ + static int count = 0; + + static const string corner[16] = { + "\u0020", "\u2575", "\u2574", "\u2518", + "\u2576", "\u2514", "\u2500", "\u2534", + "\u2577", "\u2502", "\u2510", "\u2524", + "\u250c", "\u251c", "\u252c", "\u253c" + }; + + map board; + int rmax = 0; + int cmax = 0; + + for(auto const& re: solution) { + auto pe = re; + for(; pe->col->name.length() > 2; pe=pe->l); + for(auto ce=pe->r; ce!=pe; ce=ce->r) { + int r = stoi(ce->col->name.substr(0,2)) + 1; + int c = stoi(ce->col->name.substr(2,2)) + 1; + rmax = max(rmax, r); + cmax = max(cmax, c); + board[Cell(r,c)] = pe->col->name; + } + } + + cout << "#" << ++count << ":" << endl; + for(int r=1; r<=rmax+1; ++r) { + for(int c=1; c<=cmax+1; ++c) { + cout << corner[ + ((board[Cell(r-1, c-1)] != board[Cell(r-1, c )]) ? 1 : 0) + + ((board[Cell(r-1, c-1)] != board[Cell(r, c-1)]) ? 2 : 0) + + ((board[Cell(r-1, c )] != board[Cell(r, c )]) ? 4 : 0) + + ((board[Cell(r, c-1)] != board[Cell(r, c )]) ? 8 : 0) + ]; + cout << ((board[Cell(r-1, c)] != board[Cell(r, c)]) + ? "\u2500\u2500\u2500" : "\u0020\u0020\u0020"); + } + cout << endl; + for(int c=1; c<=cmax+1; ++c) { + cout << ((board[Cell(r, c-1)] != board[Cell(r, c)]) ? "\u2502" : "\u0020"); + cout << "\u0020\u0020\u0020"; + } + cout << endl; + } +} + + +void Ortho2d::addPieceAspects(Piece const& piece, set& aspects) +{ + auto aspect = piece; + for(int flip=0; flip<2; ++flip) { + for(int rot=0; rot<4; ++rot) { + if (aspectFilter(piece, flip, rot)) continue; + sort(aspect.cells.begin(), aspect.cells.end()); + int minrow = numeric_limits::max(); + int mincol = numeric_limits::max(); + for(auto const& cell: aspect.cells) { + minrow = min(minrow, cell.rOffset); + mincol = min(mincol, cell.cOffset); + } + for(auto& cell: aspect.cells) { + cell.rOffset -= minrow; + cell.cOffset -= mincol; + } + aspects.insert(aspect); + for(auto& cell: aspect.cells) { + auto temp = cell.rOffset; + cell.rOffset = cell.cOffset; + cell.cOffset = -temp; + } + } + for(auto& cell: aspect.cells) { + cell.rOffset = -cell.rOffset; + } + } +} + + +void Ortho2d::addAspectPlacements( + Piece const& aspect, + set const& board, + vector & placements) +{ + for(auto const& pos: board) { + auto placement = aspect; + bool fit = true; + for(auto& cell: placement.cells) { + cell.rOffset += pos.rOffset; + cell.cOffset += pos.cOffset; + if (board.count(cell) == 0) { + fit = false; + break; + } + } + if (fit & !placementFilter(aspect, pos)) { + placements.push_back(placement); + } + } +} + + +void Ortho2d::buildBoard(set& board, int numRows, int numColumns) +{ + for(auto r=0; r +#include +#include + +class Ortho2dPiece; +class Ortho2dCell; + + +class Ortho2d : public Puzzle +{ +protected: + + struct Cell + { + int rOffset; + int cOffset; + Cell(int row, int col); + bool operator<(Cell const& rhs) const; + std::string name() const; + }; + + struct Piece + { + std::string name; + std::vector cells; + bool operator<(Piece const& rhs) const; + }; + + void buildBoard(std::set& board, int numRows, int numColumns); + + void addPieceAspects( + Piece const& piece, + std::set& aspects + ); + + void addAspectPlacements( + Piece const& aspect, + std::set const& board, + std::vector& placements + ); + + virtual bool aspectFilter(Piece const& piece, int flip, int rot); + virtual bool placementFilter(Piece const& aspect, Cell const& pos); + + void print(std::vector const& solution) override; + +}; + +#endif // !defined(ORTHO2D_H) diff --git a/tiling/Pentominoes.cpp b/tiling/Pentominoes.cpp index b54b0f1..ace9d2f 100644 --- a/tiling/Pentominoes.cpp +++ b/tiling/Pentominoes.cpp @@ -1,156 +1,36 @@ +#include "Pentominoes.hpp" + +#include "Element.hpp" +#include "Matrix.hpp" + #include #include #include #include #include #include -#include #include -#include "Pentominoes.hpp" - -#include "Element.hpp" -#include "Matrix.hpp" - using namespace std; -class Cell -{ -public: - - int rOffset; - int cOffset; - - Cell(int row, int col) - : rOffset(row), cOffset(col) - { - } - - bool operator<(Cell const& rhs) const - { - if (rOffset < rhs.rOffset) return true; - if (rOffset > rhs.rOffset) return false; - if (cOffset < rhs.cOffset) return true; - if (cOffset > rhs.cOffset) return false; - return false; - } - - std::string name() const - { - ostringstream str; - str << setfill('0') << setw(2) << rOffset << setw(2) << cOffset; - return str.str(); - } - -}; - - -class Piece -{ -public: - - string name; - vector cells; - - bool operator<(Piece const& rhs) const - { - if (name < rhs.name) return true; - if (name > rhs.name) return false; - if (cells < rhs.cells) return true; - if (cells > rhs.cells) return false; - return false; - } - -}; - - -namespace { - -vector pieces = { - {"F", {{0,1}, {0,2}, {1,0}, {1,1}, {2,1}}}, - {"I", {{0,0}, {1,0}, {2,0}, {3,0}, {4,0}}}, - {"L", {{0,0}, {1,0}, {2,0}, {3,0}, {3,1}}}, - {"N", {{0,0}, {0,1}, {1,1}, {1,2}, {1,3}}}, - {"P", {{0,0}, {0,1}, {1,0}, {1,1}, {2,0}}}, - {"T", {{0,0}, {0,1}, {0,2}, {1,1}, {2,1}}}, - {"U", {{0,0}, {1,0}, {1,1}, {1,2}, {0,2}}}, - {"V", {{0,0}, {1,0}, {2,0}, {2,1}, {2,2}}}, - {"W", {{0,0}, {1,0}, {1,1}, {2,1}, {2,2}}}, - {"X", {{0,1}, {1,0}, {1,1}, {1,2}, {2,1}}}, - {"Y", {{0,2}, {1,0}, {1,1}, {1,2}, {1,3}}}, - {"Z", {{0,0}, {0,1}, {1,1}, {2,1}, {2,2}}} -}; - - -void rectBoard(set& board, int rows, int cols) -{ - for(auto r=0; r& aspects) -{ - auto aspect = piece; - for(int flip=0; flip<2; ++flip) { - for(int rot=0; rot<4; ++rot) { - if (aspectFilter(piece, flip, rot)) continue; - sort(aspect.cells.begin(), aspect.cells.end()); - int minrow = numeric_limits::max(); - int mincol = numeric_limits::max(); - for(auto const& cell: aspect.cells) { - minrow = min(minrow, cell.rOffset); - mincol = min(mincol, cell.cOffset); - } - for(auto& cell: aspect.cells) { - cell.rOffset -= minrow; - cell.cOffset -= mincol; - } - aspects.insert(aspect); - for(auto& cell: aspect.cells) { - auto temp = cell.rOffset; - cell.rOffset = cell.cOffset; - cell.cOffset = -temp; - } - } - for(auto& cell: aspect.cells) { - cell.rOffset = -cell.rOffset; - } - } -} - - -void Pentominoes::addAspectPlacements( - Piece const& aspect, - set const& board, - vector& placements) -{ - for(auto const& pos: board) { - auto placement = aspect; - bool fit = true; - for(auto& cell: placement.cells) { - cell.rOffset += pos.rOffset; - cell.cOffset += pos.cOffset; - if (board.count(cell) == 0) { - fit = false; - break; - } - } - if (fit & !placementFilter(aspect, pos)) { - placements.push_back(placement); - } - } -} - - void Pentominoes::init() { + static vector pieces = { + {"F", {{0,1}, {0,2}, {1,0}, {1,1}, {2,1}}}, + {"I", {{0,0}, {1,0}, {2,0}, {3,0}, {4,0}}}, + {"L", {{0,0}, {1,0}, {2,0}, {3,0}, {3,1}}}, + {"N", {{0,0}, {0,1}, {1,1}, {1,2}, {1,3}}}, + {"P", {{0,0}, {0,1}, {1,0}, {1,1}, {2,0}}}, + {"T", {{0,0}, {0,1}, {0,2}, {1,1}, {2,1}}}, + {"U", {{0,0}, {1,0}, {1,1}, {1,2}, {0,2}}}, + {"V", {{0,0}, {1,0}, {2,0}, {2,1}, {2,2}}}, + {"W", {{0,0}, {1,0}, {1,1}, {2,1}, {2,2}}}, + {"X", {{0,1}, {1,0}, {1,1}, {1,2}, {2,1}}}, + {"Y", {{0,2}, {1,0}, {1,1}, {1,2}, {1,3}}}, + {"Z", {{0,0}, {0,1}, {1,1}, {2,1}, {2,2}}} + }; + subGoals.emplace_back(); auto& sg = subGoals.back(); @@ -184,70 +64,9 @@ void Pentominoes::init() } -void Pentominoes::print(vector& solution) -{ - static int count = 0; - - static string corner[16] = { - "\u0020", "\u2575", "\u2574", "\u2518", - "\u2576", "\u2514", "\u2500", "\u2534", - "\u2577", "\u2502", "\u2510", "\u2524", - "\u250c", "\u251c", "\u252c", "\u253c" - }; - - map board; - int rmax = 0; - int cmax = 0; - - for(auto& re: solution) { - auto pe = re; - for(; pe->col->name.length() > 1; pe=pe->l); - for(auto ce=pe->r; ce!=pe; ce=ce->r) { - int r = stoi(ce->col->name.substr(0,2)) + 1; - int c = stoi(ce->col->name.substr(2,2)) + 1; - rmax = max(rmax, r); - cmax = max(cmax, c); - board[Cell(r,c)] = pe->col->name; - } - } - - cout << "#" << ++count << ":" << endl; - for(int r=1; r<=rmax+1; ++r) { - for(int c=1; c<=cmax+1; ++c) { - cout << corner[ - ((board[Cell(r-1, c-1)] != board[Cell(r-1, c )]) ? 1 : 0) + - ((board[Cell(r-1, c-1)] != board[Cell(r, c-1)]) ? 2 : 0) + - ((board[Cell(r-1, c )] != board[Cell(r, c )]) ? 4 : 0) + - ((board[Cell(r, c-1)] != board[Cell(r, c )]) ? 8 : 0) - ]; - cout << ((board[Cell(r-1, c)] != board[Cell(r, c)]) - ? "\u2500\u2500\u2500" : "\u0020\u0020\u0020"); - } - cout << endl; - for(int c=1; c<=cmax+1; ++c) { - cout << ((board[Cell(r, c-1)] != board[Cell(r, c)]) - ? "\u2502\u0020\u0020\u0020" : "\u0020\u0020\u0020\u0020"); - } - cout << endl; - } -} - - -bool Pentominoes::aspectFilter(Piece const& piece, int flip, int rot) -{ - return false; -} - - -bool Pentominoes::placementFilter(Piece const& aspect, Cell const& pos) -{ - return false; -} - - void Pentominoes6x10::buildBoard(set& board) { - rectBoard(board, 6, 10); + Ortho2d::buildBoard(board, 6, 10); } @@ -259,7 +78,7 @@ bool Pentominoes6x10::placementFilter(Piece const& aspect, Cell const& pos) void Pentominoes5x12::buildBoard(set& board) { - rectBoard(board, 5, 12); + Ortho2d::buildBoard(board, 5, 12); } @@ -271,7 +90,7 @@ bool Pentominoes5x12::aspectFilter(Piece const& piece, int flip, int rot) void Pentominoes4x15::buildBoard(set& board) { - rectBoard(board, 4, 15); + Ortho2d::buildBoard(board, 4, 15); } @@ -283,7 +102,7 @@ bool Pentominoes4x15::aspectFilter(Piece const& piece, int flip, int rot) void Pentominoes3x20::buildBoard(set& board) { - rectBoard(board, 3, 20); + Ortho2d::buildBoard(board, 3, 20); } diff --git a/tiling/Pentominoes.hpp b/tiling/Pentominoes.hpp index dc59871..75daf8b 100644 --- a/tiling/Pentominoes.hpp +++ b/tiling/Pentominoes.hpp @@ -1,37 +1,17 @@ #ifndef PENTOMINOES_H #define PENTOMINOES_H +#include "Ortho2d.hpp" + #include #include -#include "Puzzle.hpp" - -class Cell; -class Element; -class Piece; - -class Pentominoes : public Puzzle +class Pentominoes : public Ortho2d { protected: - void init() override; - void print(std::vector& solution) override; - virtual void buildBoard(std::set& board) = 0; - virtual bool aspectFilter(Piece const& piece, int flip, int rot); - virtual bool placementFilter(Piece const& aspect, Cell const& pos); - -private: - - void addPieceAspects(Piece const& piece, std::set& aspects); - - void addAspectPlacements( - Piece const& aspect, - std::set const& board, - std::vector& placements - ); - }; diff --git a/tiling/Pyramid.cpp b/tiling/Pyramid.cpp index 048d3e5..0a94730 100644 --- a/tiling/Pyramid.cpp +++ b/tiling/Pyramid.cpp @@ -1,9 +1,9 @@ +#include "Pyramid.hpp" + #include #include #include -#include "Pyramid.hpp" - using namespace std; @@ -236,7 +236,7 @@ void Pyramid::init() } -void Pyramid::print(vector& solution) +void Pyramid::print(vector const& solution) { static int count = 0; diff --git a/tiling/Pyramid.hpp b/tiling/Pyramid.hpp index ff3703a..3c1c81f 100644 --- a/tiling/Pyramid.hpp +++ b/tiling/Pyramid.hpp @@ -1,11 +1,11 @@ #ifndef PYRAMID_HPP #define PYRAMID_HPP +#include "Puzzle.hpp" + #include #include -#include "Puzzle.hpp" - class PyrCell; class Element; class PyrPiece; @@ -16,7 +16,7 @@ class Pyramid : public Puzzle protected: virtual void init() override; - virtual void print(std::vector& solution) override; + virtual void print(std::vector const& solution) override; private: diff --git a/tiling/Soma.cpp b/tiling/Soma.cpp index b84b3e4..95b59d3 100644 --- a/tiling/Soma.cpp +++ b/tiling/Soma.cpp @@ -1,9 +1,9 @@ +#include "Soma.hpp" + #include #include #include -#include "Soma.hpp" - using namespace std; @@ -242,7 +242,7 @@ void Soma::init() } -void Soma::print(vector& solution) +void Soma::print(vector const& solution) { static int count = 0; diff --git a/tiling/Soma.hpp b/tiling/Soma.hpp index 76b92dd..a924d00 100644 --- a/tiling/Soma.hpp +++ b/tiling/Soma.hpp @@ -1,11 +1,11 @@ #ifndef SOMA_HPP #define SOMA_HPP +#include "Puzzle.hpp" + #include #include -#include "Puzzle.hpp" - class SomaCell; class Element; class SomaPiece; @@ -16,7 +16,7 @@ class Soma : public Puzzle protected: virtual void init() override; - virtual void print(std::vector& solution) override; + virtual void print(std::vector const& solution) override; private: