#include <algorithm>
#include <functional>
#include <iostream>
#include <stack>
#include <string>
#include <vector>
#include <iterator>
using namespace std;
using namespace std::placeholders;
#define IT(v) (v).begin(), (v).end()
template <class Iterator>
void print_it(Iterator vbegin, Iterator vend) {
if (vbegin == vend) return;
cout << *vbegin;
for (auto v = vbegin + 1; v!= vend; ++v) {
cout << ", " << *v;
}
cout << endl;
}
template <class Iterator1, class Iterator2, class F>
auto zip_with(Iterator1 vbegin, Iterator1 vend,
Iterator2 wbegin, Iterator2 wend,
F f) -> vector<decltype(f(*vbegin, *wbegin))> {
vector<decltype(f(*vbegin, *wbegin))> r {};
Iterator1 v = vbegin;
Iterator2 w = wbegin;
for (; v != vend && w != wend; ++v, ++w) {
r.push_back(f(*v, *w));
}
return r;
}
struct Process {
string name;
vector<int> allocation;
vector<int> max;
bool can_allocate(const vector<int>& available) const;
vector<int> unallocate(const vector<int>& available) const;
};
bool operator==(const Process& lhs, const Process& rhs) {
return lhs.name == rhs.name
&& lhs.allocation == rhs.allocation
&& lhs.max == rhs.max;
}
struct DfsData {
vector<int> available;
vector<Process> processes;
};
bool Process::can_allocate(const vector<int>& available) const {
auto need = zip_with(IT(max), IT(allocation), minus<int>());
auto test = zip_with(IT(need), IT(available), less_equal<int>());
return all_of(IT(test), [](bool b) { return b; });
}
vector<int> Process::unallocate(const vector<int>& available) const {
return zip_with(IT(available), IT(allocation), plus<int>());
}
vector<Process> solve_bankers(
vector<int> available,
vector<Process> processes) {
stack<DfsData> s;
s.push({
.available = available,
.processes = {}
});
while(!s.empty()) {
DfsData d = s.top();
s.pop();
if (processes.size() == d.processes.size()) {
return d.processes;
}
for (const auto& p : processes) {
if (d.processes.end() == std::find(IT(d.processes), p)
&& p.can_allocate(d.available)) {
vector<Process> ps (d.processes);
ps.push_back(p);
s.push({
.available = p.unallocate(d.available),
.processes = ps,
});
}
}
}
return {};
}
int main() {
vector<int> available {3,3,2};
vector<Process> processes {
{.name = "P0", .allocation = {0,1,0}, .max = {7,5,3}},
{.name = "P1", .allocation = {2,0,0}, .max = {3,2,2}},
{.name = "P2", .allocation = {3,0,2}, .max = {9,0,2}},
{.name = "P3", .allocation = {2,1,1}, .max = {2,2,2}},
{.name = "P4", .allocation = {0,0,2}, .max = {4,3,3}},
};
auto solution = solve_bankers(available, processes);
vector<string> names {};
for (auto& s : solution) {
names.push_back(s.name);
}
print_it(IT(names));
return 0;
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHN0YWNrPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8aXRlcmF0b3I+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwp1c2luZyBuYW1lc3BhY2Ugc3RkOjpwbGFjZWhvbGRlcnM7CgojZGVmaW5lIElUKHYpICh2KS5iZWdpbigpLCAodikuZW5kKCkKCnRlbXBsYXRlIDxjbGFzcyBJdGVyYXRvcj4Kdm9pZCBwcmludF9pdChJdGVyYXRvciB2YmVnaW4sIEl0ZXJhdG9yIHZlbmQpIHsKCWlmICh2YmVnaW4gPT0gdmVuZCkgcmV0dXJuOwoJY291dCA8PCAqdmJlZ2luOwoJZm9yIChhdXRvIHYgPSB2YmVnaW4gKyAxOyB2IT0gdmVuZDsgKyt2KSB7CgkJY291dCA8PCAiLCAiIDw8ICAqdjsKCX0KCWNvdXQgPDwgZW5kbDsKfQoKdGVtcGxhdGUgPGNsYXNzIEl0ZXJhdG9yMSwgY2xhc3MgSXRlcmF0b3IyLCBjbGFzcyBGPgphdXRvIHppcF93aXRoKEl0ZXJhdG9yMSB2YmVnaW4sIEl0ZXJhdG9yMSB2ZW5kLCAKCQlJdGVyYXRvcjIgd2JlZ2luLCBJdGVyYXRvcjIgd2VuZCwKCQlGIGYpIC0+IHZlY3RvcjxkZWNsdHlwZShmKCp2YmVnaW4sICp3YmVnaW4pKT4gewoJdmVjdG9yPGRlY2x0eXBlKGYoKnZiZWdpbiwgKndiZWdpbikpPiByIHt9OwoJSXRlcmF0b3IxIHYgPSB2YmVnaW47CglJdGVyYXRvcjIgdyA9IHdiZWdpbjsKCWZvciAoOyB2ICE9IHZlbmQgJiYgdyAhPSB3ZW5kOyArK3YsICsrdykgewoJCXIucHVzaF9iYWNrKGYoKnYsICp3KSk7Cgl9CglyZXR1cm4gcjsKfQoKc3RydWN0IFByb2Nlc3MgewoJc3RyaW5nIG5hbWU7Cgl2ZWN0b3I8aW50PiBhbGxvY2F0aW9uOwoJdmVjdG9yPGludD4gbWF4OwoJYm9vbCBjYW5fYWxsb2NhdGUoY29uc3QgdmVjdG9yPGludD4mIGF2YWlsYWJsZSkgY29uc3Q7Cgl2ZWN0b3I8aW50PiB1bmFsbG9jYXRlKGNvbnN0IHZlY3RvcjxpbnQ+JiBhdmFpbGFibGUpIGNvbnN0Owp9OwoKYm9vbCBvcGVyYXRvcj09KGNvbnN0IFByb2Nlc3MmIGxocywgY29uc3QgUHJvY2VzcyYgcmhzKSB7CglyZXR1cm4gbGhzLm5hbWUgPT0gcmhzLm5hbWUgCgkJJiYgbGhzLmFsbG9jYXRpb24gPT0gcmhzLmFsbG9jYXRpb24KCQkmJiBsaHMubWF4ID09IHJocy5tYXg7Cn0KCnN0cnVjdCBEZnNEYXRhIHsKCXZlY3RvcjxpbnQ+IGF2YWlsYWJsZTsKCXZlY3RvcjxQcm9jZXNzPiBwcm9jZXNzZXM7Cn07Cgpib29sIFByb2Nlc3M6OmNhbl9hbGxvY2F0ZShjb25zdCB2ZWN0b3I8aW50PiYgYXZhaWxhYmxlKSBjb25zdCB7CglhdXRvIG5lZWQgPSB6aXBfd2l0aChJVChtYXgpLCBJVChhbGxvY2F0aW9uKSwgbWludXM8aW50PigpKTsKCWF1dG8gdGVzdCA9IHppcF93aXRoKElUKG5lZWQpLCBJVChhdmFpbGFibGUpLCBsZXNzX2VxdWFsPGludD4oKSk7CglyZXR1cm4gYWxsX29mKElUKHRlc3QpLCBbXShib29sIGIpIHsgcmV0dXJuIGI7IH0pOwp9Cgp2ZWN0b3I8aW50PiBQcm9jZXNzOjp1bmFsbG9jYXRlKGNvbnN0IHZlY3RvcjxpbnQ+JiBhdmFpbGFibGUpIGNvbnN0IHsKCXJldHVybiB6aXBfd2l0aChJVChhdmFpbGFibGUpLCBJVChhbGxvY2F0aW9uKSwgcGx1czxpbnQ+KCkpOwp9Cgp2ZWN0b3I8UHJvY2Vzcz4gc29sdmVfYmFua2VycygKCQl2ZWN0b3I8aW50PiBhdmFpbGFibGUsCgkJdmVjdG9yPFByb2Nlc3M+IHByb2Nlc3NlcykgewoJc3RhY2s8RGZzRGF0YT4gczsKCXMucHVzaCh7CgkJLmF2YWlsYWJsZSA9IGF2YWlsYWJsZSwKCQkucHJvY2Vzc2VzID0ge30KCX0pOwoJd2hpbGUoIXMuZW1wdHkoKSkgewoJCURmc0RhdGEgZCA9IHMudG9wKCk7CgkJcy5wb3AoKTsKCQlpZiAocHJvY2Vzc2VzLnNpemUoKSA9PSBkLnByb2Nlc3Nlcy5zaXplKCkpIHsKCQkJcmV0dXJuIGQucHJvY2Vzc2VzOwoJCX0KCQlmb3IgKGNvbnN0IGF1dG8mICBwIDogcHJvY2Vzc2VzKSB7CgkJCWlmIChkLnByb2Nlc3Nlcy5lbmQoKSA9PSBzdGQ6OmZpbmQoSVQoZC5wcm9jZXNzZXMpLCBwKQoJCQkJCSYmIHAuY2FuX2FsbG9jYXRlKGQuYXZhaWxhYmxlKSkgewoJCQkJdmVjdG9yPFByb2Nlc3M+IHBzIChkLnByb2Nlc3Nlcyk7CgkJCQlwcy5wdXNoX2JhY2socCk7CgkJCQlzLnB1c2goewoJCQkJCS5hdmFpbGFibGUgPSBwLnVuYWxsb2NhdGUoZC5hdmFpbGFibGUpLAoJCQkJCS5wcm9jZXNzZXMgPSBwcywKCQkJCX0pOwoJCQl9CgkJfQoJfQoJcmV0dXJuIHt9Owp9CgppbnQgbWFpbigpIHsKCXZlY3RvcjxpbnQ+IGF2YWlsYWJsZSB7MywzLDJ9OwoJdmVjdG9yPFByb2Nlc3M+IHByb2Nlc3NlcyB7CgkJey5uYW1lID0gIlAwIiwgLmFsbG9jYXRpb24gPSB7MCwxLDB9LCAubWF4ID0gezcsNSwzfX0sCgkJey5uYW1lID0gIlAxIiwgLmFsbG9jYXRpb24gPSB7MiwwLDB9LCAubWF4ID0gezMsMiwyfX0sCgkJey5uYW1lID0gIlAyIiwgLmFsbG9jYXRpb24gPSB7MywwLDJ9LCAubWF4ID0gezksMCwyfX0sCgkJey5uYW1lID0gIlAzIiwgLmFsbG9jYXRpb24gPSB7MiwxLDF9LCAubWF4ID0gezIsMiwyfX0sCgkJey5uYW1lID0gIlA0IiwgLmFsbG9jYXRpb24gPSB7MCwwLDJ9LCAubWF4ID0gezQsMywzfX0sCgl9OwoKCWF1dG8gc29sdXRpb24gPSBzb2x2ZV9iYW5rZXJzKGF2YWlsYWJsZSwgcHJvY2Vzc2VzKTsKCXZlY3RvcjxzdHJpbmc+IG5hbWVzIHt9OwoJZm9yIChhdXRvJiBzIDogc29sdXRpb24pIHsKCQluYW1lcy5wdXNoX2JhY2socy5uYW1lKTsKCX0KCXByaW50X2l0KElUKG5hbWVzKSk7CgoJcmV0dXJuIDA7Cn0=