#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
using std::vector;
enum wires { invalid, white, red, black, orange, green };
struct s0; struct s1; struct s2; struct s3; struct s4; struct s5; struct sf; struct ss;
struct ctx {
ctx(vector<wires> const & v) : defused(false), input(v) {
it = input.begin();
run<s0>();
}
wires next() {
if ( it == input.end() )
return invalid;
return *it++;
}
template<typename T>
void run() {
T().run(*this);
}
bool defused;
vector<wires> input;
vector<wires>::const_iterator it;
};
struct defuse_check {
defuse_check(vector<vector<wires>> const & v) {
for(auto&&a:v)
for(auto&&w:a)
input.emplace_back(w);
}
bool defusable() {
std::sort(input.begin(), input.end());
while ( std::next_permutation(input.begin(), input.end()) ) {
if ( ctx(input).defused ) return true;
}
return false;
}
vector<wires> input;
};
struct s0 {
void run(ctx& c) {
switch(c.next()) {
case white: c.run<s1>(); break;
case red : c.run<s2>(); break;
default: c.run<sf>();
}
}
};
struct s1 {
void run(ctx& c) {
switch(c.next()) {
case white : c.run<s2>(); break;
case orange: c.run<s3>(); break;
default: c.run<sf>();
}
}
};
struct s2 {
void run(ctx& c) {
switch(c.next()) {
case red : c.run<s0>(); break;
case black: c.run<s3>(); break;
default: c.run<sf>();
}
}
};
struct s3 {
void run(ctx& c) {
switch(c.next()) {
case black : c.run<s3>(); break;
case orange: c.run<s4>(); break;
case green : c.run<s5>(); break;
default: c.run<sf>();
}
}
};
struct s4 {
void run(ctx& c) {
if ( c.next() == green ) c.run<ss>();
else c.run<sf>();
}
};
struct s5 {
void run(ctx& c) {
if ( c.next() == orange ) c.run<ss>();
else c.run<sf>();
}
};
struct sf { void run(ctx& c) { c.defused = false; } };
struct ss { void run(ctx& c) { c.defused = true ; } };
template<typename T>
void print_defused(T && c) {
cout << (c.defused ? "defused" : "boom") << "\n";
}
template<typename T>
void print_defusable(T && c) {
cout << (c.defusable() ? "defusable" : "not defusable") << "\n";
}
int main(int argc, char* argv[]) {
// challenges
print_defused(ctx( {white, white, red, red, red, white, white, black, green, orange} ));
print_defused(ctx( {white, black, black, black, black, green, orange} ));
print_defused(ctx( {black, green, green} ));
print_defused(ctx( {red, red, white, orange, black, green} ));
// bonus 1
print_defusable(defuse_check({{4, white}, {3, red}, {4, black}, {1, green}, {1, orange}}));
print_defusable(defuse_check({{4, white}, {3, red}, {4, black}, {1, orange}}));
// bonus 1 challenge
print_defusable(defuse_check({{3, white}, {1, red}, {48, black}, {1, green}, {2, orange}}));
print_defusable(defuse_check({{3, white}, {1, red}, {48, black}, {1, green}, {1, orange}}));
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgoKdXNpbmcgc3RkOjpjb3V0Owp1c2luZyBzdGQ6OnZlY3RvcjsKCmVudW0gd2lyZXMgeyBpbnZhbGlkLCB3aGl0ZSwgcmVkLCBibGFjaywgb3JhbmdlLCBncmVlbiB9OwoKc3RydWN0IHMwOyBzdHJ1Y3QgczE7IHN0cnVjdCBzMjsgc3RydWN0IHMzOyBzdHJ1Y3QgczQ7IHN0cnVjdCBzNTsgc3RydWN0IHNmOyBzdHJ1Y3Qgc3M7CgpzdHJ1Y3QgY3R4IHsKCiAgICBjdHgodmVjdG9yPHdpcmVzPiBjb25zdCAmIHYpIDogZGVmdXNlZChmYWxzZSksIGlucHV0KHYpIHsgCiAgICAgICAgaXQgPSBpbnB1dC5iZWdpbigpOwogICAgICAgIHJ1bjxzMD4oKTsKICAgIH0KICAgIAogICAgd2lyZXMgbmV4dCgpIHsKICAgICAgICBpZiAoIGl0ID09IGlucHV0LmVuZCgpICkKICAgICAgICAgICAgcmV0dXJuIGludmFsaWQ7CiAgICAgICAgcmV0dXJuICppdCsrOwogICAgfQogICAgCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgogICAgdm9pZCBydW4oKSB7CiAgICAgICAgVCgpLnJ1bigqdGhpcyk7CiAgICB9CiAgICAKICAgIAogICAgYm9vbCBkZWZ1c2VkOwogICAgdmVjdG9yPHdpcmVzPiBpbnB1dDsKICAgIHZlY3Rvcjx3aXJlcz46OmNvbnN0X2l0ZXJhdG9yIGl0Owp9OwoKc3RydWN0IGRlZnVzZV9jaGVjayB7CiAgICBkZWZ1c2VfY2hlY2sodmVjdG9yPHZlY3Rvcjx3aXJlcz4+IGNvbnN0ICYgdikgewogICAgICAgIGZvcihhdXRvJiZhOnYpCiAgICAgICAgICAgIGZvcihhdXRvJiZ3OmEpCiAgICAgICAgICAgICAgICBpbnB1dC5lbXBsYWNlX2JhY2sodyk7CiAgICB9CiAgCiAgYm9vbCBkZWZ1c2FibGUoKSB7CiAgICAgIHN0ZDo6c29ydChpbnB1dC5iZWdpbigpLCBpbnB1dC5lbmQoKSk7CiAgICAgIHdoaWxlICggc3RkOjpuZXh0X3Blcm11dGF0aW9uKGlucHV0LmJlZ2luKCksIGlucHV0LmVuZCgpKSApIHsKICAgICAgICAgIGlmICggY3R4KGlucHV0KS5kZWZ1c2VkICkgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgcmV0dXJuIGZhbHNlOwogIH0KICAKICB2ZWN0b3I8d2lyZXM+IGlucHV0Owp9OwoKc3RydWN0IHMwIHsKICAgIHZvaWQgcnVuKGN0eCYgYykgewogICAgICAgIHN3aXRjaChjLm5leHQoKSkgewogICAgICAgICAgICBjYXNlIHdoaXRlOiBjLnJ1bjxzMT4oKTsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgcmVkICA6IGMucnVuPHMyPigpOyBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogYy5ydW48c2Y+KCk7CiAgICAgICAgfSAgICAgICAgCiAgICB9Cn07CnN0cnVjdCBzMSB7CiAgICB2b2lkIHJ1bihjdHgmIGMpIHsKICAgICAgICBzd2l0Y2goYy5uZXh0KCkpIHsKICAgICAgICAgICAgY2FzZSB3aGl0ZSA6IGMucnVuPHMyPigpOyBicmVhazsKICAgICAgICAgICAgY2FzZSBvcmFuZ2U6IGMucnVuPHMzPigpOyBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogYy5ydW48c2Y+KCk7CiAgICAgICAgfQogICAgfSAgICAKfTsKc3RydWN0IHMyIHsKICAgIHZvaWQgcnVuKGN0eCYgYykgewogICAgICAgIHN3aXRjaChjLm5leHQoKSkgewogICAgICAgICAgICBjYXNlIHJlZCAgOiBjLnJ1bjxzMD4oKTsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgYmxhY2s6IGMucnVuPHMzPigpOyBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogYy5ydW48c2Y+KCk7CiAgICAgICAgfSAgICAgICAgCiAgICB9ICAgIAp9OwpzdHJ1Y3QgczMgewogICAgdm9pZCBydW4oY3R4JiBjKSB7CiAgICAgICAgc3dpdGNoKGMubmV4dCgpKSB7CiAgICAgICAgICAgIGNhc2UgYmxhY2sgOiBjLnJ1bjxzMz4oKTsgYnJlYWs7CiAgICAgICAgICAgIGNhc2Ugb3JhbmdlOiBjLnJ1bjxzND4oKTsgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgZ3JlZW4gOiBjLnJ1bjxzNT4oKTsgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6IGMucnVuPHNmPigpOwogICAgICAgIH0KICAgIH0gICAgCn07CnN0cnVjdCBzNCB7CiAgICB2b2lkIHJ1bihjdHgmIGMpIHsKICAgICAgICBpZiAoIGMubmV4dCgpID09IGdyZWVuICkgYy5ydW48c3M+KCk7CiAgICAgICAgZWxzZSBjLnJ1bjxzZj4oKTsKICAgIH0gICAgCn07ICAgIApzdHJ1Y3QgczUgewogICAgdm9pZCBydW4oY3R4JiBjKSB7CiAgICAgICAgaWYgKCBjLm5leHQoKSA9PSBvcmFuZ2UgKSBjLnJ1bjxzcz4oKTsKICAgICAgICBlbHNlIGMucnVuPHNmPigpOwogICAgfSAgICAKfTsgICAgCnN0cnVjdCBzZiB7IHZvaWQgcnVuKGN0eCYgYykgeyBjLmRlZnVzZWQgPSBmYWxzZTsgfSB9OwpzdHJ1Y3Qgc3MgeyB2b2lkIHJ1bihjdHgmIGMpIHsgYy5kZWZ1c2VkID0gdHJ1ZSA7IH0gfTsgICAgCgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgp2b2lkIHByaW50X2RlZnVzZWQoVCAmJiBjKSB7CiAgICBjb3V0IDw8IChjLmRlZnVzZWQgPyAiZGVmdXNlZCIgOiAiYm9vbSIpIDw8ICJcbiI7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnZvaWQgcHJpbnRfZGVmdXNhYmxlKFQgJiYgYykgewogICAgY291dCA8PCAoYy5kZWZ1c2FibGUoKSA/ICJkZWZ1c2FibGUiIDogIm5vdCBkZWZ1c2FibGUiKSA8PCAiXG4iOwp9CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKSB7CiAgICAvLyBjaGFsbGVuZ2VzCiAgICBwcmludF9kZWZ1c2VkKGN0eCgge3doaXRlLCB3aGl0ZSwgcmVkLCByZWQsIHJlZCwgd2hpdGUsIHdoaXRlLCBibGFjaywgZ3JlZW4sIG9yYW5nZX0gKSk7CiAgICBwcmludF9kZWZ1c2VkKGN0eCgge3doaXRlLCBibGFjaywgYmxhY2ssIGJsYWNrLCBibGFjaywgZ3JlZW4sIG9yYW5nZX0gKSk7CiAgICBwcmludF9kZWZ1c2VkKGN0eCgge2JsYWNrLCBncmVlbiwgZ3JlZW59ICkpOwogICAgcHJpbnRfZGVmdXNlZChjdHgoIHtyZWQsIHJlZCwgd2hpdGUsIG9yYW5nZSwgYmxhY2ssIGdyZWVufSApKTsKICAgIAogICAgLy8gYm9udXMgMQogICAgcHJpbnRfZGVmdXNhYmxlKGRlZnVzZV9jaGVjayh7ezQsIHdoaXRlfSwgezMsIHJlZH0sIHs0LCBibGFja30sIHsxLCBncmVlbn0sIHsxLCBvcmFuZ2V9fSkpOwogICAgcHJpbnRfZGVmdXNhYmxlKGRlZnVzZV9jaGVjayh7ezQsIHdoaXRlfSwgezMsIHJlZH0sIHs0LCBibGFja30sIHsxLCBvcmFuZ2V9fSkpOwoKICAgIC8vIGJvbnVzIDEgY2hhbGxlbmdlCiAgICBwcmludF9kZWZ1c2FibGUoZGVmdXNlX2NoZWNrKHt7Mywgd2hpdGV9LCB7MSwgcmVkfSwgezQ4LCBibGFja30sIHsxLCBncmVlbn0sIHsyLCBvcmFuZ2V9fSkpOwogICAgcHJpbnRfZGVmdXNhYmxlKGRlZnVzZV9jaGVjayh7ezMsIHdoaXRlfSwgezEsIHJlZH0sIHs0OCwgYmxhY2t9LCB7MSwgZ3JlZW59LCB7MSwgb3JhbmdlfX0pKTsKfQ==