181 lines
No EOL
3.8 KiB
C++
181 lines
No EOL
3.8 KiB
C++
#include <fstream>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <vector>
|
|
#include <tuple>
|
|
#include <set>
|
|
|
|
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<Guard> parseGuards(const char *path) {
|
|
vector<Guard> 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<Guard> guards) {
|
|
for (auto guard : guards) {
|
|
cout << "p=" << guard.p.x << "," << guard.p.y << " v=" << guard.v.x << "," << guard.v.y << endl;
|
|
}
|
|
}
|
|
|
|
void printField(vector<Guard> 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<Guard> &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<Guard> 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<Guard> 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<Guard> 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<Guard> 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;
|
|
} |