advent2024

Advent of Code 2024
git clone git://bsandro.tech/advent2024
Log | Files | Refs

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 }