Add 2021 Day 22 puzzles
This commit is contained in:
84
2021/puzzle-22-01.cc
Normal file
84
2021/puzzle-22-01.cc
Normal file
@@ -0,0 +1,84 @@
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
using Int = long;
|
||||
struct Pos
|
||||
{
|
||||
constexpr Pos(Int x, Int y, Int z) : x_(x), y_(y), z_(z) {}
|
||||
[[nodiscard]] constexpr auto x() const noexcept -> Int { return x_; }
|
||||
[[nodiscard]] constexpr auto y() const noexcept -> Int { return y_; }
|
||||
[[nodiscard]] constexpr auto z() const noexcept -> Int { return z_; }
|
||||
|
||||
private:
|
||||
Int x_{0};
|
||||
Int y_{0};
|
||||
Int z_{0};
|
||||
};
|
||||
|
||||
constexpr auto operator==(Pos const& lhs, Pos const& rhs) -> bool
|
||||
{
|
||||
return lhs.x() == rhs.x() && lhs.y() == rhs.y() && lhs.z() == rhs.z();
|
||||
}
|
||||
|
||||
constexpr auto operator<(Pos const& lhs, Pos const& rhs) -> bool
|
||||
{
|
||||
return lhs.x() < rhs.x() ||
|
||||
(lhs.x() == rhs.x() && (lhs.y() < rhs.y() || (lhs.y() == rhs.y() && lhs.z() < rhs.z())));
|
||||
}
|
||||
|
||||
struct State
|
||||
{
|
||||
void set(Pos const& from, Pos const& to) { set(from, to, true); }
|
||||
void clear(Pos const& from, Pos const& to) { set(from, to, false); }
|
||||
[[nodiscard]] constexpr auto size() const noexcept
|
||||
{
|
||||
return std::count(nodes_.begin(), nodes_.end(), true);
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr static Int min_coord{-50};
|
||||
constexpr static Int max_coord{50};
|
||||
constexpr static Int width{max_coord - min_coord + 1};
|
||||
|
||||
void set(Pos const& from, Pos const& to, bool value)
|
||||
{
|
||||
for (auto x{std::max(min_coord, from.x())}; x <= std::min(max_coord, to.x()); ++x) {
|
||||
for (auto y{std::max(min_coord, from.y())}; y <= std::min(max_coord, to.y()); ++y) {
|
||||
for (auto z{std::max(min_coord, from.z())}; z <= std::min(max_coord, to.z()); ++z) {
|
||||
nodes_[(x - min_coord) * width * width + (y - min_coord) * width + (z - min_coord)] =
|
||||
value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::array<bool, (width * width * width)> nodes_{false};
|
||||
};
|
||||
|
||||
auto main() -> int
|
||||
{
|
||||
std::regex re{R"((on|off) x=(-?\d+)..(-?\d+),y=(-?\d+)..(-?\d+),z=(-?\d+)..(-?\d+))"};
|
||||
std::string line;
|
||||
State state;
|
||||
|
||||
while (std::getline(std::cin, line) && !line.empty()) {
|
||||
std::smatch m;
|
||||
if (!std::regex_search(line, m, re)) {
|
||||
std::cout << "Unable to match: " << line << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
Pos from{std::stol(m.str(2)), std::stol(m.str(4)), std::stol(m.str(6))};
|
||||
Pos to{std::stol(m.str(3)), std::stol(m.str(5)), std::stol(m.str(7))};
|
||||
if (m.str(1) == "on") {
|
||||
state.set(from, to);
|
||||
}
|
||||
else {
|
||||
state.clear(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Number lit: " << state.size() << '\n';
|
||||
}
|
131
2021/puzzle-22-02.cc
Normal file
131
2021/puzzle-22-02.cc
Normal file
@@ -0,0 +1,131 @@
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
using Int = std::int64_t;
|
||||
struct Pos
|
||||
{
|
||||
constexpr Pos(Int x, Int y, Int z) : x_(x), y_(y), z_(z) {}
|
||||
[[nodiscard]] constexpr auto x() const noexcept -> Int { return x_; }
|
||||
[[nodiscard]] constexpr auto y() const noexcept -> Int { return y_; }
|
||||
[[nodiscard]] constexpr auto z() const noexcept -> Int { return z_; }
|
||||
|
||||
private:
|
||||
Int x_{0};
|
||||
Int y_{0};
|
||||
Int z_{0};
|
||||
};
|
||||
|
||||
constexpr auto operator==(Pos const& lhs, Pos const& rhs) -> bool
|
||||
{
|
||||
return lhs.x() == rhs.x() && lhs.y() == rhs.y() && lhs.z() == rhs.z();
|
||||
}
|
||||
|
||||
constexpr auto operator<(Pos const& lhs, Pos const& rhs) -> bool
|
||||
{
|
||||
return lhs.x() < rhs.x() ||
|
||||
(lhs.x() == rhs.x() && (lhs.y() < rhs.y() || (lhs.y() == rhs.y() && lhs.z() < rhs.z())));
|
||||
}
|
||||
|
||||
struct State
|
||||
{
|
||||
void add(Pos const& from, Pos const& to, bool set)
|
||||
{
|
||||
x_segments_.push_back(from.x());
|
||||
x_segments_.push_back(to.x() + 1);
|
||||
y_segments_.push_back(from.y());
|
||||
y_segments_.push_back(to.y() + 1);
|
||||
z_segments_.push_back(from.z());
|
||||
z_segments_.push_back(to.z() + 1);
|
||||
instructions_.emplace_back(from, to, set);
|
||||
}
|
||||
|
||||
void calculate()
|
||||
{
|
||||
std::sort(x_segments_.begin(), x_segments_.end());
|
||||
x_segments_.erase(std::unique(x_segments_.begin(), x_segments_.end()), x_segments_.end());
|
||||
std::sort(y_segments_.begin(), y_segments_.end());
|
||||
y_segments_.erase(std::unique(y_segments_.begin(), y_segments_.end()), y_segments_.end());
|
||||
std::sort(z_segments_.begin(), z_segments_.end());
|
||||
z_segments_.erase(std::unique(z_segments_.begin(), z_segments_.end()), z_segments_.end());
|
||||
auto x_size{x_segments_.size()};
|
||||
auto y_size{y_segments_.size()};
|
||||
auto z_size{z_segments_.size()};
|
||||
|
||||
nodes_.resize(x_size * y_size * z_size, false);
|
||||
for (auto const& i : instructions_) {
|
||||
auto xit_begin{std::lower_bound(x_segments_.begin(), x_segments_.end(), std::get<0>(i).x())};
|
||||
auto yit_begin{std::lower_bound(y_segments_.begin(), y_segments_.end(), std::get<0>(i).y())};
|
||||
auto zit_begin{std::lower_bound(z_segments_.begin(), z_segments_.end(), std::get<0>(i).z())};
|
||||
auto xit_end{
|
||||
std::lower_bound(x_segments_.begin(), x_segments_.end(), std::get<1>(i).x() + 1)};
|
||||
auto yit_end{
|
||||
std::lower_bound(y_segments_.begin(), y_segments_.end(), std::get<1>(i).y() + 1)};
|
||||
auto zit_end{
|
||||
std::lower_bound(z_segments_.begin(), z_segments_.end(), std::get<1>(i).z() + 1)};
|
||||
for (auto zit{zit_begin}; zit != zit_end; ++zit) {
|
||||
for (auto yit{yit_begin}; yit != yit_end; ++yit) {
|
||||
for (auto xit{xit_begin}; xit != xit_end; ++xit) {
|
||||
auto x{std::distance(x_segments_.begin(), xit)};
|
||||
auto y{std::distance(y_segments_.begin(), yit)};
|
||||
auto z{std::distance(z_segments_.begin(), zit)};
|
||||
nodes_[z * y_size * x_size + y * x_size + x] = std::get<2>(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr auto size() const noexcept -> Int
|
||||
{
|
||||
Int size{0};
|
||||
auto x_size{x_segments_.size()};
|
||||
auto y_size{y_segments_.size()};
|
||||
|
||||
for (auto zit{z_segments_.begin()}; zit + 1 != z_segments_.end(); ++zit) {
|
||||
for (auto yit{y_segments_.begin()}; yit + 1 != y_segments_.end(); ++yit) {
|
||||
for (auto xit{x_segments_.begin()}; xit + 1 != x_segments_.end(); ++xit) {
|
||||
auto x{std::distance(x_segments_.begin(), xit)};
|
||||
auto y{std::distance(y_segments_.begin(), yit)};
|
||||
auto z{std::distance(z_segments_.begin(), zit)};
|
||||
if (nodes_[z * y_size * x_size + y * x_size + x]) {
|
||||
size += (xit[1] - xit[0]) * (yit[1] - yit[0]) * (zit[1] - zit[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::tuple<Pos, Pos, bool>> instructions_;
|
||||
std::vector<Int> x_segments_;
|
||||
std::vector<Int> y_segments_;
|
||||
std::vector<Int> z_segments_;
|
||||
std::vector<bool> nodes_;
|
||||
};
|
||||
|
||||
auto main() -> int
|
||||
{
|
||||
std::regex re{R"((on|off) x=(-?\d+)..(-?\d+),y=(-?\d+)..(-?\d+),z=(-?\d+)..(-?\d+))"};
|
||||
std::string line;
|
||||
State state;
|
||||
|
||||
while (std::getline(std::cin, line) && !line.empty()) {
|
||||
std::smatch m;
|
||||
if (!std::regex_search(line, m, re)) {
|
||||
std::cout << "Unable to match: " << line << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
Pos from(std::stol(m.str(2)), std::stol(m.str(4)), std::stol(m.str(6)));
|
||||
Pos to(std::stol(m.str(3)), std::stol(m.str(5)), std::stol(m.str(7)));
|
||||
state.add(from, to, m.str(1) == "on");
|
||||
}
|
||||
|
||||
state.calculate();
|
||||
std::cout << "Number lit: " << state.size() << '\n';
|
||||
}
|
Reference in New Issue
Block a user