main.cpp (3225B)
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 <chrono> 10 #include <thread> 11 #include "utils.hpp" 12 13 struct Vec2 { 14 int x; 15 int y; 16 }; 17 18 struct Robot { 19 Vec2 p; // position 20 Vec2 v; // velocity 21 Robot(const std::string &s) { 22 std::sscanf(s.c_str(), "p=%d,%d v=%d,%d", &p.x, &p.y, &v.x, &v.y); 23 } 24 }; 25 26 typedef std::vector<Robot> Data; 27 28 template<typename T, typename N> 29 T read_file(const std::string &path) { 30 std::ifstream ifs(path, std::ios::binary); 31 if (!ifs.is_open()) { 32 throw std::runtime_error(path+":"+std::strerror(errno)); 33 } 34 T buf; 35 while (1) { 36 std::string str; 37 std::getline(ifs, str); 38 if (!str.empty()) buf.push_back(N(str)); 39 if (!ifs) break; 40 } 41 return buf; 42 } 43 44 void printMap(const Data &robots, const Vec2 &mapSize) { 45 for (int y=0; y<mapSize.y; ++y) { 46 for (int x=0; x<mapSize.x; ++x) { 47 if (std::count_if(robots.begin(), robots.end(), [&x, &y](const Robot &r) {return r.p.x==x&&r.p.y==y;})>0) { 48 std::printf("+"); 49 } else std::printf("."); 50 } 51 std::printf("\n"); 52 } 53 std::printf("\n"); 54 } 55 56 int countRobots(const Data &robots, const Vec2 &from, const Vec2 &to) { 57 return std::count_if(robots.begin(), robots.end(), [&from, &to](const Robot &r) { 58 return (r.p.x>=from.x && r.p.y<=from.y && r.p.x<=to.x && r.p.y>=to.y); 59 }); 60 } 61 62 void moveRobots(Data &robots, const Vec2 &mapSize, int seconds) { 63 for (auto &r:robots) { 64 r.p.x += r.v.x*seconds; 65 r.p.y += r.v.y*seconds; 66 r.p.x %= mapSize.x; 67 r.p.y %= mapSize.y; 68 if (r.p.x<0) r.p.x += mapSize.x; 69 if (r.p.y<0) r.p.y += mapSize.y; 70 } 71 } 72 73 int64_t part1(Data input, Vec2 mapSize) { 74 int64_t out = 1; 75 moveRobots(input, mapSize, 100); 76 77 out *= countRobots(input, Vec2(0, mapSize.y/2-1), Vec2(mapSize.x/2-1, 0)); 78 out *= countRobots(input, Vec2(mapSize.x/2+1, mapSize.y/2-1), Vec2(mapSize.x-1, 0)); 79 out *= countRobots(input, Vec2(0, mapSize.y-1), Vec2(mapSize.x/2-1, mapSize.y/2+1)); 80 out *= countRobots(input, Vec2(mapSize.x/2+1, mapSize.y-1), Vec2(mapSize.x-1, mapSize.y/2+1)); 81 82 return out; 83 } 84 85 int64_t part2(Data &input, Vec2 mapSize) { 86 using namespace std::chrono_literals; 87 int i=1; 88 const int minRobots = mapSize.y*0.12; 89 for (; i<INT_MAX; ++i) { 90 moveRobots(input, mapSize, 1); 91 if (countRobots(input, Vec2(mapSize.x/2, mapSize.y-1), Vec2(mapSize.x/2, 0))>minRobots && 92 countRobots(input, Vec2(0, mapSize.y/2), Vec2(mapSize.x-1, mapSize.y/2))>minRobots) { 93 break; 94 } 95 } 96 97 return i; 98 } 99 100 int main(int argc, char **argv) { 101 Performance perf; 102 const std::string fname = argc>1 ? argv[1] : "test1.txt"; 103 std::cout << "AoC 2024 day 14 " << fname << std::endl; 104 Data input = read_file<Data, Robot>(fname); 105 Vec2 mapSize = fname.contains("test") ? Vec2(11,7) : Vec2(101,103); 106 std::cout << "part1: " << part1(input, mapSize) << std::endl; 107 std::cout << "part2: " << part2(input, mapSize) << std::endl; 108 printMap(input, mapSize); 109 return 0; 110 }