#include #include #include #include #include #include #include using namespace std; struct Port { int gate; // -1=X int pos; // 0=Left, 1=Right Port(int gate_number=-1, int position=-1) : gate(gate_number) , pos(position) {} Port offset(int gate_off, int input_off) { if (gate==-1) pos+=input_off; else gate+=gate_off; } void save(ostream &out) const { if (gate==-1) { if (pos==0) out<<"X"; else out< start; vector end; int value; // input vector gate; void clear(); void load(istream &in); void load(const char *str); void save(ostream &out); inline int read(Port p); int step(int in); void append(const Circuit &x); void connect(int from, int to); Circuit() {} Circuit(const char *str) { load(str); } }; void skipSpaces(istream &in) { while(in) { int c=in.get(); if (!isspace(c)) { in.putback(c); return; } } } Port getPort(istream &in) { int c; c=in.get(); if (c=='X') return Port(-1,0); else if (isdigit(c)) { int n=0; do { n=n*10 + c-'0'; c=in.get(); } while (isdigit(c)); if (c=='L') return Port(n,0); if (c=='R') return Port(n,1); if (c=='X') // estensione per il multiinput return Port(-1,n); } cerr<<"unexpected character ["<to) gate[i].port[k].pos--; if (gate[i].port[2+k].gate==-1 && gate[i].port[2+k].pos>from) gate[i].port[2+k].pos--; } } } Circuit circuit; const char ZERO[]= "1R:" "8L0L0#0R1L," // 0 "0RX0#2L2R," // 1 "1L1R0#3L3R," // 2 "2L2R0#4L4R," // 3 "3L3R0#8L5R," // 4 "7L4R0#8R7L," // 5 "7R6L0#6R7R," // 6 "5R6R0#5L6L," // 7 "4L5L0#0LX:" // 8 "8R" ; const char ONE_1[]= "1L:" "3L0L0#0R1R," // 0 "X0R0#X3L," // 1 "3R2L0#2R3R," // 2 "1R2R0#0L2L:" // 3 "1L" ; const char TWO_1[]= "0L:" "X0L0#0RX:" "0R"; const char ID[]= "0R:" "2RX0#1R2R," // 0 "2L0L0#X2L," // 1 "1R0R0#1L0L:"// 2 "1L"; const char DELTA_1[]= "4R:" "4L4R0#1R2R,"//0 "3L0L0#4L3L,"//1 "3R0R0#X3R,"//2 "1R2R0#1L2L,"//3 "1LX0#0L0R:"//4 "2L"; const char QUAD_1[]= "1L0L2R3L:" "1X0L0#0R2L," //0 "0X1L0#1R4L," //1 "0R2X0#4R5R," //2 "3X3L0#3R5L," //3 "1R2L0#0X1X," //4 "3R2R0#2X3X:" //5 "4L4R5L5R"; const char DUP_1[]= "2L0L1R:" "1X0L0#0R1L,"//0 "0R2X0#3R2X,"//1 "0X2L0#2R3L,"//2 "2R1L0#0X1X:"//3 "3L3R1R"; const char TERNA_1[]= "1L0R1R0L2R:" "3X1X0#3X2L,"//0 "0X2X0#2X3L,"//1 "0R4X0#4X3R,"//2 "1R2R0#0X1X:"//3 "3L3R1L0L2L"; Circuit zero(ZERO); Circuit one; Circuit two; Circuit id(ID); Circuit delta; Circuit tau; Circuit duplex; Circuit quad; Circuit terna; void construct() { one.append(zero); one.append(Circuit(ONE_1)); one.connect(0,1); two.append(zero); two.append(Circuit(TWO_1)); two.connect(0,1); delta.append(one); delta.append(Circuit(DELTA_1)); delta.connect(0,1); tau.append(id); tau.append(id); tau.connect(1,0); duplex.append(Circuit(DUP_1)); duplex.append(zero); duplex.connect(3,1); duplex.append(zero); duplex.connect(3,0); duplex.connect(2,1); quad.append(Circuit(QUAD_1)); quad.append(zero); quad.connect(4,0); quad.append(zero); quad.connect(4,1); quad.append(zero); quad.connect(4,3); terna.append(duplex); terna.append(one); terna.append(Circuit(TERNA_1)); terna.connect(0,3); terna.connect(0,3); terna.connect(0,4); terna.connect(1,1); terna.connect(1,1); assert(terna.start.size()==3); } void addTrit(char trit) { circuit.append(tau); circuit.connect(0,1); circuit.append(delta); switch(trit) { case '0': circuit.append(zero); break; case '1': circuit.append(one); break; case '2': circuit.append(two); break; default: assert(false); } circuit.append(terna); circuit.connect(0,5); circuit.connect(0,3); circuit.connect(0,3); circuit.connect(1,1); circuit.connect(1,1); assert(circuit.start.size()==1); } void sequence(const char *s) { int i; circuit.append(zero); for (i=0;s[i];++i); --i; while (i>=0) { addTrit(s[i]); i--; } } main(int argc, char *argv[]) { if (argc==1) { construct(); sequence("110212101121012211"); circuit.save(cout); } else { char *filename=argv[1]; ifstream in(filename); if (!in) { cerr<<"cannot open file ["<>in; cout<