diff --git a/2016/puzzle-10-01.cc b/2016/puzzle-10-01.cc new file mode 100644 index 0000000..d3955f8 --- /dev/null +++ b/2016/puzzle-10-01.cc @@ -0,0 +1,132 @@ +// +// Created by Matthew Gretton-Dann on 05/12/2021. +// + +#include +#include +#include +#include +#include + +struct Bot +{ + void receive(unsigned long v) // NOLINT(google-runtime-int) + { + assert(!is_full()); + values_.emplace_back(v); + } + + void clear() { values_.clear(); } + + [[nodiscard]] auto is_full() const noexcept -> bool { return values_.size() == 2; } + + [[nodiscard]] auto low_value() const noexcept -> unsigned + { + assert(is_full()); + return *std::min_element(values_.begin(), values_.end()); + } + + [[nodiscard]] auto high_value() const noexcept -> unsigned + { + assert(is_full()); + return *std::max_element(values_.begin(), values_.end()); + } + +private: + std::vector values_; +}; + +enum class Destination { bot, output }; + +auto to_destination(std::string const& s) -> Destination +{ + if (s == "bot") { + return Destination::bot; + } + if (s == "output") { + return Destination::output; + } + abort(); +} + +struct Action +{ + unsigned long id_; + Destination low_dest_type_; + unsigned long low_dest_id_; + Destination high_dest_type_; + unsigned long high_dest_id_; +}; + +auto main() -> int +{ + static std::regex value_action{"value (\\d+) goes to bot (\\d+)"}; + static std::regex bot_action{R"(bot (\d+) gives low to (.+) (\d+) and high to (.+) (\d+))"}; + std::vector bots; + std::vector outputs; + std::vector actions; + std::string line; + while (std::getline(std::cin, line)) { + std::smatch m; + if (std::regex_search(line, m, value_action)) { + auto value{std::stoul(m.str(1))}; + auto bot{std::stoul(m.str(2))}; + if (bot >= bots.size()) { + bots.resize(bot + 1); + } + bots.at(bot).receive(value); + } + else if (std::regex_search(line, m, bot_action)) { + auto bot{std::stoul(m.str(1))}; + auto low_type{to_destination(m.str(2))}; + auto low_id{std::stoul(m.str(3))}; + auto high_type{to_destination(m.str(4))}; + auto high_id{std::stoul(m.str(5))}; + if (bot >= bots.size()) { + bots.resize(bot + 1); + } + if (low_type == Destination::output && low_id >= outputs.size()) { + outputs.resize(low_id + 1); + } + if (high_type == Destination::output && high_id >= outputs.size()) { + outputs.resize(high_id + 1); + } + actions.push_back(Action{bot, low_type, low_id, high_type, high_id}); + } + else { + std::cerr << "Unable to interpret: " << line << '\n'; + return 1; + } + } + + for (std::size_t i{0}; i < outputs.size(); ++i) { + outputs[i] = 0; + } + + while (true) { + for (auto action : actions) { + auto& bot{bots.at(action.id_)}; + if (!bot.is_full()) { + continue; + } + if (bot.low_value() == 17 && bot.high_value() == 61) { + std::cout << "Result: " << action.id_ << '\n'; + return 0; + } + + if (action.low_dest_type_ == Destination::bot) { + bots.at(action.low_dest_id_).receive(bot.low_value()); + } + else { + outputs.at(action.low_dest_id_) = bot.low_value(); + } + if (action.high_dest_type_ == Destination::bot) { + bots.at(action.high_dest_id_).receive(bot.high_value()); + } + else { + outputs.at(action.high_dest_id_) = bot.high_value(); + } + bot.clear(); + } + } +} \ No newline at end of file diff --git a/2016/puzzle-10-02.cc b/2016/puzzle-10-02.cc new file mode 100644 index 0000000..7f056e4 --- /dev/null +++ b/2016/puzzle-10-02.cc @@ -0,0 +1,130 @@ +// +// Created by Matthew Gretton-Dann on 05/12/2021. +// + +#include +#include +#include +#include +#include + +struct Bot +{ + void receive(unsigned long v) // NOLINT(google-runtime-int) + { + assert(!is_full()); + values_.emplace_back(v); + } + + void clear() { values_.clear(); } + + [[nodiscard]] auto is_full() const noexcept -> bool { return values_.size() == 2; } + + [[nodiscard]] auto low_value() const noexcept -> unsigned + { + assert(is_full()); + return *std::min_element(values_.begin(), values_.end()); + } + + [[nodiscard]] auto high_value() const noexcept -> unsigned + { + assert(is_full()); + return *std::max_element(values_.begin(), values_.end()); + } + +private: + std::vector values_; +}; + +enum class Destination { bot, output }; + +auto to_destination(std::string const& s) -> Destination +{ + if (s == "bot") { + return Destination::bot; + } + if (s == "output") { + return Destination::output; + } + abort(); +} + +struct Action +{ + unsigned long id_; + Destination low_dest_type_; + unsigned long low_dest_id_; + Destination high_dest_type_; + unsigned long high_dest_id_; +}; + +auto main() -> int +{ + static std::regex value_action{"value (\\d+) goes to bot (\\d+)"}; + static std::regex bot_action{R"(bot (\d+) gives low to (.+) (\d+) and high to (.+) (\d+))"}; + std::vector bots; + std::vector outputs; + std::vector actions; + std::string line; + while (std::getline(std::cin, line)) { + std::smatch m; + if (std::regex_search(line, m, value_action)) { + auto value{std::stoul(m.str(1))}; + auto bot{std::stoul(m.str(2))}; + if (bot >= bots.size()) { + bots.resize(bot + 1); + } + bots.at(bot).receive(value); + } + else if (std::regex_search(line, m, bot_action)) { + auto bot{std::stoul(m.str(1))}; + auto low_type{to_destination(m.str(2))}; + auto low_id{std::stoul(m.str(3))}; + auto high_type{to_destination(m.str(4))}; + auto high_id{std::stoul(m.str(5))}; + if (bot >= bots.size()) { + bots.resize(bot + 1); + } + if (low_type == Destination::output && low_id >= outputs.size()) { + outputs.resize(low_id + 1); + } + if (high_type == Destination::output && high_id >= outputs.size()) { + outputs.resize(high_id + 1); + } + actions.push_back(Action{bot, low_type, low_id, high_type, high_id}); + } + else { + std::cerr << "Unable to interpret: " << line << '\n'; + return 1; + } + } + + for (std::size_t i{0}; i < outputs.size(); ++i) { + outputs[i] = 0; + } + + while (outputs[0] == 0 || outputs[1] == 0 || outputs[2] == 0) { + for (auto action : actions) { + auto& bot{bots.at(action.id_)}; + if (!bot.is_full()) { + continue; + } + + if (action.low_dest_type_ == Destination::bot) { + bots.at(action.low_dest_id_).receive(bot.low_value()); + } + else { + outputs.at(action.low_dest_id_) = bot.low_value(); + } + if (action.high_dest_type_ == Destination::bot) { + bots.at(action.high_dest_id_).receive(bot.high_value()); + } + else { + outputs.at(action.high_dest_id_) = bot.high_value(); + } + bot.clear(); + } + } + + std::cout << "Result: " << outputs[0] * outputs[1] * outputs[2] << '\n'; +} \ No newline at end of file