#include #include #include #include #include #include using namespace std; #ifdef DEBUG #define DBG(str) do { std::cout << str << std::endl; } while( false ) #else #define DBG(str) do { } while ( false ) #endif struct Point { int x; int y; }; struct Guard { Point p; Point v; }; vector parseGuards(const char *path) { vector guards; ifstream input(path); string line; while(getline(input, line)) { Guard guard; stringstream ss; char c; ss << line; ss >> c >> c >> guard.p.x >> c >> guard.p.y >> c >> c >> guard.v.x >> c >> guard.v.y; guards.push_back(guard); } return guards; } void printGuards(vector guards) { for (auto guard : guards) { cout << "p=" << guard.p.x << "," << guard.p.y << " v=" << guard.v.x << "," << guard.v.y << endl; } } void printField(vector guards, int rows, int columns) { for (int y = 0; y < rows; y++) { for (int x = 0; x < columns; x++) { int num = 0; for (auto guard : guards) { if (guard.p.x == x && guard.p.y == y) num++; } if (num) cout << num; else cout << '.'; } cout << endl; } cout << endl; } // Function to perform Modular Addition int modAdd(int a, int b, int m) { // Adding m to handle negative numbers return ((a % m) + (b % m) + m) % m; } void doStep(vector &guards, int rows, int columns) { for (auto &guard : guards) { guard.p.x = modAdd(guard.p.x, guard.v.x, columns); guard.p.y = modAdd(guard.p.y, guard.v.y, rows); } } long calculateResult(vector guards, int rows, int columns) { long quadrants[4]; int count = 0; for (int y = 0; y < rows / 2; y++) { for (int x = 0; x < columns / 2; x++) { for (auto guard : guards) { if (guard.p.x == x && guard.p.y == y) count++; } } } quadrants[0] = count; count = 0; for (int y = rows / 2 + 1; y < rows; y++) { for (int x = 0; x < columns / 2; x++) { for (auto guard : guards) { if (guard.p.x == x && guard.p.y == y) count++; } } } quadrants[1] = count; count = 0; for (int y = 0; y < rows / 2; y++) { for (int x = columns / 2 + 1; x < columns; x++) { for (auto guard : guards) { if (guard.p.x == x && guard.p.y == y) count++; } } } quadrants[2] = count; count = 0; for (int y = rows / 2 + 1; y < rows; y++) { for (int x = columns / 2 + 1; x < columns; x++) { for (auto guard : guards) { if (guard.p.x == x && guard.p.y == y) count++; } } } quadrants[3] = count; return quadrants[0] * quadrants[1] * quadrants[2] * quadrants[3]; } long part1(const char *path, int rows, int columns) { vector guards = parseGuards(path); // printField(guards, rows, columns); for (int i = 0; i < 100; i++) { doStep(guards, rows, columns); } // printField(guards, rows, columns); return calculateResult(guards, rows, columns); } bool isUnique(vector guards, int rows, int columns) { for (int y = 0; y < rows; y++) { for (int x = 0; x < columns; x++) { bool flag = false; for (auto guard : guards) { if (guard.p.x == x && guard.p.y == y) { if (flag) return false; else flag = true; } } } } return true; } long part2(const char *path, int rows, int columns) { vector guards = parseGuards(path); long step = 0; while (true) { if (isUnique(guards, rows, columns)) return step; doStep(guards, rows, columns); step++; } } int main(int argc, char *argv[]) { int example1 = part1("example", 7, 11); cout << "example1: " << example1 << endl; int input1 = part1("input", 103, 101); cout << "input1: " << input1 << endl; unsigned long long input2 = part2("input", 103, 101); cout << "input2: " << input2 << endl; return 0; }