Files

87 lines
2.5 KiB
C++

#include <algorithm>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#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
int main() {
std::ifstream input("input");
std::string wholeFile(std::istreambuf_iterator<char>{input}, {});
uint16_t width, height, length;
width = wholeFile.find('\n');
// Note for self, std::remove is an algorithm that gets a range and then
// removes a specific value, however it returns a forward iterator, not the
// type itself. Neat thing with the iterator is that you can use
// std::string::erase with it to basically presicion strike specific
// characters from an existing string. Iterated value must be same as the
// array(std::string = std::basic_string<char>, hence must use char)
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;
// Range
// x = 0 <= currentPosition < width
// y = 0 <= currentPosition < height
char currentCharacter = ' ';
uint16_t x = 0, y = 0, totalAvailable = 0;
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++;
}
}
totalAvailable += neighbourCount < 5;
}
std::cout << totalAvailable << std::endl;
return 0;
}