advent_of_code_2021/10/main.cpp
2021-12-10 10:47:44 +01:00

128 lines
2.8 KiB
C++

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <deque>
uint64_t getIllegalScore(char closer) {
switch (closer) {
case ')':
return 3;
case ']':
return 57;
case '}':
return 1197;
case '>':
return 25137;
}
return 0;
}
uint64_t getCompletionScore(char closer) {
switch (closer) {
case ')':
return 1;
case ']':
return 2;
case '}':
return 3;
case '>':
return 4;
}
return 0;
}
std::vector<std::string> getLines(const std::string &file_name) {
std::vector<std::string> lines;
std::ifstream file(file_name);
std::string str;
while (std::getline(file, str)) {
lines.push_back(str);
}
return lines;
}
char getCloser(char opener) {
switch (opener) {
case '(':
return ')';
case '[':
return ']';
case '{':
return '}';
case '<':
return '>';
}
return '-';
}
bool isOpener(char opener) {
return opener == '(' || opener == '[' || opener == '{' || opener == '<';
}
uint64_t getCompleteScore(std::deque<char> &expected) {
uint64_t score = 0;
while (expected.size() != 0) {
score *= 5;
score += getCompletionScore(expected.back());
expected.pop_back();
}
return score;
}
uint64_t getScore(const std::string &line, bool corrupted) {
std::deque<char> expected{};
for (auto &c : line) {
if (isOpener(c)) {
expected.push_back(getCloser(c));
} else if (expected.back() == c) {
expected.pop_back();
} else {
if (corrupted) {
return getIllegalScore(c);
} else {
return 0;
}
}
}
if (corrupted) {
return 0;
}
return getCompleteScore(expected);
}
uint64_t part1(const std::vector<std::string> &lines) {
uint64_t score = 0;
for (const auto &line : lines) {
score += getScore(line, true);
}
return score;
}
uint64_t part2(const std::vector<std::string> &lines) {
std::vector<uint64_t> scores{};
for (const auto &line : lines) {
auto score = getScore(line, false);
if (score != 0) {
scores.push_back(score);
}
}
std::sort(scores.begin(), scores.end());
return scores[(scores.size() - 1) / 2];
}
int main(int argc, char **argv) {
if (argc < 2) {
std::cerr << "You must provide input file!" << std::endl;
return 1;
}
auto lines = getLines(argv[1]);
std::cout << "There total syntax error score is \033[91;1m" << part1(lines)
<< "\033[0m." << std::endl;
std::cout << "The middle completion score is \033[91;1m" << part2(lines)
<< "\033[0m." << std::endl;
return 0;
}