advent2024

Advent of Code 2024
git clone git://bsandro.tech/advent2024
Log | Files | Refs

main.cpp (2146B)


      1 #include <iostream>
      2 #include <filesystem>
      3 #include <fstream>
      4 #include <vector>
      5 #include <cstring>
      6 #include <cstdio>
      7 #include <tuple>
      8 #include <algorithm>
      9 
     10 struct Report {
     11     std::vector<int> levels;
     12     Report(std::string str) {
     13         std::istringstream ss(str);
     14         for (std::string s; std::getline(ss, s, ' ');) {
     15             levels.push_back(std::stoi(s));
     16         }
     17     }
     18     bool is_safe() {
     19         return is_safe(levels);
     20     }
     21     bool is_safe(std::vector<int> levels) {
     22         int sign = 0;
     23         for (int i=1; i<(int)levels.size(); ++i) {
     24             int diff = levels[i]-levels[i-1];
     25             int adiff = std::abs(diff);
     26             if (adiff<1||adiff>3) return false;
     27             if (sign==0) sign=diff/adiff;
     28             if (sign!=0&&sign!=diff/adiff) return false;
     29         }
     30         return true;
     31     }
     32     bool is_safe2() {
     33         if (is_safe()) return true;
     34         for (int i=0; i<(int)levels.size(); ++i) {
     35             auto levels2 = levels;
     36             auto iter = levels2.begin()+i;
     37             levels2.erase(iter);
     38             if (is_safe(levels2)) return true;
     39         }
     40         return false;
     41     }
     42 };
     43 
     44 typedef std::vector<Report> Data;
     45 
     46 template<typename T>
     47 T read_file(const std::string &path) {
     48     std::ifstream ifs(path, std::ios::binary);
     49     if (!ifs.is_open()) {
     50         throw std::runtime_error(path+":"+std::strerror(errno));
     51     }
     52     T buf;
     53     while (1) {
     54         std::string str;
     55         std::getline(ifs, str);
     56         if (!str.empty()) buf.push_back(Report(str));
     57         if (!ifs) break;
     58     }
     59     return buf;
     60 }
     61 
     62 int part1(Data &input) {
     63     int ret = 0;
     64     for (auto &r : input) {
     65         if (r.is_safe()) ++ret;
     66     }
     67     return ret;
     68 }
     69 int part2(Data &input) {
     70     int ret = 0;
     71     for (auto &r : input) {
     72         if (r.is_safe2()) ++ret;
     73     }
     74     return ret;
     75 }
     76 
     77 int main(int argc, char **argv) {
     78     const std::string fname = argc>1 ? argv[1] : "test1.txt";
     79     std::cout << "AoC 2024 day 02 " << fname << std::endl;
     80     Data input = read_file<Data>(fname);
     81     std::cout << "part1: " << part1(input) << std::endl;
     82     std::cout << "part2: " << part2(input) << std::endl;
     83 
     84     return 0;
     85 }