main.cpp (3073B)
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 #include <sstream> 10 11 enum class Op { 12 sum, 13 mul, 14 con 15 }; 16 17 //@todo make generic function using template 18 void genVariations(std::vector<Op> &v, const std::vector<Op> &ops, size_t len, std::vector<std::vector<Op>> &vs) { 19 if (v.size()==len) { 20 vs.push_back(v); 21 return; 22 } 23 for (Op o:ops) { 24 v.push_back(o); 25 genVariations(v, ops, len, vs); 26 v.pop_back(); 27 } 28 } 29 30 class Equation { 31 public: 32 int64_t res; 33 std::vector<int64_t> numbers; 34 std::vector<std::vector<Op>> ps1; // operator permutations for part 1 35 std::vector<std::vector<Op>> ps2; // operator permutations for part 1 36 37 Equation(std::string in) { 38 char tmp[256] = {0}; 39 std::sscanf(in.c_str(), "%ld: %[^\n]", &res, tmp); 40 std::istringstream iss(tmp); 41 int64_t num; 42 while (iss >> num) numbers.push_back(num); 43 populate(); 44 } 45 46 int64_t calc(const std::vector<Op> &ops) { 47 int64_t r = numbers.front(); 48 for (size_t i=0; i<ops.size(); ++i) { 49 if (ops[i]==Op::mul) r *= numbers[i+1]; 50 if (ops[i]==Op::sum) r += numbers[i+1]; 51 if (ops[i]==Op::con) { 52 std::stringstream ss; 53 ss << r << numbers[i+1]; 54 //r = std::stoi(ss.str()); 55 ss >> r; 56 } 57 } 58 return r; 59 } 60 61 private: 62 void populate() { 63 std::vector<Op> v; 64 std::vector<Op> ops = {Op::sum, Op::mul}; 65 genVariations(v, ops, numbers.size()-1, ps1); 66 v.clear(); 67 ops.push_back(Op::con); 68 genVariations(v, ops, numbers.size()-1, ps2); 69 } 70 }; 71 72 typedef std::vector<Equation> Data; 73 74 template<typename T> 75 T read_file(const std::string &path) { 76 std::ifstream ifs(path, std::ios::binary); 77 if (!ifs.is_open()) { 78 throw std::runtime_error(path+":"+std::strerror(errno)); 79 } 80 T buf; 81 while (1) { 82 std::string str; 83 std::getline(ifs, str); 84 if (!str.empty()) buf.push_back(Equation(str)); 85 if (!ifs) break; 86 } 87 return buf; 88 } 89 //@todo threads! 90 int64_t part1(Data &input [[ maybe_unused ]]) { 91 int64_t r = 0; 92 for (auto &e:input) { 93 for (auto &v:e.ps1) { 94 if (e.res==e.calc(v)) { 95 r+=e.res; 96 break; 97 } 98 } 99 } 100 return r; 101 } 102 int64_t part2(Data &input [[ maybe_unused ]]) { 103 int64_t r = 0; 104 for (auto &e:input) { 105 for (auto &v:e.ps2) { 106 if (e.res==e.calc(v)) { 107 r+=e.res; 108 break; 109 } 110 } 111 } 112 return r; 113 } 114 115 int main(int argc, char **argv) { 116 const std::string fname = argc>1 ? argv[1] : "test1.txt"; 117 std::cout << "AoC 2024 day 07 " << fname << std::endl; 118 Data input = read_file<Data>(fname); 119 std::cout << "part1: " << part1(input) << std::endl; 120 std::cout << "part2: " << part2(input) << std::endl; 121 122 return 0; 123 }