advent2024

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

main.cpp (3512B)


      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 
     10 typedef std::vector<std::string> Data;
     11 typedef enum Direction {
     12     DIR_N,
     13     DIR_S,
     14     DIR_W,
     15     DIR_E,
     16     DIR_NE,
     17     DIR_SE,
     18     DIR_SW,
     19     DIR_NW
     20 } Direction;
     21 
     22 struct Vec2 {
     23     int x;
     24     int y;
     25 };
     26 
     27 struct Field {
     28     Data data;
     29 };
     30 
     31 template<typename T>
     32 T read_file(const std::string &path) {
     33     std::ifstream ifs(path, std::ios::binary);
     34     if (!ifs.is_open()) {
     35         throw std::runtime_error(path+":"+std::strerror(errno));
     36     }
     37     T buf;
     38     while (1) {
     39         std::string str;
     40         std::getline(ifs, str);
     41         if (!str.empty()) buf.push_back(str);
     42         if (!ifs) break;
     43     }
     44     return buf;
     45 }
     46 
     47 bool check_dir(Data &d, Vec2 p, Direction dir) {
     48     switch (dir) {
     49     case DIR_N:
     50         return d[p.y-1][p.x]=='M'&&d[p.y-2][p.x]=='A'&&d[p.y-3][p.x]=='S';
     51     case DIR_S:
     52         return d[p.y+1][p.x]=='M'&&d[p.y+2][p.x]=='A'&&d[p.y+3][p.x]=='S';
     53     case DIR_W:
     54         return d[p.y][p.x-1]=='M'&&d[p.y][p.x-2]=='A'&&d[p.y][p.x-3]=='S';
     55     case DIR_E:
     56         return d[p.y][p.x+1]=='M'&&d[p.y][p.x+2]=='A'&&d[p.y][p.x+3]=='S';
     57     case DIR_NE:
     58         return d[p.y-1][p.x+1]=='M'&&d[p.y-2][p.x+2]=='A'&&d[p.y-3][p.x+3]=='S';
     59     case DIR_SE:
     60         return d[p.y+1][p.x+1]=='M'&&d[p.y+2][p.x+2]=='A'&&d[p.y+3][p.x+3]=='S';
     61     case DIR_SW:
     62         return d[p.y+1][p.x-1]=='M'&&d[p.y+2][p.x-2]=='A'&&d[p.y+3][p.x-3]=='S';
     63     case DIR_NW:
     64         return d[p.y-1][p.x-1]=='M'&&d[p.y-2][p.x-2]=='A'&&d[p.y-3][p.x-3]=='S';
     65     }
     66     return false;
     67 }
     68 
     69 bool check_xmas(Data &d, Vec2 p) {
     70     char nw = d[p.y-1][p.x-1];
     71     char se = d[p.y+1][p.x+1];
     72     char ne = d[p.y-1][p.x+1];
     73     char sw = d[p.y+1][p.x-1];
     74     return ((nw=='S'&&se=='M')||(nw=='M'&&se=='S')) &&
     75            ((ne=='S'&&sw=='M')||(ne=='M'&&sw=='S'));
     76 }
     77 
     78 int part1(Data &input) {
     79     int size = input.size(); // square input
     80     int ret = 0;
     81     for (int y=0; y<size; ++y) {
     82         for (int x=0; x<size; ++x) {
     83             Vec2 p{x, y};
     84             if (input[y][x]=='X') {
     85                 if (y>=3)               ret+=(int)check_dir(input, p, DIR_N);
     86                 if (y<size-3)           ret+=(int)check_dir(input, p, DIR_S);
     87                 if (x>=3)               ret+=(int)check_dir(input, p, DIR_W);
     88                 if (x<size-3)           ret+=(int)check_dir(input, p, DIR_E);
     89                 if (y>=3&&x<size-3)     ret+=(int)check_dir(input, p, DIR_NE);
     90                 if (y<size-3&&x<size-3) ret+=(int)check_dir(input, p, DIR_SE);
     91                 if (y<size-3&&x>=3)     ret+=(int)check_dir(input, p, DIR_SW);
     92                 if (y>=3&&x>=3)         ret+=(int)check_dir(input, p, DIR_NW);
     93             }
     94         }
     95     }
     96     return ret;
     97 }
     98 int part2(Data &input) {
     99     int size = input.size(); // square input
    100     int ret = 0;
    101     for (int y=0; y<size; ++y) {
    102         for (int x=0; x<size; ++x) {
    103             Vec2 p{x, y};
    104             if (input[y][x]=='A'&&y>0&&y<size-1&&x>0&&x<size-1) {
    105                 if (check_xmas(input, p)) {
    106                     ++ret;
    107                 }
    108             }
    109         }
    110     }
    111     return ret;
    112 }
    113 
    114 int main(int argc, char **argv) {
    115     const std::string fname = argc>1 ? argv[1] : "test1.txt";
    116     std::cout << "AoC 2024 day 04 " << fname << std::endl;
    117     Data input = read_file<Data>(fname);
    118     std::cout << "part1: " << part1(input) << std::endl;
    119     std::cout << "part2: " << part2(input) << std::endl;
    120 
    121     return 0;
    122 }