From e865b2a5673692cacfd19f99db5f23d854cdd15a Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Mon, 1 Sep 2025 11:42:07 +0200 Subject: [PATCH] Change Grid to use vector not string. This is another optimisation, as it improves memory layout and we are not using a reference counted string. On a M1 Macbook Air this brings runtime for solving the 9 cell down to under 3m30s. Which is about a 15% performance improvement. --- main.cc | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/main.cc b/main.cc index 1cec77c..0ceda9e 100644 --- a/main.cc +++ b/main.cc @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -44,11 +43,11 @@ struct Grid { Grid(int length) : grid_(length * length, '.'), length_(length) { } - Grid(Grid const &other) = default; + Grid(Grid const &other) = delete; Grid(Grid &&other) noexcept = default; - Grid &operator=(Grid const &other) = default; + Grid &operator=(Grid const &other) = delete; Grid &operator=(Grid &&other) noexcept = default; @@ -113,7 +112,8 @@ struct Grid { auto output() const { for (auto i = 0; i < length_; ++i) { - std::cout << grid_.substr(i * length_, length_) << '\n'; + std::cout << + std::string_view(grid_.data() + i * length_, length_) << '\n'; } } @@ -137,6 +137,7 @@ struct Grid { if (grid_[b + y(pos) * length_] != '.') { break; } ++b; } + // Check that this length fits vertically as well. auto len = b - x(pos); auto ye = std::min(y(pos) + len, length_); return ye - y(pos); @@ -146,15 +147,16 @@ struct Grid { * 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_); + auto const b = grid_.begin() + x(pos) + n + y(pos) * length_; + auto const p = std::find(b, grid_.end(), '.'); + if (p == grid_.end()) { + return std::make_pair(0, length_); + } + auto const v = p - grid_.begin(); + return std::make_pair(v % length_, v / length_); } - std::string grid_; + std::vector grid_; int length_; }; @@ -174,6 +176,7 @@ auto find_solution_impl(Grid &grid, int n, Pos const &pos, Avail &avail_sqs) -> * If we know a square of side length N will fit then we know a square of side length * N - 1 will fit. */ + assert(x(pos) + grid.largest_square(pos, n) <= grid.length()); for (auto idx = grid.largest_square(pos, n); idx != 0; --idx) { if (avail_sqs[idx] == 0) { continue; }