From 6e82a377c44b78a4b496f59ea4f8ea0f999e0129 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Wed, 21 Dec 2022 10:47:13 +0000 Subject: [PATCH] Add solutions for 2018 day 6 --- 2018/puzzle-06-01.cc | 120 +++++++++++++++++++++++++++++++++++++++++++ 2018/puzzle-06-02.cc | 85 ++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 2018/puzzle-06-01.cc create mode 100644 2018/puzzle-06-02.cc diff --git a/2018/puzzle-06-01.cc b/2018/puzzle-06-01.cc new file mode 100644 index 0000000..f655a9a --- /dev/null +++ b/2018/puzzle-06-01.cc @@ -0,0 +1,120 @@ +// +// Created by Matthew Gretton-Dann on 01/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using Point = std::pair; + +struct PointCompare +{ + auto operator()(Point const& lhs, Point const& rhs) const noexcept -> bool + { + if (lhs.first < rhs.first) { + return true; + } + if (lhs.first > rhs.first) { + return false; + } + return lhs.second < rhs.second; + } +}; + +using PointMap = std::map; + +using namespace std::string_literals; + +auto manhattan_distance(Point const& l, Point const& r) -> Int +{ + return std::abs(l.first - r.first) + std::abs(l.second - r.second); +} + +template +auto find_closest(iterator begin, iterator end, Point const& pt) -> iterator +{ + iterator closest{end}; + Int min_distance{std::numeric_limits::max()}; + for (; begin != end; ++begin) { + auto dist{manhattan_distance(begin->first, pt)}; + if (dist < min_distance) { + min_distance = dist; + closest = begin; + } + else if (dist == min_distance) { + closest = end; + } + } + + return closest; +} + +auto main() -> int +{ + std::string line; + PointMap point_map; + Point max(0, 0); + std::regex const re{"(\\d+), (\\d+)"}; + + // Read data + while (std::getline(std::cin, line)) { + std::smatch m; + if (!std::regex_match(line, m, re)) { + std::cerr << "Unable to interpret: " << line << "\n"; + return EXIT_FAILURE; + } + Point const pt(std::stoull(m.str(1)), std::stoull(m.str(2))); + point_map.insert({pt, 0}); + max.first = std::max(max.first, pt.first); + max.second = std::max(max.second, pt.second); + } + + // Examine each point within the grid. + for (Int x{1}; x <= max.first; ++x) { + for (Int y{1}; y <= max.second; ++y) { + auto closest_point = find_closest(point_map.begin(), point_map.end(), Point(x, y)); + if (closest_point != point_map.end()) { + closest_point->second += 1; + } + } + } + + // Now do the top & bottom edges to detect infinities. + for (Int x{0}; x <= max.first; ++x) { + auto closest_point = find_closest(point_map.begin(), point_map.end(), Point(x, 0)); + if (closest_point != point_map.end()) { + closest_point->second = 0; + } + closest_point = find_closest(point_map.begin(), point_map.end(), Point(x, max.second + 1)); + if (closest_point != point_map.end()) { + closest_point->second = 0; + } + } + + // Now do the left & right edges to detect infinities. + for (Int y{0}; y <= max.second; ++y) { + auto closest_point = find_closest(point_map.begin(), point_map.end(), Point(0, y)); + if (closest_point != point_map.end()) { + closest_point->second = 0; + } + closest_point = find_closest(point_map.begin(), point_map.end(), Point(max.first, y)); + if (closest_point != point_map.end()) { + closest_point->second = 0; + } + } + + // Find maximum size. + auto closest_size{ + std::max_element(point_map.begin(), point_map.end(), + [](auto const& l, auto const& r) { return l.second < r.second; })}; + std::cout << "Point: " << closest_size->first.first << ", " << closest_size->first.second << "\n"; + std::cout << "Safe size: " << closest_size->second << "\n"; + return EXIT_SUCCESS; +} diff --git a/2018/puzzle-06-02.cc b/2018/puzzle-06-02.cc new file mode 100644 index 0000000..d083a26 --- /dev/null +++ b/2018/puzzle-06-02.cc @@ -0,0 +1,85 @@ +// +// Created by Matthew Gretton-Dann on 01/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using Point = std::pair; + +struct PointCompare +{ + auto operator()(Point const& lhs, Point const& rhs) const noexcept -> bool + { + if (lhs.first < rhs.first) { + return true; + } + if (lhs.first > rhs.first) { + return false; + } + return lhs.second < rhs.second; + } +}; + +using PointMap = std::map; + +using namespace std::string_literals; + +auto manhattan_distance(Point const& l, Point const& r) -> Int +{ + return std::abs(l.first - r.first) + std::abs(l.second - r.second); +} + +template +auto within_distance(iterator begin, iterator end, Point const& pt, Int distance) -> bool +{ + auto sum{std::accumulate(begin, end, Int{0}, [pt](Int a, auto const& p) { + return a + manhattan_distance(p.first, pt); + })}; + return sum < distance; +} + +auto main() -> int +{ + std::string line; + PointMap point_map; + Point max(0, 0); + std::regex const re{"(\\d+), (\\d+)"}; + + // Read data + while (std::getline(std::cin, line)) { + std::smatch m; + if (!std::regex_match(line, m, re)) { + std::cerr << "Unable to interpret: " << line << "\n"; + return EXIT_FAILURE; + } + Point const pt(std::stoll(m.str(1)), std::stoll(m.str(2))); + point_map.insert({pt, 0}); + max.first = std::max(max.first, pt.first); + max.second = std::max(max.second, pt.second); + } + + // Examine each point within the grid. We go over the top just to be safe + Int const safe_distance{10'000}; + Int region_size{0}; + for (Int x{max.first - safe_distance - 1}; x <= safe_distance + 1; ++x) { + if (x % 1000 == 0) { + std::cout << "x: " << x << "\n"; + } + for (Int y{max.second - safe_distance - 1}; y <= safe_distance + 1; ++y) { + if (within_distance(point_map.begin(), point_map.end(), Point(x, y), safe_distance)) { + ++region_size; + } + } + } + + std::cout << "Safe size: " << region_size << "\n"; + return EXIT_SUCCESS; +}