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/Makefile | 19 +++++ 2023/14/resources/input_small.txt | 10 +++ 2023/14/src/part1.cpp | 41 ++++++++++ 2023/14/src/part2.cpp | 167 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 237 insertions(+) create mode 100644 2023/14/Makefile create mode 100644 2023/14/resources/input_small.txt create mode 100644 2023/14/src/part1.cpp create mode 100644 2023/14/src/part2.cpp diff --git a/2023/14/Makefile b/2023/14/Makefile new file mode 100644 index 0000000..af6a294 --- /dev/null +++ b/2023/14/Makefile @@ -0,0 +1,19 @@ +CXXFLAGS := -std=c++17 +CPPFLAGS := -I../include +EXE := part1 part2 + +.PHONY: all clean configure + +all: $(EXE) + +configure: + bear -- $(MAKE) all + +%.o: %.cpp + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ + +clean: + rm -rf $(EXE) src/*.o compile_commands.json + +%: src/%.o + $(CXX) $^ -o $@ diff --git a/2023/14/resources/input_small.txt b/2023/14/resources/input_small.txt new file mode 100644 index 0000000..5a24dce --- /dev/null +++ b/2023/14/resources/input_small.txt @@ -0,0 +1,10 @@ +O....#.... +O.OO#....# +.....##... +OO.#O....O +.O.....O#. +O.#..O.#.# +..O..#O..O +.......O.. +#....###.. +#OO..#.... 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