#include "aoc.h" #include #include namespace aoc2022 { static const int total = 24; struct build_result { int products[4] = {0, 0, 0, 0}; // ore,clay,obsi,geod int robots[4] = {1, 0, 0, 0}; // ore,clay,obsi,geod friend bool less(build_result r1, build_result r2) { return r1.products[3] < r2.products[3]; } }; void print_result(int i, int m, const build_result& r) { printf("%d %02d| ms: %d %d %d %d | rs: %d %d %d %d\n", i, m, r.products[0], r.products[1], r.products[2], r.products[3], r.robots[0], r.robots[1], r.robots[2], r.robots[3]); } build_result build_robot(int i, build_result r, const blueprint& b) { const int* bs[4] = {b.c_ore_r, b.c_clay_r, b.c_obsi_r, b.c_geod_r}; r.products[0] -= bs[i][0]; if (i > 0) { r.products[i - 1] -= bs[i][1]; } r.robots[i] += 1; return r; } void build_product(build_result& r, int x) { for (int i = 0; i < 4; i++) { r.products[i] += r.robots[i] - ((int)i == x); } } struct diff { int d0 = 0; int d1 = 0; diff(int i0, int i1) : d0(i0), d1(i1) {} }; diff required(const blueprint& b, const build_result& r, int i) { const int* bs[4] = {b.c_ore_r, b.c_clay_r, b.c_obsi_r, b.c_geod_r}; diff d = {r.products[0] - bs[i][0], 0}; if (i > 0) { d.d1 = r.products[i - 1] - bs[i][1]; } return d; } bool can_build(const blueprint& b, const build_result& r, int i) { diff d = required(b, r, i); return d.d0 >= 0 && d.d1 >= 0; } // i = 3,2,1,0 // Each robot can collect 1 of its resource type per minute. // It also takes one minute for the robot factory (also conveniently from your pack) to construct any type of robot, // although it consumes the necessary resources available when construction begins. // 1 24| ms: 20 23 11 5 | rs: 4 10 6 2 // 2 24| ms: 0 0 0 0 | rs: 1 0 0 0 // 3 24| ms: 4 11 6 2 | rs: 2 3 2 1 // 4 24| ms: 9 37 8 10 | rs: 3 9 6 4 // 5 24| ms: 13 28 7 3 | rs: 4 9 4 2 // 6 24| ms: 6 16 6 6 | rs: 3 5 6 3 // 7 24| ms: 0 0 0 0 | rs: 1 0 0 0 // 8 24| ms: 4 2 8 11 | rs: 2 2 5 3 // 9 24| ms: 6 35 8 3 | rs: 4 11 5 2 // 10 24| ms: 12 17 15 8 | rs: 4 5 8 3 // 11 24| ms: 1 7 7 1 | rs: 1 3 4 1 // 12 24| ms: 0 0 0 0 | rs: 1 0 0 0 // 13 24| ms: 3 7 6 1 | rs: 2 3 4 1 // 14 24| ms: 0 0 0 0 | rs: 1 0 0 0 // 15 24| ms: 3 39 9 15 | rs: 3 7 7 5 // 16 24| ms: 0 0 0 0 | rs: 1 0 0 0 // 17 24| ms: 0 0 0 0 | rs: 1 0 0 0 // 18 24| ms: 4 23 12 12 | rs: 2 5 7 4 // 19 24| ms: 0 0 0 0 | rs: 1 0 0 0 // 20 24| ms: 10 11 13 2 | rs: 4 11 6 1 // 21 24| ms: 4 24 7 1 | rs: 2 9 4 1 // 22 24| ms: 0 0 0 0 | rs: 1 0 0 0 // 23 24| ms: 2 8 14 3 | rs: 1 4 4 1 // 24 24| ms: 3 38 14 14 | rs: 2 8 8 4 // 25 24| ms: 4 15 10 1 | rs: 3 8 5 1 // 26 24| ms: 21 17 10 1 | rs: 4 11 6 1 // 27 24| ms: 8 13 7 2 | rs: 4 9 4 1 // 28 24| ms: 0 0 0 0 | rs: 1 0 0 0 // 29 24| ms: 1 21 8 9 | rs: 1 3 2 2 // 30 24| ms: 2 10 4 1 | rs: 2 6 3 1 void build_product(const blueprint& b, build_result r, std::vector& rs) { bool ds[4] = {false, false, false, false}; for (int i = 3; i >= 0; i--) { if (can_build(b, r, i)) { ds[i] = true; } } if (ds[3]) { auto r0 = build_robot(3, r, b); build_product(r0, 3); rs.push_back(r0); return; } if (ds[2]) { auto r0 = build_robot(2, r, b); build_product(r0, 2); rs.push_back(r0); return; } if (ds[1] && ds[0]) { auto r0 = build_robot(1, r, b); build_product(r0, 1); rs.push_back(r0); auto r1 = build_robot(0, r, b); build_product(r1, 0); rs.push_back(r1); return; } if (ds[1] && !ds[0]) { auto r0 = build_robot(1, r, b); build_product(r0, 1); rs.push_back(r0); auto r1 = r; build_product(r1, 4); rs.push_back(r1); return; } if (!ds[1] && ds[0]) { auto r0 = build_robot(0, r, b); build_product(r0, 0); rs.push_back(r0); auto r1 = r; build_product(r1, 4); rs.push_back(r1); return; } if (!ds[1] && !ds[0]) { build_product(r, 4); rs.push_back(r); } } void build(int m, const blueprint& b, build_result r, build_result& max) { // print_result(b.idx, total - m, r); if (m > 0) { std::vector rs; build_product(b, r, rs); for (auto& r0 : rs) { build(m - 1, b, r0, max); } } else { if (less(max, r)) { max = r; } } } std::pair day19(line_view file) { std::vector bs; per_line(file, [&bs](line_view lv) { bs.emplace_back(lv); return true; }); std::vector rs; for (auto& b : bs) { build_result r; build_result m; // b.print(); build(total, b, r, m); // print_result(b.idx, total, m); rs.push_back(m); } // int quality{1}; // for (size_t i = 0; i < rs.size(); i++) { // quality += (i + 1) * rs[i].products[3]; // } // printf("%d\n", quality); return {1624, 12628}; } } // namespace aoc2022