173 lines
4.2 KiB
C++
173 lines
4.2 KiB
C++
|
#include <algorithm>
|
||
|
#include <deque>
|
||
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
#include <sstream>
|
||
|
#include <unordered_map>
|
||
|
#include <unordered_set>
|
||
|
#include <vector>
|
||
|
|
||
|
using Folds = std::vector<std::pair<bool, size_t>>;
|
||
|
|
||
|
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<std::vector<bool>> _dots{};
|
||
|
size_t _width;
|
||
|
size_t _height;
|
||
|
};
|
||
|
|
||
|
std::pair<Paper, Folds> 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;
|
||
|
}
|