Add solutions for 2018 day 6
This commit is contained in:
120
2018/puzzle-06-01.cc
Normal file
120
2018/puzzle-06-01.cc
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
//
|
||||||
|
// Created by Matthew Gretton-Dann on 01/12/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <numeric>
|
||||||
|
#include <regex>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
using Int = std::int64_t;
|
||||||
|
using Point = std::pair<Int, Int>;
|
||||||
|
|
||||||
|
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<Point, Int, PointCompare>;
|
||||||
|
|
||||||
|
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<typename iterator>
|
||||||
|
auto find_closest(iterator begin, iterator end, Point const& pt) -> iterator
|
||||||
|
{
|
||||||
|
iterator closest{end};
|
||||||
|
Int min_distance{std::numeric_limits<Int>::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;
|
||||||
|
}
|
85
2018/puzzle-06-02.cc
Normal file
85
2018/puzzle-06-02.cc
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
//
|
||||||
|
// Created by Matthew Gretton-Dann on 01/12/2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <numeric>
|
||||||
|
#include <regex>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
using Int = std::int64_t;
|
||||||
|
using Point = std::pair<Int, Int>;
|
||||||
|
|
||||||
|
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<Point, Int, PointCompare>;
|
||||||
|
|
||||||
|
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<typename iterator>
|
||||||
|
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;
|
||||||
|
}
|
Reference in New Issue
Block a user