From 041da7b737fc91eba4572b29ce3a9e2564645822 Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Wed, 21 Dec 2022 14:44:55 +0000 Subject: [PATCH] Solutions for 2018 day 10 --- 2018/puzzle-10-01.cc | 99 ++++++++++++++++++++++++++++++++++++++++++++ 2018/puzzle-10-02.cc | 99 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 2018/puzzle-10-01.cc create mode 100644 2018/puzzle-10-02.cc diff --git a/2018/puzzle-10-01.cc b/2018/puzzle-10-01.cc new file mode 100644 index 0000000..70dfe86 --- /dev/null +++ b/2018/puzzle-10-01.cc @@ -0,0 +1,99 @@ +// +// Created by Matthew Gretton-Dann on 01/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using Point = std::pair; + +struct Star +{ + auto time_step() noexcept + { + pos_.first += velocity_.first; + pos_.second += velocity_.second; + } + Point pos_; + Point velocity_; +}; + +using Stars = std::vector; + +auto vert_dist(Stars const& stars) +{ + auto [min, max] = + std::minmax_element(stars.begin(), stars.end(), + [](auto const& l, auto const& r) { return l.pos_.second < r.pos_.second; }); + return max->pos_.second - min->pos_.second; +} + +auto main() -> int +{ + std::string line; + std::regex const re{R"(position=<\s*(-?\d+),\s*(-?\d+)> velocity=<\s*(-?\d+),\s*(-?\d+)>)"}; + + Stars stars; + 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; + } + + Star star; + star.pos_.first = std::stoll(m.str(1)); + star.pos_.second = std::stoll(m.str(2)); + star.velocity_.first = std::stoll(m.str(3)); + star.velocity_.second = std::stoll(m.str(4)); + stars.push_back(star); + } + + auto range{vert_dist(stars)}; + auto old_range{range + 1}; + Stars old_stars; + Int time{-1}; + + // We continue until the vertical range starts getting bigger. + while (range < old_range) { + old_range = range; + old_stars = stars; + for (auto& star : stars) { + star.time_step(); + } + range = vert_dist(stars); + ++time; + } + + // We want to use the smallest star set. + stars = old_stars; + auto [min_x_elt, max_x_elt] = + std::minmax_element(stars.begin(), stars.end(), + [](auto const& l, auto const& r) { return l.pos_.first < r.pos_.first; }); + auto [min_y_elt, max_y_elt] = + std::minmax_element(stars.begin(), stars.end(), + [](auto const& l, auto const& r) { return l.pos_.second < r.pos_.second; }); + auto min_x{min_x_elt->pos_.first}; + auto max_x{max_x_elt->pos_.first}; + auto min_y{min_y_elt->pos_.second}; + auto max_y{max_y_elt->pos_.second}; + std::vector strings(max_y - min_y + 1); + for (auto& s : strings) { + s.resize(max_x - min_x + 1, ' '); + } + for (auto const& star : stars) { + strings.at(star.pos_.second - min_y).at(star.pos_.first - min_x) = '#'; + } + for (auto const& s : strings) { + std::cout << s << "\n"; + } + std::cout <<"In " << time << " seconds.\n"; + + return EXIT_SUCCESS; +} diff --git a/2018/puzzle-10-02.cc b/2018/puzzle-10-02.cc new file mode 100644 index 0000000..70dfe86 --- /dev/null +++ b/2018/puzzle-10-02.cc @@ -0,0 +1,99 @@ +// +// Created by Matthew Gretton-Dann on 01/12/2022. +// + +#include +#include +#include +#include +#include +#include +#include + +using Int = std::int64_t; +using Point = std::pair; + +struct Star +{ + auto time_step() noexcept + { + pos_.first += velocity_.first; + pos_.second += velocity_.second; + } + Point pos_; + Point velocity_; +}; + +using Stars = std::vector; + +auto vert_dist(Stars const& stars) +{ + auto [min, max] = + std::minmax_element(stars.begin(), stars.end(), + [](auto const& l, auto const& r) { return l.pos_.second < r.pos_.second; }); + return max->pos_.second - min->pos_.second; +} + +auto main() -> int +{ + std::string line; + std::regex const re{R"(position=<\s*(-?\d+),\s*(-?\d+)> velocity=<\s*(-?\d+),\s*(-?\d+)>)"}; + + Stars stars; + 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; + } + + Star star; + star.pos_.first = std::stoll(m.str(1)); + star.pos_.second = std::stoll(m.str(2)); + star.velocity_.first = std::stoll(m.str(3)); + star.velocity_.second = std::stoll(m.str(4)); + stars.push_back(star); + } + + auto range{vert_dist(stars)}; + auto old_range{range + 1}; + Stars old_stars; + Int time{-1}; + + // We continue until the vertical range starts getting bigger. + while (range < old_range) { + old_range = range; + old_stars = stars; + for (auto& star : stars) { + star.time_step(); + } + range = vert_dist(stars); + ++time; + } + + // We want to use the smallest star set. + stars = old_stars; + auto [min_x_elt, max_x_elt] = + std::minmax_element(stars.begin(), stars.end(), + [](auto const& l, auto const& r) { return l.pos_.first < r.pos_.first; }); + auto [min_y_elt, max_y_elt] = + std::minmax_element(stars.begin(), stars.end(), + [](auto const& l, auto const& r) { return l.pos_.second < r.pos_.second; }); + auto min_x{min_x_elt->pos_.first}; + auto max_x{max_x_elt->pos_.first}; + auto min_y{min_y_elt->pos_.second}; + auto max_y{max_y_elt->pos_.second}; + std::vector strings(max_y - min_y + 1); + for (auto& s : strings) { + s.resize(max_x - min_x + 1, ' '); + } + for (auto const& star : stars) { + strings.at(star.pos_.second - min_y).at(star.pos_.first - min_x) = '#'; + } + for (auto const& s : strings) { + std::cout << s << "\n"; + } + std::cout <<"In " << time << " seconds.\n"; + + return EXIT_SUCCESS; +}