#include #include #include #include #include class Bingo { public: Bingo() = default; ~Bingo() = default; void addNumberToCard(int number) { card[numbers / 5][numbers % 5] = { number, false }; numbers += 1; } void checkNumber(int number) { if (hasWon()) { invalidate(); return; } for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (card[i][j].first == number) { card[i][j].second = true; checkWin(number); return; } } } } bool hasWon() { return won; } int getWinningScore() { return winning_score; } void printSelf() { std::cout << std::endl; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (card[i][j].second) { std::cout << "*"; } std::cout << card[i][j].first << " "; } std::cout << std::endl; } std::cout << std::endl; } bool isValid() { return valid; } private: void checkWin(int multiplier) { for (int i = 0; i < 5; i++) { int horizontal = 0; int vertical = 0; for (int j = 0; j < 5; j++) { if (card[i][j].second) { horizontal += 1; } if (card[j][i].second) { vertical += 1; } } if (horizontal == 5 || vertical == 5) { won = true; calculateScore(multiplier); } } } void calculateScore(int multiplier) { int score = 0; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (!card[i][j].second) { score += card[i][j].first; } } } winning_score = score * multiplier; } void invalidate() { valid = false; } std::array, 5>, 5> card; int numbers = 0; bool won = false; int winning_score = -1; bool valid = true; }; std::pair, std::vector> getBingo(const std::string &file_name) { std::pair, std::vector> result; std::ifstream file(file_name); int tmp{}; char tmp_char{}; std::string str; std::getline(file, str); std::stringstream ss(str); while (ss >> tmp) { result.first.push_back(tmp); ss >> tmp_char; } while (std::getline(file, str)) { if (str.empty()) { result.second.emplace_back(); continue; } std::stringstream ss2(str); for (int i = 0; i < 5; i++) { ss2 >> tmp; result.second.back().addNumberToCard(tmp); } } return result; } int part1(const std::vector &numbers, std::vector &bingo) { for (auto &number : numbers) { for (auto &card : bingo) { card.checkNumber(number); if (card.hasWon()) { return card.getWinningScore(); } } } return -1; } int part2(const std::vector &numbers, std::vector &bingo) { int last_score = -1; for (auto &number : numbers) { for (auto &card : bingo) { card.checkNumber(number); if (card.hasWon() && card.isValid()) { last_score = card.getWinningScore(); } } } return last_score; } int main(int argc, char **argv) { if (argc < 2) { std::cerr << "You must provide input file!" << std::endl; return 1; } auto input = getBingo(argv[1]); auto &numbers = input.first; auto &bingo = input.second; std::cout << "The winning score of the first winning card is \033[91;1m" << part1(numbers, bingo) << "\033[0m." << std::endl; std::cout << "The winning score of the last winning card is \033[91;1m" << part2(numbers, bingo) << "\033[0m." << std::endl; return 0; }