diff options
author | Clyne Sullivan <clyne@bitgloo.com> | 2022-11-30 19:55:31 -0500 |
---|---|---|
committer | Clyne Sullivan <clyne@bitgloo.com> | 2022-11-30 19:55:31 -0500 |
commit | 8d43e37df99f280377bed90284d6ac2428334804 (patch) | |
tree | 3a5042c9af29da52b4bac38fd78b3ccde77a1dbc /day16/part2.cpp | |
parent | 66ed0b9d27850dc653abc8baa75884f3de311bfa (diff) |
move 2021 days to folder; update README
Diffstat (limited to 'day16/part2.cpp')
-rw-r--r-- | day16/part2.cpp | 131 |
1 files changed, 0 insertions, 131 deletions
diff --git a/day16/part2.cpp b/day16/part2.cpp deleted file mode 100644 index 5a02df9..0000000 --- a/day16/part2.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include <algorithm> -#include <cstdint> -#include <iostream> -#include <list> -#include <map> -#include <string> -#include <string_view> -#include <tuple> - -static const std::map<char, const char *> hexToBin = { - {'0', "0000"}, {'1', "0001"}, {'2', "0010"}, {'3', "0011"}, - {'4', "0100"}, {'5', "0101"}, {'6', "0110"}, {'7', "0111"}, - {'8', "1000"}, {'9', "1001"}, {'A', "1010"}, {'B', "1011"}, - {'C', "1100"}, {'D', "1101"}, {'E', "1110"}, {'F', "1111"} -}; - -static std::pair<uint64_t, std::string_view> solve(std::string_view packet); - -int main(int argc, const char *argv[]) -{ - if (argc != 2) - return -1; - - std::string packetBin; - std::string packetHex (argv[1]); - for (char c : packetHex) - packetBin += hexToBin.at(c); - - std::cout << solve(packetBin).first << std::endl; - - return 0; -} - -uint64_t binStrToInt(std::string_view bin) -{ - uint64_t n = 0; - - for (char c : bin) { - n = n * 2ull; - if (c == '1') - ++n; - } - - return n; -} - -bool isEmptyPacket(std::string_view packet) -{ - return packet.empty() || - std::all_of(packet.cbegin(), packet.cend(), - [](char c) { return c == '0'; }); -} - -std::pair<uint64_t, std::string_view> solve(std::string_view packet) -{ - // Remove version - packet = packet.substr(3); - // Pull type ID - const auto typeId = packet.substr(0, 3); - packet = packet.substr(3); - - if (typeId == "100") { - std::string numberStr; - while (1) { - const auto chunk = packet.substr(0, 5); - packet = packet.substr(5); - numberStr += chunk.substr(1); - if (chunk.front() == '0') - break; - } - - return {binStrToInt(numberStr), isEmptyPacket(packet) ? "" : packet}; - } else { - const bool isLengthBits = packet.front() == '0'; - packet = packet.substr(1); - const auto lengthStr = packet.substr(0, isLengthBits ? 15 : 11); - const auto length = binStrToInt(lengthStr); - packet = packet.substr(isLengthBits ? 15 : 11); - - std::list<uint64_t> args; - if (isLengthBits) { - auto rem = packet.substr(0, length); - while (1) { - const auto ret = solve(rem); - args.emplace_front(ret.first); - if (ret.second.empty() || isEmptyPacket(ret.second)) - break; - rem = ret.second; - } - packet = packet.substr(length); - } else { - for (uint64_t i = 0; i < length; ++i) { - const auto ret = solve(packet); - args.emplace_front(ret.first); - packet = ret.second; - if (isEmptyPacket(packet)) - break; - } - } - - uint64_t result; - if (typeId == "000") { - result = 0; - for (auto a : args) - result += a; - } else if (typeId == "001") { - result = 1; - for (auto a : args) - result *= a; - } else if (typeId == "010") { - result = *std::min_element(args.cbegin(), args.cend()); - } else if (typeId == "011") { - result = *std::max_element(args.cbegin(), args.cend()); - } else if (typeId == "101") { - const auto a1 = args.back(); - args.pop_back(); - result = args.back() < a1; - } else if (typeId == "110") { - const auto a1 = args.back(); - args.pop_back(); - result = args.back() > a1; - } else if (typeId == "111") { - const auto a1 = args.back(); - args.pop_back(); - result = args.back() == a1; - } - - return {result, isEmptyPacket(packet) ? "" : packet}; - } -} - |