Files
AdventOfCode2025/Day4/Question2/main.cpp
2025-12-06 00:40:31 +02:00

102 lines
2.6 KiB
C++

#include <algorithm>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#define POSITON_TO_INDEX(x, y) (y * width) + x
#define SEARCHBOX_WIDTH 3
#define SEARCHBOX_HEIGTH 3
// Basically floor(SEARCHBOX_WIDTH/2)
#define SEARCHBOX_HALF 1
std::ifstream input("input");
std::string wholeFile(std::istreambuf_iterator<char>{input}, {});
uint16_t width, height, length;
uint16_t iterateAndFindAvailableRolls();
int main() {
width = wholeFile.find('\n');
wholeFile.erase(std::remove(wholeFile.begin(), wholeFile.end(), '\n'),
wholeFile.end());
// Need \n for width, for rest it screws with the result
length = wholeFile.length();
height = length / width;
uint16_t output = 0, totalAvailable = 0;
while ((output = iterateAndFindAvailableRolls())) {
totalAvailable += output;
}
std::cout << totalAvailable << std::endl;
return 0;
}
uint16_t iterateAndFindAvailableRolls() {
// Range
// x = 0 <= currentPosition < width
// y = 0 <= currentPosition < height
char currentCharacter = ' ';
uint16_t x = 0, y = 0;
std::vector<uint16_t> whereAvailableRollsAre{};
for (uint16_t currentPosition = 0; currentPosition < length;
currentPosition++) {
currentCharacter = wholeFile.at(currentPosition);
if (currentCharacter != '@') {
continue;
}
// Really convenient that integers are floored
x = currentPosition % width;
y = currentPosition / width;
uint8_t neighbourCount = 0;
// Just check for 5 since we know middle is definetly @ always
for (int16_t index = 0, widthCounter = SEARCHBOX_HALF * -2,
currentGlobalIndex = 0, currentX = 0, currentY = 0;
index < SEARCHBOX_WIDTH * SEARCHBOX_HEIGTH; index++) {
if (neighbourCount == 5) {
break;
}
if (index % SEARCHBOX_WIDTH == 0) {
widthCounter++;
}
// Edge case, corners don't wrap
currentX = (x - SEARCHBOX_HALF) + index % SEARCHBOX_WIDTH;
currentY = y + widthCounter;
if (currentX < 0 || currentX >= width || currentY < 0 ||
currentY >= height) {
continue;
}
// Make sure index is valid
currentGlobalIndex = POSITON_TO_INDEX(currentX, currentY);
if (wholeFile.at(currentGlobalIndex) == '@') {
neighbourCount++;
}
}
if (neighbourCount < 5) {
whereAvailableRollsAre.push_back(currentPosition);
}
}
// I'm sure there is a better way, where yo integrate this
// logic with the one above
for (uint16_t position : whereAvailableRollsAre) {
wholeFile.at(position) = '.';
}
return whereAvailableRollsAre.size();
}