#include "common/getinputpath.h" #include #include #include #include #include #include #include #include #include #include int main() { auto data_path = get_input_path(DATA_FOLDER); auto data_size = std::filesystem::file_size(data_path); std::ifstream data_ifstream(data_path); if (!data_ifstream.is_open()) { std::println("Failed to open input file at {}", data_path.string()); return 1; } std::string data{}; data.resize(data_size); data_ifstream.read(data.data(), data_size); long long password_part_1 = 0; // password_part_2 requires a whole different way of parsing data. look for // the next block. { std::vector> data_p1{}; std::stringstream data_ss(data); for (std::string t; std::getline(data_ss, t);) { std::stringstream t_stream(t); std::string word; std::vector words{}; // stringstream >> buffer_string skips all whitespaces (space, tab, \n, // etc.) and overwrites the buffer_string. while (t_stream >> word) { words.push_back(word); } data_p1.push_back(words); } // now, calculations. for (size_t i = 0; i < data_p1[0].size(); ++i) { std::optional subtotal = std::nullopt; std::string operation = data_p1.back()[i]; for (size_t j = 0; j < data_p1.size() - 1; ++j) { if (!subtotal.has_value()) { subtotal = std::stoll(data_p1[j][i]); continue; } switch (operation[0]) { case '+': { subtotal = subtotal.value() + std::stoll(data_p1[j][i]); break; } case '*': { subtotal = subtotal.value() * std::stoll(data_p1[j][i]); break; } } } password_part_1 += subtotal.value(); } } long long password_part_2 = 0; // let's rotate the world { // splitting string by \n std::vector data_p2{}; std::stringstream data_ss(data); for (std::string t; std::getline(data_ss, t);) { data_p2.push_back(t); } // reading it like Japanese hiragana in traditional (vertical, // right-to-left) writing std::vector rotated_data{}; for (long i = data_p2[0].size() - 1; i >= 0; --i) { std::string buffer_string{}; for (size_t j = 0; j < data_p2.size(); ++j) { if (data_p2[j][i] == ' ') { continue; } buffer_string.push_back(data_p2[j][i]); } if (!buffer_string.empty()) { rotated_data.push_back(buffer_string); } } std::vector acc{}; std::vector solutions{}; for (auto number : rotated_data) { char last_character = number.back(); switch (last_character) { case '*': { auto actual_number = number.substr(0, number.size() - 1); acc.push_back(std::stoll(actual_number)); long long solution = std::ranges::fold_left(acc, 1LL, std::multiplies<>()); solutions.push_back(solution); acc = std::vector(); continue; break; } case '+': { auto actual_number = number.substr(0, number.size() - 1); acc.push_back(std::stoll(actual_number)); long long solution = std::ranges::fold_left(acc, 0LL, std::plus<>()); solutions.push_back(solution); acc = std::vector(); continue; break; } } acc.push_back(std::stoll(number)); } password_part_2 = std::ranges::fold_left(solutions, 0LL, std::plus<>()); } std::println("Eureka! {} / {}", password_part_1, password_part_2); return 0; }