Split out results structure
We now return the results in a separate structure to the grid we have been working on. This ultimately makes it easier to play with the implementation of the solution finder.
This commit is contained in:
126
main.cc
126
main.cc
@@ -57,6 +57,78 @@ namespace {
|
|||||||
int length_; ///< Side length
|
int length_; ///< Side length
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Structure holding the results.
|
||||||
|
*/
|
||||||
|
struct Results {
|
||||||
|
Results(int length, std::vector<Square> squares) : length_(length), squares_(std::move(squares)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Results(Results const &other) noexcept = delete;
|
||||||
|
Results &operator=(Results const &other) noexcept = delete;
|
||||||
|
Results &operator=(Results &&other) noexcept = default;
|
||||||
|
Results(Results &&other) noexcept = default;
|
||||||
|
~Results() noexcept = default;
|
||||||
|
|
||||||
|
auto length() const noexcept -> int { return length_; }
|
||||||
|
|
||||||
|
/** Output the grid. */
|
||||||
|
auto output() const -> void {
|
||||||
|
std::string out;
|
||||||
|
out.resize(length_ * length_);
|
||||||
|
for (auto const& sq : squares_) {
|
||||||
|
prettify_sq(out, sq);
|
||||||
|
}
|
||||||
|
for (auto idx = 0; idx < length_ * length_; idx += length_) {
|
||||||
|
std::cout << std::string_view(out.data() + idx, length_) << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto set(std::string& s, int x, int y, char c) const noexcept -> void {
|
||||||
|
assert(x < length_);
|
||||||
|
assert(y < length_);
|
||||||
|
assert(grid_[x + y * length_] != c);
|
||||||
|
s[x + y * length_] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto prettify_sq(std::string& s, Square const &sq) const noexcept -> void {
|
||||||
|
switch (sq.length()) {
|
||||||
|
case 1: set(s, sq.x(), sq.y(), '*');
|
||||||
|
break;
|
||||||
|
case 2: set(s, sq.x(), sq.y(), '+');
|
||||||
|
set(s, sq.x() + 1, sq.y(), '+');
|
||||||
|
set(s, sq.x(), sq.y() + 1, '+');
|
||||||
|
set(s, sq.x() + 1, sq.y() + 1, '+');
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
auto n = sq.length();
|
||||||
|
set(s, sq.x(), sq.y(), '+');
|
||||||
|
set(s, sq.x() + n - 1, sq.y(), '+');
|
||||||
|
set(s, sq.x(), sq.y() + n - 1, '+');
|
||||||
|
set(s, sq.x() + n - 1, sq.y() + n - 1, '+');
|
||||||
|
for (int i = 1; i < n - 1; ++i) {
|
||||||
|
set(s, sq.x() + i, sq.y(), '-');
|
||||||
|
set(s, sq.x() + i, sq.y() + n - 1, '-');
|
||||||
|
set(s, sq.x(), sq.y() + i, '|');
|
||||||
|
for (int j = 1; j < n - 1; ++j) {
|
||||||
|
set(s, sq.x() + j, sq.y() + i, ' ');
|
||||||
|
}
|
||||||
|
set(s, sq.x() + n - 1, sq.y() + i, '|');
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = sq.x() + n - 1;
|
||||||
|
while (n != 0) {
|
||||||
|
set(s, --i, sq.y() + 1, '0' + (n % 10));
|
||||||
|
n /= 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int length_;
|
||||||
|
std::vector<Square> squares_;
|
||||||
|
};
|
||||||
|
|
||||||
/** An N * N grid of characters. */
|
/** An N * N grid of characters. */
|
||||||
struct Grid {
|
struct Grid {
|
||||||
/** Construct a grid of given side-length. */
|
/** Construct a grid of given side-length. */
|
||||||
@@ -94,22 +166,6 @@ namespace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto prettify() noexcept -> void {
|
|
||||||
for (auto idx = 0; idx < grid_.size(); ++idx) {
|
|
||||||
if (grid_[idx] < 32) {
|
|
||||||
auto const pos = std::make_pair(idx % length_, idx / length_);
|
|
||||||
prettify_sq(Square(pos, grid_[idx]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Output the grid. */
|
|
||||||
auto output() const -> void {
|
|
||||||
for (auto idx = 0; idx < length_ * length_; idx += length_) {
|
|
||||||
std::cout << std::string_view(grid_.data() + idx, length_) << '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief Get length of the largest square that fits at \a pos in the grid.
|
/** \brief Get length of the largest square that fits at \a pos in the grid.
|
||||||
*/
|
*/
|
||||||
auto largest_square(Pos const &pos, int n) const noexcept -> int {
|
auto largest_square(Pos const &pos, int n) const noexcept -> int {
|
||||||
@@ -147,39 +203,6 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
auto prettify_sq(Square const &sq) noexcept -> void {
|
|
||||||
switch (sq.length()) {
|
|
||||||
case 1: set(sq.x(), sq.y(), '*');
|
|
||||||
break;
|
|
||||||
case 2: set(sq.x(), sq.y(), '+');
|
|
||||||
set(sq.x() + 1, sq.y(), '+');
|
|
||||||
set(sq.x(), sq.y() + 1, '+');
|
|
||||||
set(sq.x() + 1, sq.y() + 1, '+');
|
|
||||||
break;
|
|
||||||
default: {
|
|
||||||
auto n = sq.length();
|
|
||||||
set(sq.x(), sq.y(), '+');
|
|
||||||
set(sq.x() + n - 1, sq.y(), '+');
|
|
||||||
set(sq.x(), sq.y() + n - 1, '+');
|
|
||||||
set(sq.x() + n - 1, sq.y() + n - 1, '+');
|
|
||||||
for (int i = 1; i < n - 1; ++i) {
|
|
||||||
set(sq.x() + i, sq.y(), '-');
|
|
||||||
set(sq.x() + i, sq.y() + n - 1, '-');
|
|
||||||
set(sq.x(), sq.y() + i, '|');
|
|
||||||
for (int j = 1; j < n - 1; ++j) {
|
|
||||||
set(sq.x() + j, sq.y() + i, ' ');
|
|
||||||
}
|
|
||||||
set(sq.x() + n - 1, sq.y() + i, '|');
|
|
||||||
}
|
|
||||||
|
|
||||||
int i = sq.x() + n - 1;
|
|
||||||
while (n != 0) {
|
|
||||||
set(--i, sq.y() + 1, '0' + (n % 10));
|
|
||||||
n /= 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set the grid position (x, y) to the character c.
|
/** Set the grid position (x, y) to the character c.
|
||||||
*
|
*
|
||||||
@@ -209,7 +232,7 @@ namespace {
|
|||||||
*
|
*
|
||||||
* Returns the grid of the solution.
|
* Returns the grid of the solution.
|
||||||
*/
|
*/
|
||||||
auto find_solution(int const n) noexcept -> Grid {
|
auto find_solution(int const n) noexcept -> Results {
|
||||||
/* Implementation is iterative, as opposed to recursive.
|
/* Implementation is iterative, as opposed to recursive.
|
||||||
*
|
*
|
||||||
* The recursive implementation is easier to understand - but is
|
* The recursive implementation is easier to understand - but is
|
||||||
@@ -277,8 +300,7 @@ namespace {
|
|||||||
if (x(pos) == 0 && y(pos) == grid.length()) { break; }
|
if (x(pos) == 0 && y(pos) == grid.length()) { break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
grid.prettify();
|
return Results(length, sqs);
|
||||||
return grid;
|
|
||||||
}
|
}
|
||||||
} // anon namespace
|
} // anon namespace
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user