#include #include #include #include #include #include #include #include using Folds = std::vector>; class Paper { public: Paper() = default; ~Paper() = default; void addPoint(size_t x, size_t y) { bool resizeX = false; if (y >= _dots.size()) { _dots.resize(y + 1); _height = y + 1; resizeX = true; } if (resizeX || x >= _dots[0].size()) { auto newX = x >= _width ? x + 1 : _width; for (auto &line : _dots) { line.resize(newX); } _width = newX; } _dots[y][x] = true; } void foldY(size_t y) { for (size_t i = 1; i < _height - y; i++) { for (size_t j = 0; j < _width; j++) { if (_dots[y + i][j]) { _dots[y - i][j] = true; } } } _height = y; } void foldX(size_t x) { for (size_t i = 1; i < _width - x; i++) { for (size_t j = 0; j < _height; j++) { if (_dots[j][x + i]) { _dots[j][x - i] = true; } } } _width = x; } void printPaper() { for (size_t i = 0; i < _height; i++) { for (size_t j = 0; j < _width; j++) { std::cout << (_dots[i][j] ? '#' : ' '); } std::cout << std::endl; } std::cout << std::endl; } size_t getDots() { size_t dots = 0; for (size_t i = 0; i < _height; i++) { for (size_t j = 0; j < _width; j++) { if (_dots[i][j]) { dots++; } } } return dots; } private: std::vector> _dots{}; size_t _width; size_t _height; }; std::pair getPaperAndFolds(const std::string &file_name) { Paper paper{}; Folds folds{}; std::ifstream file(file_name); std::string str; bool isFold = false; while (std::getline(file, str)) { if (str.empty()) { isFold = true; continue; } std::stringstream ss(str); if (!isFold) { size_t x, y; char tmp; ss >> x; ss >> tmp; ss >> y; paper.addPoint(x, y); } else { std::string tmp; char tmp_char; bool isX = false; size_t tmp_num; ss >> tmp; ss >> tmp; ss >> tmp_char; if (tmp_char == 'x') { isX = true; } ss >> tmp_char; ss >> tmp_num; folds.emplace_back(isX, tmp_num); } } return { paper, folds }; } uint64_t part1(Paper &paper, Folds &folds, bool print) { if (print) { paper.printPaper(); } if (folds[0].first) { paper.foldX(folds[0].second); } else { paper.foldY(folds[0].second); } if (print) { std::cout << "-----------" << std::endl; paper.printPaper(); } return paper.getDots(); } uint64_t part2(Paper &paper, Folds &folds, bool print) { for (size_t i = 1; i < folds.size(); i++) { if (folds[i].first) { paper.foldX(folds[i].second); } else { paper.foldY(folds[i].second); } if (print) { std::cout << "-----------" << std::endl; paper.printPaper(); } } return paper.getDots(); } int main(int argc, char **argv) { if (argc < 2) { std::cerr << "You must provide input file!" << std::endl; return 1; } auto paper_and_folds = getPaperAndFolds(argv[1]); auto &paper = paper_and_folds.first; auto &folds = paper_and_folds.second; std::cout << "There are \033[91;1m" << std::endl << part1(paper, folds, argc > 2) << "\033[0m dots after the first fold." << std::endl; part2(paper, folds, argc > 2); std::cout << "The resulting code is:" << std::endl << "\033[91;1m"; paper.printPaper(); std::cout << "\033[0m" << std::flush; return 0; }