Add solution for 2022 day 18

This commit is contained in:
2022-12-18 13:05:59 +00:00
parent 1c2074d074
commit 5d1edaa0a3
2 changed files with 263 additions and 0 deletions

113
2022/puzzle-18-01.cc Normal file
View File

@@ -0,0 +1,113 @@
//
// Created by Matthew Gretton-Dann on 16/12/2022.
//
#include <array>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <regex>
#include <set>
#include <stdexcept>
#include <utility>
#include <vector>
using Int = std::int64_t;
using UInt = std::uint64_t;
using Point3 = std::tuple<UInt, UInt, UInt>;
using namespace std::string_literals;
struct Grid3
{
explicit Grid3(std::size_t size) : size_(size) { map_.resize(size * size * size, false); }
auto point(Point3 const& p) const noexcept -> bool
{
assert(std::get<0>(p) < size_);
assert(std::get<1>(p) < size_);
assert(std::get<2>(p) < size_);
return map_[std::get<0>(p) * size_ * size_ + std::get<1>(p) * size_ + std::get<2>(p)];
}
void point(Point3 const& p, bool v)
{
assert(std::get<0>(p) < size_);
assert(std::get<1>(p) < size_);
assert(std::get<2>(p) < size_);
map_[std::get<0>(p) * size_ * size_ + std::get<1>(p) * size_ + std::get<2>(p)] = v;
}
std::size_t size_;
std::vector<bool> map_;
};
auto main() -> int
{
std::string line;
std::vector<Point3> points;
UInt max{0};
std::regex const re{"(\\d+),(\\d+),(\\d+)"};
while (std::getline(std::cin, line)) {
std::smatch m;
if (!std::regex_search(line, m, re)) {
std::cerr << "Cannot interpret: " << line << "\n";
return EXIT_FAILURE;
}
Point3 pt{std::make_tuple(std::stoull(m.str(1)), std::stoull(m.str(2)), std::stoull(m.str(3)))};
max = std::max(std::get<0>(pt), max);
max = std::max(std::get<1>(pt), max);
max = std::max(std::get<2>(pt), max);
points.push_back(pt);
}
Grid3 grid(max + 2);
for (auto const& pt : points) {
grid.point(pt, true);
}
UInt exposed_sides{0};
for (auto const& pt : points) {
UInt x{std::get<0>(pt)};
UInt y{std::get<1>(pt)};
UInt z{std::get<2>(pt)};
if (x > 0) {
exposed_sides += grid.point(std::make_tuple(x - 1, y, z)) ? 0 : 1;
}
else {
++exposed_sides;
}
exposed_sides += grid.point(std::make_tuple(x + 1, y, z)) ? 0 : 1;
if (y > 0) {
exposed_sides += grid.point(std::make_tuple(x, y - 1, z)) ? 0 : 1;
}
else {
++exposed_sides;
}
exposed_sides += grid.point(std::make_tuple(x, y + 1, z)) ? 0 : 1;
if (z > 0) {
exposed_sides += grid.point(std::make_tuple(x, y, z - 1)) ? 0 : 1;
}
else {
++exposed_sides;
}
exposed_sides += grid.point(std::make_tuple(x, y, z + 1)) ? 0 : 1;
}
std::cout << "Surface area: " << exposed_sides << "\n";
#if 0
for (UInt z{0}; z <= max; ++z) {
std::cout << "\nz = " << z << "\n";
for (UInt y{0}; y <= max; ++y) {
for (UInt x{0}; x <= max; ++x) {
std::cout << (grid.point(std::make_tuple(x, y, z)) ? '#' : ' ');
}
std::cout << "\n";
}
}
#endif
return EXIT_SUCCESS;
}

150
2022/puzzle-18-02.cc Normal file
View File

