#include #include #include #include #include #include #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{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, 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 / height; 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; }