From 082fa94b8f75a5c2259bed97aabe2534f1bc91e9 Mon Sep 17 00:00:00 2001 From: zvon Date: Sun, 12 Dec 2021 09:09:11 +0100 Subject: [PATCH] 11 --- 11/CMakeLists.txt | 22 ++++++ 11/input | 10 +++ 11/main.cpp | 176 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 11/CMakeLists.txt create mode 100644 11/input create mode 100644 11/main.cpp diff --git a/11/CMakeLists.txt b/11/CMakeLists.txt new file mode 100644 index 0000000..eb79d53 --- /dev/null +++ b/11/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.10) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED True) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +enable_language(CXX) + +project(AoC11) + +if(APPLE) + include_directories(/usr/local/include) + link_directories(/usr/local/lib) +endif() + +if(WIN32) + add_executable(${CMAKE_PROJECT_NAME} WIN32) +else() + add_executable(${CMAKE_PROJECT_NAME}) +endif() + +target_sources(${CMAKE_PROJECT_NAME} + PRIVATE main.cpp + ) diff --git a/11/input b/11/input new file mode 100644 index 0000000..c360afa --- /dev/null +++ b/11/input @@ -0,0 +1,10 @@ +1224346384 +5621128587 +6388426546 +1556247756 +1451811573 +1832388122 +2748545647 +2582877432 +3185643871 +2224876627 diff --git a/11/main.cpp b/11/main.cpp new file mode 100644 index 0000000..06090de --- /dev/null +++ b/11/main.cpp @@ -0,0 +1,176 @@ +#include +#include +#include +#include +#include +#include +#include + +constexpr int flash_threshold = 9; +constexpr int part1_iterations = 100; + +using Point = std::pair; + +class Octopus { +public: + Octopus(int level) : _level(level) {} + + void increaseLevel() { + _level += 1; + if (_level > flash_threshold && _can_explode) { + _can_explode = false; + _exploded = true; + } + } + + void resetIfFlash() { + if (_level > flash_threshold) { + _level = 0; + _can_explode = true; + _exploded = false; + } + } + + std::string printOctopus() const { + if (!_can_explode) { + return "\033[93;1m0\033[0m"; + } + return std::to_string(_level); + } + + bool flashed() const { + return !_can_explode; + } + + bool exploded() { + if (_exploded) { + _exploded = false; + return true; + } + return false; + } + +private: + int _level; + bool _exploded = false; + bool _can_explode = true; +}; + +std::vector> getOctopi(const std::string &file_name) { + std::vector> octopi; + + std::ifstream file(file_name); + std::string str; + while (std::getline(file, str)) { + std::vector line{}; + for (auto &c : str) { + line.emplace_back(c - '0'); + } + octopi.push_back(std::move(line)); + } + return octopi; +} + +std::deque increaseLevels(std::vector> &octopi) { + std::deque exploded{}; + for (int i = 0; i < octopi.size(); i++) { + for (int j = 0; j < octopi[i].size(); j++) { + auto &octopus = octopi[i][j]; + octopus.increaseLevel(); + if (octopus.exploded()) { + exploded.emplace_back(i, j); + } + } + } + return exploded; +} + +void explodeOctopus(std::vector> &octopi, + std::deque &exploded, Point &position) { + for (int i = -1; i < 2; i++) { + for (int j = -1; j < 2; j++) { + if (i == 0 && j == 0) { + continue; + } + auto newI = position.first + i; + auto newJ = position.second + j; + if (newI < 0 || newI >= octopi.size()) { + continue; + } + if (newJ < 0 || newJ >= octopi[newI].size()) { + continue; + } + auto &octopus = octopi[newI][newJ]; + octopus.increaseLevel(); + if (octopus.exploded()) { + exploded.emplace_back(newI, newJ); + } + } + } +} + +void explodeOctopi(std::vector> &octopi, + std::deque &exploded) { + while (!exploded.empty()) { + auto position = exploded.front(); + explodeOctopus(octopi, exploded, position); + exploded.pop_front(); + } +} + +void printOctopi(std::vector> &octopi) { + for (auto &line : octopi) { + for (auto &octopus : line) { + std::cout << octopus.printOctopus(); + } + std::cout << std::endl; + } +} + +uint64_t getFlashesAndReset(std::vector> &octopi) { + uint64_t flashes = 0; + for (auto &line : octopi) { + for (auto &octopus : line) { + if (octopus.flashed()) { + flashes++; + octopus.resetIfFlash(); + } + } + } + return flashes; +} + +uint64_t part1(std::vector> &octopi) { + uint64_t flashes = 0; + for (int i = 0; i < part1_iterations; i++) { + auto exploded = increaseLevels(octopi); + explodeOctopi(octopi, exploded); + flashes += getFlashesAndReset(octopi); + } + return flashes; +} + +uint64_t part2(std::vector> &octopi) { + uint64_t round = part1_iterations; + uint64_t flashes = 0; + while (flashes != octopi.size() * octopi[0].size()) { + auto exploded = increaseLevels(octopi); + explodeOctopi(octopi, exploded); + flashes = getFlashesAndReset(octopi); + round++; + } + return round; +} + +int main(int argc, char **argv) { + if (argc < 2) { + std::cerr << "You must provide input file!" << std::endl; + return 1; + } + auto octopi = getOctopi(argv[1]); + std::cout << "The octopi flashed \033[91;1m" << part1(octopi) + << "\033[0m times." << std::endl; + std::cout << "The octopi syncronize on round \033[91;1m" << part2(octopi) + << "\033[0m." << std::endl; + return 0; +}