Day13 (I love to over-engineer things)

master
Benjamin Kraft 2 years ago
parent 82bc109ecf
commit 002d023c65
  1. 133
      src/days/13/Day13.cpp
  2. 24
      src/days/13/Day13.h

@ -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();
}
auto pairs = parsePacketPairs();
vector<Packet*> 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::PacketPair> Day13::parsePacketPairs() {
vector<PacketPair> 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<char> 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<Day13::ListPacket*>(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<Day13::IntPacket*>(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<Day13::IntPacket*>(other)){
if (value < intP->value)
return LOWER;
if (value > intP->value)
return HIGHER;
return EQUAL;
}
if (auto* list = dynamic_cast<Day13::ListPacket*>(other)){
auto thisAsList = Day13::ListPacket::FromIntPacket(this);
CompResult result = thisAsList->compare(list);
delete thisAsList;
return result;
}
return EQUAL;
}

@ -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<Packet*> subPackets;
static ListPacket* FromIntPacket(IntPacket*);
};
struct IntPacket : Packet {
CompResult compare(Packet*) override;
int value = 0;
};
typedef pair<Packet*, Packet*> PacketPair;
vector<PacketPair> parsePacketPairs();
protected:
Result Task1() override;

Loading…
Cancel
Save