diff --git a/2018/position.h b/2018/position.h new file mode 100644 index 0000000..301bb53 --- /dev/null +++ b/2018/position.h @@ -0,0 +1,60 @@ +// +// Created by Matthew Gretton-Dann on 14/12/2022. +// + +#ifndef ADVENT_OF_CODE_POSITION_H +#define ADVENT_OF_CODE_POSITION_H + +#include + +template +struct Pos +{ + constexpr Pos() noexcept = default; + constexpr Pos(Int x, Int y) noexcept : x_(x), y_(y) {} + constexpr Pos(Pos const&) noexcept = default; + auto constexpr operator=(Pos const&) noexcept -> Pos& = default; + constexpr Pos(Pos&&) noexcept = default; + auto constexpr operator=(Pos&&) noexcept -> Pos& = default; + constexpr ~Pos() noexcept = default; + + [[nodiscard]] auto constexpr x() const noexcept -> Int { return x_; } + auto constexpr x(Int x) noexcept { x_ = x; } + [[nodiscard]] auto constexpr y() const noexcept -> Int { return y_; } + auto constexpr y(Int y) noexcept { y_ = y; } + + auto constexpr operator+=(Pos const& r) noexcept -> Pos& + { + x_ += r.x_; + y_ += r.y_; + return *this; + } + + auto constexpr operator<=>(Pos const& r) const noexcept -> std::strong_ordering + { + auto result{y_ <=> r.y_}; + if (result == std::strong_ordering::equal) { + result = x_ <=> r.x_; + } + return result; + } + + auto constexpr operator==(Pos const& r) const noexcept -> bool + { + return x_ == r.x_ && y_ == r.y_; + } + +private: + Int x_{0}; + Int y_{0}; +}; + +template +auto operator+(Pos const& x, Pos const& y) noexcept -> Pos +{ + auto z{x}; + z += y; + return y; +} + +#endif // ADVENT_OF_CODE_POSITION_H diff --git a/2018/puzzle-03-01.CMakeLists.txt b/2018/puzzle-03-01.CMakeLists.txt new file mode 100644 index 0000000..5ca56a8 --- /dev/null +++ b/2018/puzzle-03-01.CMakeLists.txt @@ -0,0 +1 @@ +target_sources("${puzzle_name}" PRIVATE 2018/position.h) diff --git a/2018/puzzle-03-01.cc b/2018/puzzle-03-01.cc new file mode 100644 index 0000000..5131af2 --- /dev/null +++ b/2018/puzzle-03-01.cc @@ -0,0 +1,88 @@ +// +// Created by Matthew Gretton-Dann on 01/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include + +#include "position.h" + +using Int = std::int64_t; + +struct Grid +{ + [[nodiscard]] auto width() const noexcept -> Int { return width_; } + [[nodiscard]] auto height() const noexcept -> Int { return static_cast(grid_.size()); } + + auto add_rect(Pos tl, Pos br) + { + for (Int x{std::min(tl.x(), br.x())}; x < std::max(tl.x(), br.x()); ++x) { + for (Int y{std::min(tl.y(), br.y())}; y < std::max(tl.y(), br.y()); ++y) { + incr_point(Pos{x, y}); + } + } + } + + auto double_counted() const noexcept -> Int + { + Int result{0}; + for (auto const& r : grid_) { + for (auto c : r) { + if (c > 1) { + ++result; + } + } + } + return result; + } + +private: + auto incr_point(Pos pos) -> void + { + auto const x{pos.x()}; + auto const y{pos.y()}; + + if (y >= height()) { + grid_.resize(y + 1); + } + if (x >= grid_[y].size()) { + grid_[y].resize(x + 1, 0); + width_ = std::max(width_, x); + } + ++grid_[y][x]; + } + + std::vector> grid_; + Int width_{0}; +}; + +auto main() -> int +{ + std::string line; + Grid grid; + + while (std::getline(std::cin, line)) { + assert(line[0] == '#'); + std::size_t pos{1}; + std::size_t l{0}; + Int const id{std::stoll(line.substr(pos), &l)}; + pos += l + 3; + Int const tlx{std::stoll(line.substr(pos), &l)}; + pos += l + 1; + Int const tly{std::stoll(line.substr(pos), &l)}; + pos += l + 2; + Int const w{std::stoll(line.substr(pos), &l)}; + pos += l + 1; + Int const h{std::stoll(line.substr(pos), &l)}; + grid.add_rect(Pos{tlx, tly}, Pos{tlx + w, tly + h}); + } + + std::cout << "Double counted: " << grid.double_counted() << '\n'; + + return EXIT_SUCCESS; +} diff --git a/2018/puzzle-03-02.CMakeLists.txt b/2018/puzzle-03-02.CMakeLists.txt new file mode 100644 index 0000000..5ca56a8 --- /dev/null +++ b/2018/puzzle-03-02.CMakeLists.txt @@ -0,0 +1 @@ +target_sources("${puzzle_name}" PRIVATE 2018/position.h) diff --git a/2018/puzzle-03-02.cc b/2018/puzzle-03-02.cc new file mode 100644 index 0000000..945f221 --- /dev/null +++ b/2018/puzzle-03-02.cc @@ -0,0 +1,88 @@ +// +// Created by Matthew Gretton-Dann on 01/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "position.h" + +using Int = std::int64_t; + +struct Grid +{ + [[nodiscard]] auto width() const noexcept -> Int { return width_; } + [[nodiscard]] auto height() const noexcept -> Int { return static_cast(grid_.size()); } + + auto add_rect(Pos tl, Pos br, Int value) + { + unique_.insert(value); + for (Int x{std::min(tl.x(), br.x())}; x < std::max(tl.x(), br.x()); ++x) { + for (Int y{std::min(tl.y(), br.y())}; y < std::max(tl.y(), br.y()); ++y) { + set_point(Pos{x, y}, value); + } + } + } + + auto unique() const noexcept -> Int + { + assert(unique_.size() == 1); + return *unique_.begin(); + } + +private: + auto set_point(Pos pos, Int value) -> void + { + auto const x{pos.x()}; + auto const y{pos.y()}; + + if (y >= height()) { + grid_.resize(y + 1); + } + if (x >= grid_[y].size()) { + grid_[y].resize(x + 1, 0); + width_ = std::max(width_, x); + } + if (grid_[y][x] != 0) { + unique_.erase(grid_[y][x]); + unique_.erase(value); + } + grid_[y][x] = value; + } + + std::vector> grid_; + Int width_{0}; + std::set unique_; +}; + +auto main() -> int +{ + std::string line; + Grid grid; + + while (std::getline(std::cin, line)) { + assert(line[0] == '#'); + std::size_t pos{1}; + std::size_t l{0}; + Int const id{std::stoll(line.substr(pos), &l)}; + pos += l + 3; + Int const tlx{std::stoll(line.substr(pos), &l)}; + pos += l + 1; + Int const tly{std::stoll(line.substr(pos), &l)}; + pos += l + 2; + Int const w{std::stoll(line.substr(pos), &l)}; + pos += l + 1; + Int const h{std::stoll(line.substr(pos), &l)}; + grid.add_rect(Pos{tlx, tly}, Pos{tlx + w, tly + h}, id); + } + + std::cout << "Unique: " << grid.unique() << '\n'; + + return EXIT_SUCCESS; +}