From 002d023c65570ab88f36622a71a8c7c74a3c6309 Mon Sep 17 00:00:00 2001 From: Benjamin Kraft Date: Tue, 13 Dec 2022 14:05:48 +0100 Subject: [PATCH] Day13 (I love to over-engineer things) --- src/days/13/Day13.cpp | 133 +++++++++++++++++++++++++++++++++++++++++- src/days/13/Day13.h | 24 ++++++++ 2 files changed, 154 insertions(+), 3 deletions(-) diff --git a/src/days/13/Day13.cpp b/src/days/13/Day13.cpp index 6fd9442..247c0d8 100644 --- a/src/days/13/Day13.cpp +++ b/src/days/13/Day13.cpp @@ -1,9 +1,136 @@ #include "Day13.h" Result Day13::Task1() { - return Day::Task1(); + + auto pairs = parsePacketPairs(); + uint64 sum = 0; + for (size_t i = 0; i < pairs.size(); i++){ + PacketPair p = pairs[i]; + + if (p.first->compare(p.second) == LOWER) + sum += i + 1; + + delete p.first; + delete p.second; + } + + return to_string(sum); } Result Day13::Task2() { - return Day::Task2(); -} \ No newline at end of file + auto pairs = parsePacketPairs(); + vector packets; + for (const auto &p : pairs){ + packets.push_back(p.first); + packets.push_back(p.second); + } + + Packet* firstAdd = Packet::parse("[[2]]"); + Packet* secondAdd = Packet::parse("[[6]]"); + packets.push_back(firstAdd); + packets.push_back(secondAdd); + + std::sort(packets.begin(), packets.end(), [](Packet* p1, Packet* p2){ + return p1->compare(p2) == LOWER; + }); + + size_t index1, index2; + for (size_t i = 0; i < packets.size(); i++){ + Packet* p = packets[i]; + if (p == firstAdd) + index1 = i; + if (p == secondAdd) + index2 = i; + } + + delete firstAdd; + delete secondAdd; + + size_t result = (index1 + 1) * (index2 + 1); + return to_string(result); +} + +vector Day13::parsePacketPairs() { + vector packetPairs; + + for (size_t line = 0; line < input.size(); line += 3){ + Packet* p1 = Packet::parse(input[line]); + Packet* p2 = Packet::parse(input[line + 1]); + packetPairs.emplace_back(p1, p2); + } + + return packetPairs; +} + +Day13::Packet* Day13::Packet::parse(const string &raw) { + if (raw.starts_with('[')){ + auto P = new ListPacket(); + size_t pos = 1; + while (pos < raw.size()){ + size_t startPos = pos; + vector stack; + while ((raw[pos] != ',' || !stack.empty()) && pos < raw.size() - 1){ + char cur = raw[pos++]; + if (cur == '[') stack.push_back(cur); + if (cur == ']') stack.pop_back(); + } + if (pos > startPos) + P->subPackets.push_back(Day13::Packet::parse(raw.substr(startPos, pos - startPos))); + pos++; + } + return P; + } else { + auto P = new IntPacket(); + P->value = stoi(raw); + return P; + } +} + +Day13::CompResult Day13::ListPacket::compare(Day13::Packet *other) { + if (auto* list = dynamic_cast(other)){ + size_t index_left = 0; + size_t index_right = 0; + + while (index_left < subPackets.size() && index_right < list->subPackets.size()){ + CompResult result = subPackets[index_left++]->compare(list->subPackets[index_right++]); + if (result != EQUAL) + return result; + } + if (index_left < subPackets.size()) + return HIGHER; + if (index_right < list->subPackets.size()) + return LOWER; + + return EQUAL; + } + if (auto* intP = dynamic_cast(other)){ + auto otherList = Day13::ListPacket::FromIntPacket(intP); + CompResult result = compare(otherList); + delete otherList; + return result; + } + return EQUAL; +} + +Day13::ListPacket *Day13::ListPacket::FromIntPacket(Day13::IntPacket *intPacket) { + auto P = new Day13::ListPacket(); + P->subPackets.push_back(intPacket); + return P; +} + +Day13::CompResult Day13::IntPacket::compare(Day13::Packet *other) { + if (auto* intP = dynamic_cast(other)){ + if (value < intP->value) + return LOWER; + if (value > intP->value) + return HIGHER; + return EQUAL; + } + if (auto* list = dynamic_cast(other)){ + auto thisAsList = Day13::ListPacket::FromIntPacket(this); + CompResult result = thisAsList->compare(list); + delete thisAsList; + return result; + } + return EQUAL; +} diff --git a/src/days/13/Day13.h b/src/days/13/Day13.h index 141861d..56932bf 100644 --- a/src/days/13/Day13.h +++ b/src/days/13/Day13.h @@ -3,6 +3,30 @@ #include "../../Day.h" class Day13 : public Day { + + enum CompResult {LOWER, HIGHER, EQUAL}; + + struct ListPacket; + struct IntPacket; + + struct Packet { + virtual CompResult compare(Packet* other) { return CompResult::EQUAL; }; + static Packet* parse(const string &raw); + }; + struct ListPacket : Packet { + CompResult compare(Packet*) override; + vector subPackets; + static ListPacket* FromIntPacket(IntPacket*); + }; + struct IntPacket : Packet { + CompResult compare(Packet*) override; + int value = 0; + }; + + typedef pair PacketPair; + + vector parsePacketPairs(); + protected: Result Task1() override;