#include #include #include using namespace std; enum opCode { start, // start loc send, // send instrResult loc mix // mix instrResult instrResult }; struct instruction { opCode op; size_t x,y; }; // If we specify that send and mix instructions consume their argument // mixtures, we can verify in O(n). This is because we can never duplicate a // chemical, so mixing the same chemical with itself is impossible by // construction (sort of like linear types!). We can then replace the second // check with a simple check that the value generated by an instruction hasn't // been consumed already. bool verify(vector &program){ size_t n = program.size(); // we now need to check if the mixture constructed by an instruction has been // consumed, so we use an optional, which if none means consumed vector> instrResultLoc(n); for(size_t i=0; i numChemsAt(n); size_t numChems=0; for(size_t i=0; i exampleValidProgram = {{start, 0}, {start, 1}, {send, 0, 1}, {mix, 1, 2}}; vector exampleInvalidProgram = {{start, 0}, {start, 1}, {send, 0, 1}, {mix, 0, 2}}; cout << "Example valid program " << (verify(exampleValidProgram) ? "is" : "is not") << " valid" << endl; cout << "Example invalid program " << (verify(exampleInvalidProgram) ? "is" : "is not") << " valid" << endl; }