#include #include #include #include #include #include using namespace std; #define FNAME "optimal.txt" #define cin fin ifstream fin(FNAME); #define NCONS_MAX 10 #define NINST_MAX 10 #define ABS_MAX 30000 #define ADD 0 #define DIV 1 #define DUP 2 #define MUL 3 #define SUB 4 class StackMachine { public: stack S; stack B, C; StackMachine( int n ) { S.push(n); } bool isFinite() { return (S.size() == 1); } int getResult() { return S.top(); } int size() { return S.size(); } bool execute( int inst ) { switch ( inst ) { case DUP: C.push(inst); S.push(S.top()); return true; default: return executeArith(inst); } } bool executeArith( int inst ) { if ( S.size() < 2 ) return false; const int a = S.top(); S.pop(); const int b = S.top(); S.pop(); S.push(b), S.push(a); // 0-div-except if ( inst == DIV && a == 0 ) return false; int result; switch ( inst ) { case ADD: result = a + b; break; case SUB: result = b - a; break; case MUL: result = a * b; break; case DIV: result = b / a; break; default: assert( false ); } if ( abs(result) > ABS_MAX ) return false; S.pop(), S.pop(); S.push(result); C.push(inst); B.push(a); B.push(b); return true; } void undo() { assert( !C.empty() ); const int inst = C.top(); C.pop(); S.pop(); if ( inst == DUP ) return; S.push(B.top()), B.pop(); S.push(B.top()), B.pop(); } }; bool solve( vector &M, const vector &y, vector &solution, int limit, int depth ) { if ( depth == limit ) { for ( int i = 0; i < M.size(); i++ ) if ( !M[i].isFinite() || M[i].getResult() != y[i] ) return false; return true; } if ( depth == NINST_MAX ) return false; const int noper = M[0].size(); const int nrem = limit - depth - 1; for ( int inst = ADD; inst <= SUB; inst++ ) { // いくら消費しても limit 時に 1 つにならない. if ( inst == DUP && noper > nrem ) continue; int executed = 0; for ( int i = 0; i < M.size(); i++ ) { if ( !M[i].execute(inst) ) break; executed++; } if ( executed == M.size() ) { solution.push_back(inst); if ( solve(M, y, solution, limit, depth+1) ) return true; solution.pop_back(); } for ( int i = executed-1; i >= 0; i-- ) M[i].undo(); } return false; } bool compute( vector &M, const vector &y, vector &solution ) { for ( int limit = 0; limit <= NINST_MAX; limit++ ) if ( solve(M, y, solution, limit, 0) ) return true; return false; } int main() { int narg; char *instName[] = {"ADD", "DIV", "DUP", "MUL", "SUB"}; for ( int nt = 1; cin >> narg && narg != 0; nt++ ) { vector x(narg), y(narg); for ( int i = 0; i < narg; i++ ) cin >> x[i]; for ( int i = 0; i < narg; i++ ) cin >> y[i]; vector M; for ( int i = 0; i < narg; i++ ) M.push_back(StackMachine(x[i])); vector solution; const bool solved = compute(M, y, solution); cout << "Program " << nt << endl; if ( !solved ) cout << "Impossible" << endl; else if ( solution.empty() ) cout << "Empty sequence" << endl; else { cout << instName[solution[0]]; for ( int i = 1; i < solution.size(); i++ ) cout << ' ' << instName[solution[i]]; cout << endl; } cout << endl; } return 0; }