147 lines
2.5 KiB
C++
147 lines
2.5 KiB
C++
#include <fstream>
|
|
#include <iostream>
|
|
#include <set>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
bool GroupSafe(const std::vector<long> &group);
|
|
|
|
int main()
|
|
{
|
|
std::ifstream ifs("data.txt");
|
|
if(!ifs.is_open())
|
|
{
|
|
std::cerr << "Missing data.txt." << std::endl;
|
|
return -1;
|
|
}
|
|
|
|
unsigned long total = 0;
|
|
unsigned long total_pt2 = 0;
|
|
|
|
std::vector<std::vector<long>> data;
|
|
|
|
for(std::string line; std::getline(ifs, line); )
|
|
{
|
|
if(line == "")
|
|
continue;
|
|
|
|
// add a row for this line:
|
|
data.push_back({});
|
|
|
|
std::istringstream input(line);
|
|
// for each value in the line:
|
|
for(std::string value; std::getline(input, value, ' '); )
|
|
{
|
|
try {
|
|
// add it to the row
|
|
data.back().push_back(std::atoi(value.c_str()));
|
|
} catch (const std::exception &e) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// DEBUG:
|
|
// for(auto row : data)
|
|
// {
|
|
// for(auto col : row)
|
|
// std::cout << col << " ";
|
|
// std::cout << std::endl;
|
|
// }
|
|
|
|
for(auto group : data)
|
|
{
|
|
switch(group.size())
|
|
{
|
|
case 0:
|
|
// Go to next line
|
|
continue;
|
|
break;
|
|
case 1:
|
|
// Can't be increasing or decreasing because it's the only one, so I guess safe?
|
|
++total;
|
|
++total_pt2;
|
|
continue;
|
|
break;
|
|
};
|
|
|
|
bool safe = true;
|
|
|
|
if(GroupSafe(group))
|
|
++total;
|
|
else
|
|
{
|
|
bool re_safe = false;
|
|
for(auto i = 0; i < group.size(); ++i)
|
|
{
|
|
std::vector<long> check;
|
|
if(i != 0)
|
|
check = { group.begin(), group.begin() + i };
|
|
if(i < group.size() - 1)
|
|
check.insert(check.end(), group.begin() + i + 1, group.end());
|
|
if(GroupSafe(check))
|
|
{
|
|
re_safe = true;
|
|
++total_pt2;
|
|
break;
|
|
}
|
|
}
|
|
if(!re_safe)
|
|
{
|
|
std::cout << "Bad: ";
|
|
for(auto val : group)
|
|
std::cout << val << " ";
|
|
std::cout << std::endl;
|
|
}
|
|
}
|
|
}
|
|
std::cout << " Total: " << total << std::endl;
|
|
std::cout << "PT2 Total: " << total + total_pt2 << std::endl;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
bool GroupSafe(const std::vector<long> &group)
|
|
{
|
|
bool increasing = false;
|
|
for(auto i = 0; i < group.size() - 1; ++i)
|
|
{
|
|
if(group[i] == group[i+1])
|
|
continue;
|
|
increasing = group[i] < group[i+1];
|
|
break;
|
|
}
|
|
|
|
bool safe = true;
|
|
int *last = nullptr;
|
|
for(auto i = 0; i < group.size(); ++i)
|
|
{
|
|
auto next = group[i];
|
|
|
|
if(!last)
|
|
{
|
|
last = new int(next);
|
|
continue;
|
|
}
|
|
|
|
if(increasing &&
|
|
(next - *last < 1 || next - *last > 3))
|
|
safe = false;
|
|
else if(!increasing &&
|
|
(next - *last < -3 || next - *last > -1))
|
|
safe = false;
|
|
|
|
if(!safe)
|
|
break;
|
|
|
|
*last = next;
|
|
}
|
|
|
|
if(last)
|
|
delete last, last = nullptr;
|
|
|
|
return safe;
|
|
}
|