From d7b1290379853b250185f180a67832c437f792f8 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Mon, 1 Sep 2025 11:00:56 +0200 Subject: [PATCH] Optimize selection of next position. Grid::next_pos was starting its scan from the position after the current one. This is inefficient as we know how large the square we've just placed is as we scan those positions. This optimisation just skips that square when starting the scan. --- main.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/main.cc b/main.cc index 0be0146..8046875 100644 --- a/main.cc +++ b/main.cc @@ -140,14 +140,16 @@ struct Grid { return b - x(pos); } - auto next_pos(Pos const &pos) const noexcept -> Pos { - if (const auto p = x(pos) + 1 + y(pos) * length_; p >= grid_.size()) { return std::make_pair(0, length_); } else { + /** Get the next position to check. n is the size of the square we just + * added. + */ + auto next_pos(Pos const &pos, int n) const noexcept -> Pos { + const auto p = x(pos) + n + y(pos) * length_; const auto next_p = grid_.find('.', p); if (next_p == std::string::npos) { return std::make_pair(0, length_); } return std::make_pair(next_p % length_, next_p / length_); - } } std::string grid_; @@ -176,7 +178,7 @@ auto find_solution_impl(Grid &grid, int n, Pos const &pos, Avail &avail_sqs) -> auto const sq = Square(pos, idx); --avail_sqs[idx]; grid.add(sq); - if (find_solution_impl(grid, n, grid.next_pos(pos), avail_sqs)) { return true; } + if (find_solution_impl(grid, n, grid.next_pos(pos, idx), avail_sqs)) { return true; } ++avail_sqs[idx]; grid.clear(sq); }