adventOfCode2024/2/puzzle2p2.cpp

130 lines
No EOL
4.5 KiB
C++

#include <stdio.h>
#include <list>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <iterator>
using namespace std;
enum Direction {
UP,
DOWN,
UNSET
};
int main(){
string line;
int safeReports = 0;
stringstream wholeDoc;
ifstream puzzle("input.txt", ifstream::in);
while (getline(puzzle, line)) {
istringstream lineStream(line);
string numberString;
list<int> currentLevels;
while (getline(lineStream, numberString, ' ')) {
int number = stoi(numberString);
currentLevels.push_back(number);
}
list<int> currentLevelsBackup = currentLevels;
int numOfLevelsProcessed = 0;
auto curListIt = currentLevels.begin();
curListIt++; //point to second item in list
auto RevCurListIt = currentLevels.rbegin();
RevCurListIt++; //points to second to last item
enum Direction dir;
bool listDirty =false;
list<int>changeFromPrevLevel;
list<int>levelGoesUp;
list<int>levelGoDown;
list<int>levelStaysSame;
int totalChange=0;
//we are going to walk the levels and see what the change is.
//the frontIt is the front number (starts at 2nd entry)
//backIt is the first entry (starts at 1st entry)
auto frontIt = currentLevels.begin();
frontIt++;
auto backIt = currentLevels.begin();
for(int index = 1;frontIt!=currentLevels.end();index++){
int change = (*frontIt) - (*backIt);
totalChange+=change;
changeFromPrevLevel.push_back(change);
frontIt++;
backIt++;
if (change>0){
levelGoesUp.push_front(index);
} else if(change<0){
levelGoDown.push_front(index);
} else {
levelStaysSame.push_front(index);
}
}
if (totalChange>0){
dir= UP;
} else if (totalChange<0){
dir = DOWN;
}
if (dir==UP&&levelGoDown.size()>1){ //if the overall direction goes up and more then 1 level go down the list is bad
currentLevels.clear();
} else if (dir==DOWN&&levelGoesUp.size()>1){ //same as above but opiosite dirrection
currentLevels.clear();
}
if (levelStaysSame.size()>1){ //cant have more then 1 number the same or the list is bad
currentLevels.clear();
}
if (!currentLevels.empty()&&levelStaysSame.size()==1){
auto itNumberToDelete = currentLevels.begin();
advance(itNumberToDelete,levelStaysSame.front());
currentLevels.erase(itNumberToDelete);
listDirty = true;
}
if (!currentLevels.empty()){
if (dir==UP&&levelGoDown.size()==1){
list<int>::iterator itNumberToDelete = currentLevels.begin();
advance(itNumberToDelete,levelGoDown.front());
currentLevels.erase(itNumberToDelete);
listDirty = true;
} else if (dir==DOWN&&levelGoesUp.size()==1){
auto itNumberToDelete = currentLevels.begin();
advance(itNumberToDelete,levelGoesUp.front());
currentLevels.erase(itNumberToDelete);
listDirty=true;
}
int numOfLevelsInLine = currentLevels.size();
//need to pull the first one to have something to compare to
int prevlevel = currentLevels.front();
currentLevels.pop_front();
numOfLevelsProcessed++;
for (int level = currentLevels.front(); !currentLevels.empty();level=currentLevels.front()){
if (abs(prevlevel-level)>3) {currentLevels.clear();break;}
prevlevel=currentLevels.front();
currentLevels.pop_front();
numOfLevelsProcessed++;
if(numOfLevelsProcessed==numOfLevelsInLine){
safeReports++;
}
}
}
}
cout << safeReports;
puzzle.close();
}