Day 4 (sorry I am late) Question 1
This commit is contained in:
86
Day4/Question1/main.cpp
Normal file
86
Day4/Question1/main.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
#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 / 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;
|
||||
}
|
||||
Reference in New Issue
Block a user