From a1a9c876e6edcdc324316896711273fcd5dcd0ee Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Wed, 10 May 2023 10:36:07 +0200 Subject: [PATCH] =?UTF-8?q?problems(cpp):=20add=20=E2=80=9C59.=20Spiral=20?= =?UTF-8?q?Matrix=20II=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matej Focko --- problems/spiral-matrix-ii.cpp | 102 ++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 problems/spiral-matrix-ii.cpp diff --git a/problems/spiral-matrix-ii.cpp b/problems/spiral-matrix-ii.cpp new file mode 100644 index 0000000..c76e42b --- /dev/null +++ b/problems/spiral-matrix-ii.cpp @@ -0,0 +1,102 @@ +#include +#include +#include + +class Solution { + struct indices { + int x; + int y; + + bool operator==(const indices& other) const = default; + indices& operator+=(const indices& other) { + x += other.x; + y += other.y; + return *this; + } + + friend indices operator+(indices left, const indices& right) { + return left += right; + } + + int& operator[](std::vector>& mat) const { + return mat[y][x]; + } + }; + + struct spiral_indices { + spiral_indices(const std::vector>& matrix) + : x_bounds{-1, static_cast(matrix.size() ? matrix[0].size() : 0)}, + y_bounds{-1, static_cast(matrix.size())} {} + + bool done() const { return !in_bounds(idx); } + + spiral_indices& operator++() { + // update bounds and change the direction if cannot move + if (!in_bounds(idx + d)) { + // change the direction + d = {-d.y, d.x}; + + // get the magnitude of the vector + auto flat_d = d.x + d.y; + + // decide whether we're moving x or y bounds + auto& bounds = d.x ? x_bounds : y_bounds; + if (flat_d > 0) { + bounds.x++; + } else { + bounds.y--; + } + } + + idx += d; + + return *this; + } + + int& operator[](std::vector>& mat) const { + return idx[mat]; + } + + private: + indices idx{0, 0}; + indices d{1, 0}; + indices x_bounds, y_bounds; + + bool in_bounds(const indices& idx) const { + return (x_bounds.x < idx.x && idx.x < x_bounds.y) && + (y_bounds.x < idx.y && idx.y < y_bounds.y); + } + }; + + public: + std::vector> generateMatrix(int n) { + auto length = static_cast(n); + std::vector> spiral{length, std::vector(length, 0)}; + + int i = 1; + for (spiral_indices idx{spiral}; !idx.done(); ++idx) { + idx[spiral] = i++; + } + + return spiral; + } +}; + +int main() { + Solution s; + + assert((s.generateMatrix(0) == std::vector>{})); + assert((s.generateMatrix(1) == std::vector>{{1}})); + assert( + (s.generateMatrix(2) == std::vector>{{1, 2}, {4, 3}})); + + for (auto&& row : s.generateMatrix(3)) { + for (auto x : row) std::cout << x << " "; + std::cout << "\n"; + } + + assert((s.generateMatrix(3) == + std::vector>{{1, 2, 3}, {8, 9, 4}, {7, 6, 5}})); + + return 0; +}