#include #include #include #include #include #include bool GroupSafe(const std::vector &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> 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 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 &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; }