#include "common/aoc.h" namespace y2016::day10 { enum class Output { Output, Bot }; struct Bot { std::vector inputs; int lowId{-1}; int highId{-1}; Output lowOutput; Output highOutput; }; using Bots = std::map; REGISTER_DAY(2016, Day10, Bots, int); REGISTER_TEST_EXAMPLE(2016, Day10, ExampleInput, 1, 2); REGISTER_TEST(2016, Day10, Input, 1, 47); REGISTER_TEST_EXAMPLE(2016, Day10, ExampleInput, 2, 30); REGISTER_TEST(2016, Day10, Input, 2, 2666); READ_INPUT(input) { std::map map; std::string str; while (getline(input, str)) { std::stringstream ss{str}; if (str[0] == 'v') { int value; int id; ss >> "value" >> value >> "goes to bot " >> id; map[id].inputs.emplace_back(value); } else { int idFrom; int idLow; int idHigh; std::string typeLow; std::string typeHigh; ss >> "bot " >> idFrom >> "gives low to " >> typeLow >> idLow >> "and high to " >> typeHigh >> idHigh; Bot& from = map[idFrom]; from.lowId = idLow; from.highId = idHigh; if (typeLow == "bot") from.lowOutput = Output::Bot; else from.lowOutput = Output::Output; if (typeHigh == "bot") from.highOutput = Output::Bot; else from.highOutput = Output::Output; } } return map; } bool HasInput(const Bot& bot, int input1, int input2) { return bot.inputs.size() == 2 && ((bot.inputs[0] == input1 && bot.inputs[1] == input2) || (bot.inputs[0] == input2 && bot.inputs[1] == input1)); } OUTPUT1(input) { int input1 = isExample ? 5 : 61; int input2 = isExample ? 2 : 17; std::map bots = input; while (true) { for (auto it = bots.begin(); it != bots.end();) { if (HasInput(it->second, input1, input2)) return it->first; if (it->second.inputs.size() == 2) { int low = Helper::Min(it->second.inputs); int high = Helper::Max(it->second.inputs); if (it->second.lowOutput == Output::Bot) { bots[it->second.lowId].inputs.emplace_back(low); if (HasInput(bots[it->second.lowId], input1, input2)) return it->second.lowId; } if (it->second.highOutput == Output::Bot) { bots[it->second.highId].inputs.emplace_back(high); if (HasInput(bots[it->second.highId], input1, input2)) return it->second.highId; } it = bots.erase(it); } else { it++; } } } return -1; } OUTPUT2(input) { std::map outputs; int input1 = isExample ? 5 : 61; int input2 = isExample ? 2 : 17; std::map bots = input; while (!bots.empty()) { for (auto it = bots.begin(); it != bots.end();) { if (it->second.inputs.size() == 2) { int low = Helper::Min(it->second.inputs); int high = Helper::Max(it->second.inputs); if (it->second.lowOutput == Output::Bot) bots[it->second.lowId].inputs.emplace_back(low); else outputs[it->second.lowId] = low; if (it->second.highOutput == Output::Bot) bots[it->second.highId].inputs.emplace_back(high); else outputs[it->second.highId] = high; it = bots.erase(it); } else { it++; } } } return outputs[0] * outputs[1] * outputs[2]; } }