aoc24/14/main.cc

181 lines
3.8 KiB
C++
Raw Normal View History

2024-12-17 00:10:28 +01:00
#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;
}