main.cpp (3630B)
1 #include <iostream> 2 #include <filesystem> 3 #include <fstream> 4 #include <vector> 5 #include <cstring> 6 #include <cstdio> 7 #include <tuple> 8 #include <algorithm> 9 #include <map> 10 #include <set> 11 12 typedef std::pair<int, int> Vec2; 13 typedef std::map<char, std::vector<Vec2>> Data; 14 15 // I got too lazy these days 16 [[ maybe_unused ]] static int sFieldSize = 0; 17 18 std::vector<Vec2> calc_an1(Vec2 a1, Vec2 a2) { 19 std::vector<Vec2> out; 20 Vec2 d1(a1.first-a2.first, a1.second-a2.second); 21 Vec2 d2(-d1.first, -d1.second); 22 Vec2 p1(a1.first+d1.first, a1.second+d1.second); 23 Vec2 p2(a2.first+d2.first, a2.second+d2.second); 24 if (p1.first>=0&&p1.second>=0&&p1.first<sFieldSize&&p1.second<sFieldSize) { 25 out.push_back(p1); 26 } 27 if (p2.first>=0&&p2.second>=0&&p2.first<sFieldSize&&p2.second<sFieldSize) { 28 out.push_back(p2); 29 } 30 return out; 31 } 32 33 std::set<Vec2> calc_antinodes1(const std::vector<Vec2> &antennas) { 34 std::set<Vec2> out; 35 for (auto it1=antennas.begin(); it1!=antennas.end(); it1++) { 36 for (auto it2=it1+1; it2!=antennas.end(); it2++) { 37 std::vector<Vec2> an = calc_an1(*it1, *it2); 38 for (auto &v:an) out.insert(v); 39 } 40 } 41 return out; 42 } 43 44 std::vector<Vec2> calc_an2(Vec2 a1, Vec2 a2) { 45 std::vector<Vec2> out; 46 out.push_back(a1); 47 out.push_back(a2); 48 Vec2 d1(a1.first-a2.first, a1.second-a2.second); 49 Vec2 d2(-d1.first, -d1.second); 50 Vec2 p1(a1.first+d1.first, a1.second+d1.second); 51 Vec2 p2(a2.first+d2.first, a2.second+d2.second); 52 while (p1.first>=0&&p1.second>=0&&p1.first<sFieldSize&&p1.second<sFieldSize) { 53 out.push_back(p1); 54 p1.first+=d1.first; 55 p1.second+=d1.second; 56 } 57 while (p2.first>=0&&p2.second>=0&&p2.first<sFieldSize&&p2.second<sFieldSize) { 58 out.push_back(p2); 59 p2.first+=d2.first; 60 p2.second+=d2.second; 61 } 62 return out; 63 } 64 65 std::set<Vec2> calc_antinodes2(const std::vector<Vec2> &antennas) { 66 std::set<Vec2> out; 67 for (auto it1=antennas.begin(); it1!=antennas.end(); it1++) { 68 for (auto it2=it1+1; it2!=antennas.end(); it2++) { 69 std::vector<Vec2> an = calc_an2(*it1, *it2); 70 for (auto &v:an) out.insert(v); 71 } 72 } 73 return out; 74 } 75 76 template<typename T> 77 T read_file(const std::string &path) { 78 std::ifstream ifs(path, std::ios::binary); 79 if (!ifs.is_open()) { 80 throw std::runtime_error(path+":"+std::strerror(errno)); 81 } 82 T buf; 83 int y=0; 84 while (1) { 85 std::string str; 86 std::getline(ifs, str); 87 if (!str.empty()) { 88 for (int x=0; x<(int)str.size(); ++x) { 89 if (str[x]!='.') buf[str[x]].push_back(Vec2(x, y)); 90 } 91 } 92 ++y; 93 if (!ifs) break; 94 } 95 sFieldSize = y-1; 96 return buf; 97 } 98 99 int part1(Data &input [[ maybe_unused ]]) { 100 std::set<Vec2> out; 101 for (auto &[k, v] : input) { 102 std::set<Vec2> an = calc_antinodes1(v); 103 for (auto &n:an) { 104 out.insert(n); 105 } 106 } 107 return (int)out.size(); 108 } 109 int part2(Data &input [[ maybe_unused ]]) { 110 std::set<Vec2> out; 111 for (auto &[k, v] : input) { 112 std::set<Vec2> an = calc_antinodes2(v); 113 for (auto &n:an) { 114 out.insert(n); 115 } 116 } 117 return (int)out.size(); 118 } 119 120 int main(int argc, char **argv) { 121 const std::string fname = argc>1 ? argv[1] : "test1.txt"; 122 std::cout << "AoC 2024 day 08 " << fname << std::endl; 123 Data input = read_file<Data>(fname); 124 std::cout << "part1: " << part1(input) << std::endl; 125 std::cout << "part2: " << part2(input) << std::endl; 126 127 return 0; 128 }