@@ -0,0 +1,150 @@
//
// Created by Matthew Gretton-Dann on 16/12/2022.
//
#include <array>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <regex>
#include <set>
#include <stdexcept>
#include <utility>
#include <vector>
using Int = std::int64_t;
using UInt = std::uint64_t;
using Point3 = std::tuple<UInt, UInt, UInt>;
using namespace std::string_literals;
struct Grid3
{
explicit Grid3(std::size_t size) : size_(size) { map_.resize(size * size * size, ' '); }
auto point(Point3 const& p) const noexcept -> char
{
assert(std::get<0>(p) < size_);
assert(std::get<1>(p) < size_);
assert(std::get<2>(p) < size_);
return map_[std::get<0>(p) * size_ * size_ + std::get<1>(p) * size_ + std::get<2>(p)];
}
void point(Point3 const& p, char v)
{
assert(std::get<0>(p) < size_);
assert(std::get<1>(p) < size_);
assert(std::get<2>(p) < size_);
map_[std::get<0>(p) * size_ * size_ + std::get<1>(p) * size_ + std::get<2>(p)] = v;
}
std::size_t size_;
std::vector<char> map_;
};
auto main() -> int
{
std::string line;
std::vector<Point3> points;
UInt max{0};
std::regex const re{"(\\d+),(\\d+),(\\d+)"};
char const air{' '};
char const water{'.'};
char const rock{'#'};
while (std::getline(std::cin, line)) {
std::smatch m;
if (!std::regex_search(line, m, re)) {
std::cerr << "Cannot interpret: " << line << "\n";
return EXIT_FAILURE;
}
Point3 pt{std::make_tuple(std::stoull(m.str(1)), std::stoull(m.str(2)), std::stoull(m.str(3)))};
max = std::max(std::get<0>(pt), max);
max = std::max(std::get<1>(pt), max);
max = std::max(std::get<2>(pt), max);
points.push_back(pt);
}
Grid3 grid(max + 2);
// Populate points
for (auto const& pt : points) {
grid.point(pt, rock);
}
// Now fill the grid with water
std::vector<Point3> current_points;
std::vector<Point3> next_points;
next_points.push_back(std::make_tuple(0, 0, 0));
while (!next_points.empty()) {
std::vector<Point3> current_points(std::move(next_points));
next_points.clear();
for (auto const& pt : current_points) {
if (grid.point(pt) == air) {
grid.point(pt, water);
UInt x{std::get<0>(pt)};
UInt y{std::get<1>(pt)};
UInt z{std::get<2>(pt)};
if (x > 0) {
next_points.push_back(std::make_tuple(x - 1, y, z));
}
if (x < grid.size_ - 1) {
next_points.push_back(std::make_tuple(x + 1, y, z));
}
if (y > 0) {
next_points.push_back(std::make_tuple(x, y - 1, z));
}
if (y < grid.size_ - 1) {
next_points.push_back(std::make_tuple(x, y + 1, z));
}
if (z > 0) {
next_points.push_back(std::make_tuple(x, y, z - 1));
}
if (z < grid.size_ - 1) {
next_points.push_back(std::make_tuple(x, y, z + 1));
}
}
}
}
UInt exposed_sides{0};
for (auto const& pt : points) {
UInt x{std::get<0>(pt)};
UInt y{std::get<1>(pt)};
UInt z{std::get<2>(pt)};
if (x > 0) {
exposed_sides += grid.point(std::make_tuple(x - 1, y, z)) == water ? 1 : 0;
}
else {
++exposed_sides;
}
exposed_sides += grid.point(std::make_tuple(x + 1, y, z)) == water ? 1 : 0;
if (y > 0) {
exposed_sides += grid.point(std::make_tuple(x, y - 1, z)) == water ? 1 : 0;
}
else {
++exposed_sides;
}
exposed_sides += grid.point(std::make_tuple(x, y + 1, z)) == water ? 1 : 0;
if (z > 0) {
exposed_sides += grid.point(std::make_tuple(x, y, z - 1)) == water ? 1 : 0;
}
else {
++exposed_sides;
}
exposed_sides += grid.point(std::make_tuple(x, y, z + 1)) == water ? 1 : 0;
}
std::cout << "Surface area: " << exposed_sides << "\n";
for (UInt z{0}; z <= max; ++z) {
std::cout << "\nz = " << z << "\n";
for (UInt y{0}; y <= max; ++y) {
for (UInt x{0}; x <= max; ++x) {
std::cout << grid.point(std::make_tuple(x, y, z));
}
std::cout << "\n";
}
}
return EXIT_SUCCESS;
}