From fd2077171f5b0b1a9f3bb4224865f0d5c84c21ae Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Thu, 14 Dec 2023 15:51:22 +0100 Subject: aoc(2314): Parabolic Reflector Dish --- 2023/14/src/part1.cpp | 41 +++++++++++++ 2023/14/src/part2.cpp | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 2023/14/src/part1.cpp create mode 100644 2023/14/src/part2.cpp (limited to '2023/14/src') diff --git a/2023/14/src/part1.cpp b/2023/14/src/part1.cpp new file mode 100644 index 0000000..c2179b7 --- /dev/null +++ b/2023/14/src/part1.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +std::vector parse(const char* file) +{ + std::vector v; + if (std::ifstream input{ file }; input.is_open()) + { + std::string line; + while (not std::getline(input,line).eof()) + { + v.push_back(std::move(line)); + } + } + return v; +} + +int main(int argc, char* argv[]) +{ + int answer{}; + + auto v = parse(argv[1]); + for (int c = 0; c < v.size(); ++c) + { + int floor = v.size(); + for (int r = 0; r < v.size(); ++r) + { + switch (v[r][c]) + { + case '#': + floor = v.size() - r - 1; + break; + case 'O': + answer += floor--; + } + } + } + std::cout << answer << std::endl; + return 0; +} diff --git a/2023/14/src/part2.cpp b/2023/14/src/part2.cpp new file mode 100644 index 0000000..7765b3f --- /dev/null +++ b/2023/14/src/part2.cpp @@ -0,0 +1,167 @@ +#include +#include +#include +#include + +using Dish = std::vector; +using History = std::vector>; + +constexpr int CYCLES = 1'000'000'000; + +Dish parse(const char* file) +{ + Dish v; + + if (std::ifstream input{ file }; input.is_open()) + { + std::string line; + while (not std::getline(input,line).eof()) + { + v.push_back(std::move(line)); + } + } + + return v; +} + +std::vector encode(const Dish& v) +{ + auto len = v.size(); + std::vector e(len * len, 0); + for (int x = 0; x < len; ++x) + { + for (int y = 0; y < len; ++y) + { + e[x * len + y] = v[x][y] == 'O'; + } + } + return e; +} + +Dish& tilt_north(Dish& v) +{ + for (int c = 0; c < v.size(); ++c) + { + int floor{}; + for (int r = floor; r < v.size(); ++r) + { + switch (v[r][c]) + { + case '#': + floor = r + 1; + break; + case 'O': + v[r][c] = '.'; + v[floor++][c] = 'O'; + } + } + } + return v; +} + +Dish& tilt_south(Dish& v) +{ + for (int c = 0; c < v.size(); ++c) + { + int floor{ static_cast(v.size() - 1) }; + for (int r = floor; r >= 0; --r) + { + switch (v[r][c]) + { + case '#': + floor = r - 1; + break; + case 'O': + v[r][c] = '.'; + v[floor--][c] = 'O'; + } + } + } + return v; +} + +Dish& tilt_west(Dish& v) +{ + for (int r = 0; r < v.size(); ++r) + { + int floor{}; + for (int c = floor; c < v.size(); ++c) + { + switch (v[r][c]) + { + case '#': + floor = c + 1; + break; + case 'O': + v[r][c] = '.'; + v[r][floor++] = 'O'; + } + } + } + return v; +} + +Dish& tilt_east(Dish& v) +{ + for (int r = 0; r < v.size(); ++r) + { + int floor{ static_cast(v.size() - 1) }; + for (int c = floor; c >= 0; --c) + { + switch (v[r][c]) + { + case '#': + floor = c - 1; + break; + case 'O': + v[r][c] = '.'; + v[r][floor--] = 'O'; + } + } + } + return v; +} + +Dish& cycle(Dish& v) +{ + return tilt_east(tilt_south(tilt_west(tilt_north(v)))); +} + +int load(const std::vector& v, int l) +{ + int load{}; + for (int x = 0; x < l; ++x) + { + for (int y = 0; y < l; ++y) + { + load += (l - x) * v[x * l + y]; + } + } + return load; +} + +int dup(History& hist, Dish dish) +{ + auto h = encode(dish); + if (auto found = std::find(hist.cbegin(), hist.cend(), h); found != hist.cend()) + { + return hist.cend() - found; + } + hist.push_back(std::move(h)); + return 0; +} + +int main(int argc, char* argv[]) +{ + auto v = parse(argv[1]); + + History history; + history.push_back(encode(v)); + + int p, np; + for (p = 0; p == 0; p = dup(history, cycle(v))); + np = history.size() - p; + + std::cout << load(history[np + (CYCLES - np) % p], v.size()) << std::endl; + return 0; +} -- cgit v1.2.3