aoc24/08/main.cc

181 lines
4.4 KiB
C++
Raw Permalink Normal View History

2024-12-09 13:15:22 +01:00
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <set>
using namespace std;
vector<vector<char>> parseGrid(const char *path) {
vector<vector<char>> grid;
ifstream input(path);
string line;
char c;
while (getline(input, line)) {
stringstream line_stream;
line_stream << line;
vector<char> row;
while (line_stream >> c) {
row.push_back(c);
}
grid.push_back(row);
}
return grid;
}
void printGrid(vector<vector<char>> grid) {
for (int y = 0; y < grid.size(); y++) {
for (int x = 0; x < grid[y].size(); x++) {
cout << grid[y][x];
}
cout << endl;
}
}
void printAntinodes(vector<vector<char>> grid, vector<vector<bool>> antinodes) {
for (int y = 0; y < antinodes.size(); y++) {
for (int x = 0; x < antinodes[y].size(); x++) {
if (antinodes[y][x]) {
cout << '#';
} else {
cout << grid[y][x];
}
}
cout << endl;
}
}
int countAntinodes(vector<vector<char>> grid, vector<vector<bool>> &antinodes, int y1, int x1, char c) {
int sum = 0;
for (int y2 = 0; y2 < grid.size(); y2++) {
for (int x2 = 0; x2 < grid[y2].size(); x2++) {
if (grid[y2][x2] == c && y1 != y2 && x1 != x2) {
// distance vector
int x_delta = x1 - x2;
int y_delta = y1 - y2;
// first antinode
int x3 = x1 + x_delta;
int y3 = y1 + y_delta;
if (x3 >= 0 && x3 < grid[0].size() && y3 >= 0 && y3 < grid.size() && !antinodes[y3][x3]) {
antinodes[y3][x3] = true;
sum++;
}
// second antinode
x3 = x2 - x_delta;
y3 = y2 - y_delta;
if (x3 >= 0 && x3 < grid[0].size() && y3 >= 0 && y3 < grid.size() && !antinodes[y3][x3]) {
antinodes[y3][x3] = true;
sum++;
}
}
}
}
// cout << "Antinodes after " << c << ":" << endl;
// printAntinodes(grid, antinodes);
return sum;
}
int countAntinodesAdjusted(vector<vector<char>> grid, vector<vector<bool>> &antinodes, int y1, int x1, char c) {
int sum = 0;
for (int y2 = 0; y2 < grid.size(); y2++) {
for (int x2 = 0; x2 < grid[y2].size(); x2++) {
if (grid[y2][x2] == c && y1 != y2 && x1 != x2) {
// distance vector
int x_delta = x1 - x2;
int y_delta = y1 - y2;
int x3 = x1;
int y3 = y1;
while (x3 >= 0 && x3 < grid[0].size() && y3 >= 0 && y3 < grid.size()) {
if(!antinodes[y3][x3]) {
sum++;
antinodes[y3][x3] = true;
}
x3 += x_delta;
y3 += y_delta;
}
x3 = x2;
y3 = y2;
while (x3 >= 0 && x3 < grid[0].size() && y3 >= 0 && y3 < grid.size()) {
if(!antinodes[y3][x3]) {
sum++;
antinodes[y3][x3] = true;
}
x3 -= x_delta;
y3 -= y_delta;
}
}
}
}
// cout << "Antinodes after " << c << ":" << endl;
// printAntinodes(grid, antinodes);
return sum;
}
int part1(const char *path) {
vector<vector<char>> grid = parseGrid(path);
vector<vector<bool>> antinodes;
// initialize antinodes grid
for (int y = 0; y < grid.size(); y++) {
vector<bool> row;
for (int x = 0; x < grid[y].size(); x++) {
row.push_back(false);
}
antinodes.push_back(row);
}
set<char, greater<char>> visited;
int sum = 0;
for (int y = 0; y < grid.size(); y++) {
for (int x = 0; x < grid[y].size(); x++) {
if (grid[y][x] != '.' && visited.count(grid[y][x]) == 0) {
sum += countAntinodes(grid, antinodes, y, x, grid[y][x]);
}
}
}
return sum;
}
int part2(const char *path) {
vector<vector<char>> grid = parseGrid(path);
vector<vector<bool>> antinodes;
// initialize antinodes grid
for (int y = 0; y < grid.size(); y++) {
vector<bool> row;
for (int x = 0; x < grid[y].size(); x++) {
row.push_back(false);
}
antinodes.push_back(row);
}
set<char, greater<char>> visited;
int sum = 0;
for (int y = 0; y < grid.size(); y++) {
for (int x = 0; x < grid[y].size(); x++) {
if (grid[y][x] != '.' && visited.count(grid[y][x]) == 0) {
sum += countAntinodesAdjusted(grid, antinodes, y, x, grid[y][x]);
}
}
}
return sum;
}
int main(int argc, char *argv[]) {
cout << "example1: " << part1("example") << endl;
cout << "input1: " << part1("input") << endl;
cout << "example2: " << part2("example") << endl;
cout << "input2: " << part2("input") << endl;
return 0;
}