From bd25a86f9eaa5680e74c283d9a7e135f9d0b0405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20M=C3=A5rdbrink?= Date: Sun, 8 Dec 2024 18:11:50 +0100 Subject: [PATCH] Day 8 --- d08/main.cxx | 171 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 165 insertions(+), 6 deletions(-) diff --git a/d08/main.cxx b/d08/main.cxx index 2b56230..24b3d8a 100644 --- a/d08/main.cxx +++ b/d08/main.cxx @@ -1,15 +1,174 @@ #include -#include +#include +#include +#include +#include +#include +#include +#include using std::cout, std::endl; -int main() { - std::ifstream file{"../d8/input.txt"}; +constexpr const char content[] = { + #embed "input.txt" +}; + +bool position_in_bounds(int x, int y, int max_x, int max_y) { + return x >= 0 && x <= max_x && y >= 0 && y <= max_y; +} + +namespace std { + template <> + struct hash> { + std::size_t operator()(const std::pair& p) const { + auto h1 = std::hash{}(p.first); + auto h2 = std::hash{}(p.second); + return h1 ^ (h2 << 1); + } + }; +} + +void get_antinodes(std::unordered_set>& antinodes, std::pair a1, std::pair a2, int max_x, int max_y) { + auto [x1, y1] = a1; + auto [x2, y2] = a2; + auto dx = x2 - x1; + auto dy = y2 - y1; + + auto gcd = std::gcd(dx, dy); + dx /= gcd; + dy /= gcd; + + auto x_fst = x1 - dx; + auto y_fst = y1 - dy; + if(position_in_bounds(x_fst, y_fst, max_x, max_y)) { + antinodes.insert({x_fst, y_fst}); + } + + auto x_snd = x2 + dx; + auto y_snd = y2 + dy; + if(position_in_bounds(x_snd, y_snd, max_x, max_y)) { + antinodes.insert({x_snd, y_snd}); + } +} + +int part_1() { + std::istringstream input_stream(content); + std::string line; + std::unordered_map>> frequencies_map; + + auto row{0}, col{0}; + while (std::getline(input_stream, line)) { + if(line.empty()) { + continue; + } + std::istringstream line_stream(line); + char frequency; + col = 0; + while (line_stream >> frequency) { + if(frequency != '.') { + if(frequencies_map.find(frequency) == frequencies_map.end()) { + frequencies_map[frequency] = {}; + } + frequencies_map[frequency].emplace_back(row, col); + } + col++; + } + row++; + } + int max_x = row - 1, max_y = col - 1; + + std::unordered_set> antinodes = {}; + for(auto &[freq, positions] : frequencies_map) { + for(auto &pos_1 : positions) { + for(auto &pos_2 : positions) { + if(pos_1 != pos_2) { + get_antinodes(antinodes, pos_1, pos_2, max_x, max_y); + } + } + } + } + + return antinodes.size(); +} + +void get_all_antinodes(std::unordered_set>& antinodes, std::pair a1, std::pair a2, int max_x, int max_y) { + int num_antinodes{0}; + + auto [x1, y1] = a1; + auto [x2, y2] = a2; + auto dx = x2 - x1; + auto dy = y2 - y1; + + auto gcd = std::gcd(dx, dy); + dx /= gcd; + dy /= gcd; + + auto x_fst = x1 - dx; + auto y_fst = y1 - dy; + while(position_in_bounds(x_fst, y_fst, max_x, max_y)) { + antinodes.insert({x_fst, y_fst}); + x_fst -= dx; + y_fst -= dy; + } + + auto x_snd = x2 + dx; + auto y_snd = y2 + dy; + while(position_in_bounds(x_snd, y_snd, max_x, max_y)) { + antinodes.insert({x_snd, y_snd}); + x_snd += dx; + y_snd += dy; + } +} + +int part_2() { + std::istringstream input_stream(content); std::string line; - while (std::getline(file, line)) { - + std::unordered_map>> frequencies_map; + std::unordered_set> antinodes = {}; + + auto row{0}, col{0}; + while (std::getline(input_stream, line)) { + if(line.empty()) { + continue; + } + std::istringstream line_stream(line); + char frequency; + col = 0; + while (line_stream >> frequency) { + if(frequency != '.') { + if(frequencies_map.find(frequency) == frequencies_map.end()) { + frequencies_map[frequency] = {}; + } + frequencies_map[frequency].emplace_back(row, col); + antinodes.insert({row, col}); + } + col++; + } + row++; + } + int max_x = row - 1, max_y = col - 1; + + for(auto &[freq, positions] : frequencies_map) { + for(auto &pos_1 : positions) { + for(auto &pos_2 : positions) { + if(pos_1 != pos_2) { + get_all_antinodes(antinodes, pos_1, pos_2, max_x, max_y); + } + } + } } - + + return antinodes.size(); +} + +int main() { + std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); + auto p1_val = part_1(); + std::chrono::steady_clock::time_point middle = std::chrono::steady_clock::now(); + auto p2_val = part_2(); + std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); + cout << "Part 1: " << p1_val << " (" << std::chrono::duration_cast(middle - begin).count() << "µs)" << endl; + cout << "Part 2: " << p2_val << " (" << std::chrono::duration_cast(end - middle).count() << "µs)" << endl; return 0; }