advent_of_code_2021/20/main.cpp
2022-12-03 13:29:31 +01:00

148 lines
4.4 KiB
C++

#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <array>
class Image {
public:
Image(size_t width, size_t height) {
image.resize(height);
for(auto &x : image) {
x.resize(width);
}
}
Image(const std::vector<std::vector<bool>> &input) : image(std::move(input)) {}
void setPixel(size_t x, size_t y, bool pixel) {
image[y][x] = pixel;
}
bool getPixel(size_t x, size_t y) const {
return image[y][x];
}
void setOutsidePixelState(bool pixel) {
outside = pixel;
}
bool getOutsidePixelState() const {
return outside;
}
size_t getImageWidth() const {
return image[0].size();
}
size_t getImageHeight() const {
return image.size();
}
size_t getLitPixels() const {
size_t pixels = 0;
for(auto &line : image) {
for(auto pixel : line) {
if(pixel) {
pixels++;
}
}
}
return pixels;
}
bool getNewPixel(const std::array<bool, 512> &algorithm, int64_t x, int64_t y) const {
uint16_t index = 0;
for(int y_add = -1; y_add <= 1; y_add++) {
for(int x_add = -1; x_add <= 1; x_add++) {
index <<= 1;
auto new_y = y + y_add;
auto new_x = x + x_add;
if(new_y < 0 || new_x < 0 || new_y >= getImageHeight() || new_x >= getImageWidth()) {
if(getOutsidePixelState()) {
index |= 0b1;
}
} else {
if(getPixel(new_x, new_y)) {
index |= 0b1;
}
}
}
}
return algorithm[index];
}
void printImage() const {
for(auto &line : image) {
for(auto pixel : line) {
std::cout << (pixel ? '#' : '.');
}
std::cout << std::endl;
}
}
private:
bool outside = false;
std::vector<std::vector<bool>> image;
};
std::pair<std::array<bool, 512>, Image> getInput(const std::string &file_name) {
std::ifstream file(file_name);
std::array<bool, 512> algorithm{};
std::vector<std::vector<bool>> image_data{};
int tmp = 0;
std::string str;
std::getline(file, str);
for(size_t i = 0; i < 512; i++) {
if(str[i] == '#') {
algorithm[i] = true;
} else {
algorithm[i] = false;
}
}
std::getline(file, str);
while (std::getline(file, str)) {
image_data.emplace_back();
for(auto &c : str) {
if(c == '#') {
image_data.back().push_back(true);
} else {
image_data.back().push_back(false);
}
}
}
auto image = Image(image_data);
return {algorithm, image};
}
Image applyAlgorithm(const std::array<bool, 512> &algorithm, const Image &startingImage) {
Image newImage(startingImage.getImageWidth() + 2, startingImage.getImageHeight() + 2);
for(int64_t x = 0; x < newImage.getImageWidth(); x++) {
for(int64_t y = 0; y < newImage.getImageHeight(); y++) {
auto startingX = x - 1;
auto startingY = y - 1;
auto nextPixel = startingImage.getNewPixel(algorithm, startingX, startingY);
newImage.setPixel(x, y, nextPixel);
}
}
newImage.setOutsidePixelState(algorithm[startingImage.getOutsidePixelState() ? 511 : 0]);
return newImage;
}
size_t part1(const std::array<bool, 512> &algorithm, Image image) {
for(int i = 0; i < 2; i++) {
image = applyAlgorithm(algorithm, image);
}
return image.getLitPixels();
}
size_t part2(const std::array<bool, 512> &algorithm, Image image) {
for(int i = 0; i < 50; i++) {
image = applyAlgorithm(algorithm, image);
}
return image.getLitPixels();
}
int main(int argc, char **argv) {
if (argc < 2) {
std::cerr << "You must provide input file!" << std::endl;
return 1;
}
auto input = getInput(argv[1]);
std::cout << "There are \033[91;1m" << part1(input.first, input.second)
<< "\033[0m lit pixels after 2 applies." << std::endl;
std::cout << "There are \033[91;1m" << part2(input.first, input.second)
<< "\033[0m window depth increases." << std::endl;
return 0;
}