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 }