Advertisement
cielavenir

icpc2007dA in Pxem

Apr 23rd, 2012
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.66 KB | None | 0 0
  1. //nuko admitted there is specification bug that it doesn't have "swap".
  2. //#define EXTENDED
  3.  
  4. #define PUSHINT0  "00.-"
  5. #define PUSHINT1  "01.-"
  6. #define PUSHINT2  "02.-"
  7. #define PUSHINT1000  "ak.-d.!"
  8. //#define PUTSPACE  "0P.-.o"
  9. //#define PUTCOLON  "0j.-.o"
  10. #define PUTLF     "ak.-.o"
  11. #define INCREMENT PUSHINT1".+"
  12. #define DECREMENT PUSHINT1".-"
  13. #define PXEM      ".pxem"
  14.  
  15. //after using these subroutines, temporary area will be overwritten.
  16. #define ROTATEL   ".t.v.m.v"
  17. #define ROTATER   ".v.t.v.m"
  18. #define PEEKT     ".c.t"
  19. #define PEEKB     ".v.c.t.v"
  20. #define POPB      ".v.t.v"
  21.  
  22. #ifdef EXTENDED
  23. //._.c.w.c.v00.-ak.-d.!00.-.v.c.w._.c.t.v.c.m.h.x.s.m00.-00.-.a.m.h.t.v.m.v.t.c.m.h.y.s.m00.-00.-.a.m.h.t.v.m.v.+.v.t.v.m.v.t.v.m.v.s01.-.-.c.a.s02.-.-.t.-.-.m.$.nak.-.o._.c.a.s.pxem
  24. char *FILENAME=
  25. "._.c.w" //n while n
  26.     ".c" //i,n
  27.     ".v" //n,i
  28.     PUSHINT0 PUSHINT1000 PUSHINT0 //max,min,sum,n,i
  29.     ".v.c.w"       //i,n,sum,min,max while i
  30.         "._" PEEKT //x,i,n,sum,min,max t==x
  31.         ".v"       //max,min,sum,n,i,x t==x
  32.         ".c.m.h"
  33.  
  34.         //max,x,max,min,sum,n,i,x t==x
  35.         ".x"       // while max < x
  36.         ".s.m"
  37.         PUSHINT0 PUSHINT0 ".a"
  38.         //max,min,sum,n,i,x t==x
  39.         ".m.h"     //max,x,min,sum,n,i,x
  40.         ROTATEL    //x,min,sum,n,i,x,max
  41.         ".t.c.m.h"
  42.  
  43.         //min,x,min,sum,n,i,x,max t==x
  44.         ".y"       // while min > x
  45.         ".s.m"
  46.         PUSHINT0 PUSHINT0 ".a"
  47.  
  48.         //min,sum,n,i,x,max t==x
  49.         ".m.h"     //min,x,sum,n,i,x,max
  50.         ROTATEL    //x,sum,n,i,x,max,min
  51.         ".+"       //sum,n,i,x,max,min
  52.         ROTATER ROTATER ".v.s" //i,n,sum,min,max
  53.     DECREMENT".c.a"
  54.  
  55.     ".s" PUSHINT2 ".-.t" //sum,min,max t==n-2
  56.     ".-.-.m.$.n"PUTLF
  57. "._.c.a.s"PXEM;
  58. char *CONTENT="";
  59. #else
  60. //._.c.w.c.v00.-ak.-d.!00.-.v.c.w._.c.t.v.t.v.m.v.e.t.v.m.v.e.v.t.v.m.v.t.v.m.v.c.t.v.x.s.m00.-00.-.a.t.v.m.v.e.t.v.m.v.t.v.m.v.e.t.v.m.v.e.v.t.v.m.v.t.v.m.v.c.t.v.y.s.m00.-00.-.a.t.v.m.v.e.+.v.t.v.m.v.t.v.m.s.v.t.v.m.v.s01.-.-.c.a.s02.-.-.t.-.-.m.$.nak.-.o._.c.a.s.pxem
  61. char *FILENAME=
  62. "._.c.w" //n while n
  63.     ".c" //i,n
  64.     ".v" //n,i
  65.     PUSHINT0 PUSHINT1000 PUSHINT0 //max,min,sum,n,i
  66.     ".v.c.w"       //i,n,sum,min,max while i
  67.         "._" PEEKT //x,i,n,sum,min,max t==x
  68.         ".v"       //max,min,sum,n,i,x t==x
  69.         ROTATEL    //min,sum,n,i,x,max
  70.         ".e"       //x,min,sum,n,i,x,max
  71.         ROTATEL    //min,sum,n,i,x,max,x
  72.         ".e"       //max,min,sum,n,i,x,max,x
  73.         ROTATER ROTATER PEEKB
  74.  
  75.         //max,x,max,min,sum,n,i,x t==x
  76.         ".x"       // while max < x
  77.         ".s.m"
  78.         PUSHINT0 PUSHINT0 ".a"
  79.         //max,min,sum,n,i,x t==x
  80.         ROTATEL    //min,sum,n,i,x,max
  81.         ".e"       //x,min,sum,n,i,x,max
  82.         ROTATEL ROTATEL //sum,n,i,x,max,x,min
  83.         ".e"       //x,sum,n,i,x,max,x,min
  84.         ROTATEL    //sum,n,i,x,max,x,min,x
  85.         ".e"       //min,sum,n,i,x,max,x,min,x
  86.         ROTATER ROTATER PEEKB
  87.  
  88.         //min,x,min,sum,n,i,x,max,x t==x
  89.         ".y"       // while min > x
  90.         ".s.m"
  91.         PUSHINT0 PUSHINT0 ".a"
  92.  
  93.         //min,sum,n,i,x,max,x t==x
  94.         ROTATEL    //sum,n,i,x,max,x,min
  95.         ".e"       //x,sum,n,i,x,max,x,min
  96.         ".+"       //sum,n,i,x,max,x,min
  97.         ROTATER ROTATER ".s" ROTATER ".v.s" //i,n,sum,min,max
  98.     DECREMENT".c.a"
  99.  
  100.     ".s" PUSHINT2 ".-.t" //sum,min,max t==n-2
  101.     ".-.-.m.$.n"PUTLF
  102. "._.c.a.s"PXEM;
  103. char *CONTENT=".v.s.t.s.s.s.s.s.s.m"; //return second-last element
  104. #endif
  105.  
  106. // http://cfs.maxn.jp/neta/pxem.php
  107. #include <cstdio>
  108. #include <string>
  109. #include <cstring>
  110. #include <stack>
  111. #include <queue>
  112. #include <ctime>
  113. #include <cstdlib>
  114. #include <cmath>
  115. using namespace std;
  116. class Pxem{
  117.     private:
  118.         stack<int>  pStack;     // stack
  119.         char        *fName;     // file name
  120.         char        *fCont;     // file contents
  121.         int     temp;       // temporary area
  122.         bool        used;       // used temp?
  123.         void    print();        // print stack
  124.         bool    out();          // output
  125.         void    numOut();       // output(number)
  126.         void    input();        // input
  127.         void    numInput();     // number input
  128.         void    copy();         // x,y,z -> x,x,y,z
  129.         void    throwAway();        // x,y,z -> y,z
  130.         void    inverse();      // x,y,z -> z,y,x
  131.         void    fileRead();     // input from file contents
  132.         void    emu();          // run pxem using file contents
  133.         void    getRand();      // create random number from stack[0]
  134.         void    toTemp();       // temp = stack[0];
  135.         void    fromTemp();     // if(used) stack.push(temp);
  136.         void    addition();     // x,y,z -> (x+y),z
  137.         void    subtraction();      // x,y,z -> abs(x-y),z
  138.         void    multiplication();   // x,y,z -> (x*y),z
  139.         void    getQuotient();      // x,y,z -> (x>y?int(x/y):int(y/x)),z
  140.         void    getSurplus();       // x,y,z -> (x>y?int(x%y):int(y%x)),z
  141.         void    addStr(char*);      // addStr("ab"); -> pStack.push(98);pStack.push(97);
  142.  
  143.         void    getXor();   // x,y,z -> x^y,z
  144.         void    excHange();     // x,y,z -> y,x,z
  145.     public:
  146.         Pxem(char*,char*);          // constructor from main()
  147.         Pxem(char*,char*,stack<int>);       // constructor from Pxem
  148.         void    run();              // run pxem
  149.         stack<int>  getStack() const;   // get stack
  150. };
  151. Pxem::Pxem(char *f, char *g):fName(f),fCont(g){srand((unsigned)time(NULL));}
  152. Pxem::Pxem(char *f, char *g,stack<int> hoge):fName(f),fCont(g){
  153.     srand((unsigned)time(NULL));
  154.     stack<int>fuga;
  155.     while(!hoge.empty()){
  156.         fuga.push((int)hoge.top());
  157.         hoge.pop();
  158.     }
  159.     while(!fuga.empty()){
  160.         pStack.push(fuga.top());
  161.         hoge.push(fuga.top());
  162.         fuga.pop();
  163.     }
  164. }
  165. void Pxem::run(){
  166.     long ps     = 0;
  167.     long slen   = strlen(fName);
  168.     string buf;
  169.     while(ps<slen){
  170.         if(fName[ps]=='.'&&ps+1<slen){
  171.             int cnt;
  172.             int ccp;
  173.             switch(fName[++ps]){
  174.                 case 'p':
  175.                 case 'P':
  176.                     // print stack
  177.                     addStr((char*)buf.c_str());
  178.                     buf = "";
  179.                     print();
  180.                     break;
  181.                 case 'o':
  182.                 case 'O':
  183.                     // output
  184.                     addStr((char*)buf.c_str());
  185.                     buf = "";
  186.                     out();
  187.                     break;
  188.                 case 'n':
  189.                 case 'N':
  190.                     // output(number)
  191.                     addStr((char*)buf.c_str());
  192.                     buf = "";
  193.                     numOut();
  194.                     break;
  195.                 case 'i':
  196.                 case 'I':
  197.                     // input
  198.                     addStr((char*)buf.c_str());
  199.                     buf = "";
  200.                     input();
  201.                     break;
  202.                 case '_':
  203.                     // input(number)
  204.                     addStr((char*)buf.c_str());
  205.                     buf = "";
  206.                     numInput();
  207.                     break;
  208.                 case 'c':
  209.                 case 'C':
  210.                     // x,y,z -> x,x,y,z
  211.                     addStr((char*)buf.c_str());
  212.                     buf = "";
  213.                     copy();
  214.                     break;
  215.                 case 's':
  216.                 case 'S':
  217.                     // x,y,z -> x,y
  218.                     addStr((char*)buf.c_str());
  219.                     buf = "";
  220.                     throwAway();
  221.                     break;
  222.                 case 'v':
  223.                 case 'V':
  224.                     // x,y,z -> z,y,x
  225.                     addStr((char*)buf.c_str());
  226.                     buf = "";
  227.                     inverse();
  228.                     break;
  229.                 case 'f':
  230.                 case 'F':
  231.                     // input from file contents
  232.                     addStr((char*)buf.c_str());
  233.                     buf = "";
  234.                     fileRead();
  235.                     break;
  236.                 case 'e':
  237.                 case 'E':
  238.                     // run pxem using file contents
  239.                     addStr((char*)buf.c_str());
  240.                     buf = "";
  241.                     emu();
  242.                     break;
  243.                 case 'r':
  244.                 case 'R':
  245.                     // create random number from stack[0]
  246.                     addStr((char*)buf.c_str());
  247.                     buf = "";
  248.                     getRand();
  249.                     break;
  250.                 case 'w':
  251.                 case 'W':
  252.                     addStr((char*)buf.c_str());
  253.                     buf="";
  254.                     if(!pStack.empty()){
  255.                         cnt=pStack.top();
  256.                         pStack.pop();
  257.                         if(cnt==0){
  258.                             ps++;
  259.                             cnt=1;
  260.                             while(cnt){
  261.                                 if(fName[ps]=='.'){
  262.                                     switch(fName[++ps]){
  263.                                         case 'w':
  264.                                         case 'W':
  265.                                         case 'x':
  266.                                         case 'X':
  267.                                         case 'y':
  268.                                         case 'Y':
  269.                                         case 'z':
  270.                                         case 'Z':
  271.                                             cnt++;
  272.                                             break;
  273.                                         case 'a':
  274.                                         case 'A':
  275.                                             cnt--;
  276.                                             break;
  277.                                     }
  278.                                 }
  279.                                 ps++;
  280.                             }
  281.                             ps--;
  282.                         }
  283.                     }
  284.                     break;
  285.                 case 'x':
  286.                 case 'X':
  287.                     addStr((char*)buf.c_str());
  288.                     buf="";
  289.                     if(pStack.size()>1){
  290.                         cnt=pStack.top();
  291.                         pStack.pop();
  292.                         ccp=pStack.top();
  293.                         pStack.pop();
  294.                         if(cnt>=ccp){
  295.                             ps++;
  296.                             cnt=1;
  297.                             while(cnt){
  298.                                 if(fName[ps]=='.'){
  299.                                     switch(fName[++ps]){
  300.                                         case 'w':
  301.                                         case 'W':
  302.                                         case 'x':
  303.                                         case 'X':
  304.                                         case 'y':
  305.                                         case 'Y':
  306.                                         case 'z':
  307.                                         case 'Z':
  308.                                             cnt++;
  309.                                             break;
  310.                                         case 'a':
  311.                                         case 'A':
  312.                                             cnt--;
  313.                                             break;
  314.                                     }
  315.                                 }
  316.                                 ps++;
  317.                             }
  318.                             ps--;
  319.                         }
  320.                     }
  321.                     break;
  322.                 case 'y':
  323.                 case 'Y':
  324.                     addStr((char*)buf.c_str());
  325.                     buf="";
  326.                     if(pStack.size()>1){
  327.                         cnt=pStack.top();
  328.                         pStack.pop();
  329.                         ccp=pStack.top();
  330.                         pStack.pop();
  331.                         if(cnt<=ccp){
  332.                             ps++;
  333.                             cnt=1;
  334.                             while(cnt){
  335.                                 if(fName[ps]=='.'){
  336.                                     switch(fName[++ps]){
  337.                                         case 'w':
  338.                                         case 'W':
  339.                                         case 'x':
  340.                                         case 'X':
  341.                                         case 'y':
  342.                                         case 'Y':
  343.                                         case 'z':
  344.                                         case 'Z':
  345.                                             cnt++;
  346.                                             break;
  347.                                         case 'a':
  348.                                         case 'A':
  349.                                             cnt--;
  350.                                             break;
  351.                                     }
  352.                                 }
  353.                                 ps++;
  354.                             }
  355.                             ps--;
  356.                         }
  357.                     }
  358.                     break;
  359.                 case 'z':
  360.                 case 'Z':
  361.                     addStr((char*)buf.c_str());
  362.                     buf="";
  363.                     if(pStack.size()>1){
  364.                         cnt=pStack.top();
  365.                         pStack.pop();
  366.                         ccp=pStack.top();
  367.                         pStack.pop();
  368.                         if(cnt==ccp){
  369.                             ps++;
  370.                             cnt=1;
  371.                             while(cnt){
  372.                                 if(fName[ps]=='.'){
  373.                                     switch(fName[++ps]){
  374.                                         case 'w':
  375.                                         case 'W':
  376.                                         case 'x':
  377.                                         case 'X':
  378.                                         case 'y':
  379.                                         case 'Y':
  380.                                         case 'z':
  381.                                         case 'Z':
  382.                                             cnt++;
  383.                                             break;
  384.                                         case 'a':
  385.                                         case 'A':
  386.                                             cnt--;
  387.                                             break;
  388.                                     }
  389.                                 }
  390.                                 ps++;
  391.                             }
  392.                             ps--;
  393.                         }
  394.                     }
  395.                     break;
  396.                 case 'a':
  397.                 case 'A':
  398.                     addStr((char*)buf.c_str());
  399.                     buf="";
  400.                     ps-=2;
  401.                     cnt=-1;
  402.                     while(cnt){
  403.                         if(fName[ps]=='.'){
  404.                             switch(fName[ps+1]){
  405.                                 case 'w':
  406.                                 case 'W':
  407.                                 case 'x':
  408.                                 case 'X':
  409.                                 case 'y':
  410.                                 case 'Y':
  411.                                 case 'z':
  412.                                 case 'Z':
  413.                                     cnt++;
  414.                                     break;
  415.                                 case 'a':
  416.                                 case 'A':
  417.                                     cnt--;
  418.                                     break;
  419.                             }
  420.                         }
  421.                         ps--;
  422.                     }
  423.                     break;
  424.                 case 't':
  425.                 case 'T':
  426.                     addStr((char*)buf.c_str());
  427.                     buf = "";
  428.                     toTemp();
  429.                     break;
  430.                 case 'm':
  431.                 case 'M':
  432.                     addStr((char*)buf.c_str());
  433.                     buf = "";
  434.                     fromTemp();
  435.                     break;
  436.                 case 'd':
  437.                 case 'D':
  438.                     addStr((char*)buf.c_str());
  439.                     buf = "";
  440.                     return;
  441.                 case '+':
  442.                     addStr((char*)buf.c_str());
  443.                     buf = "";
  444.                     addition();
  445.                     break;
  446.                 case '-':
  447.                     addStr((char*)buf.c_str());
  448.                     buf = "";
  449.                     subtraction();
  450.                     break;
  451.                 case '!':
  452.                     addStr((char*)buf.c_str());
  453.                     buf = "";
  454.                     multiplication();
  455.                     break;
  456.                 case '$':
  457.                     addStr((char*)buf.c_str());
  458.                     buf = "";
  459.                     getQuotient();
  460.                     break;
  461.                 case '%':
  462.                     addStr((char*)buf.c_str());
  463.                     buf = "";
  464.                     getSurplus();
  465.                     break;
  466. #ifdef EXTENDED
  467.                 case '^':
  468.                     addStr((char*)buf.c_str());
  469.                     buf = "";
  470.                     getXor();
  471.                     break;
  472.                 case 'h':
  473.                 case 'H':
  474.                     addStr((char*)buf.c_str());
  475.                     buf = "";
  476.                     excHange();
  477.                     break;
  478. #endif
  479.                 default:
  480.                     buf += fName[--ps];
  481.             }
  482.         }else
  483.             buf += fName[ps];
  484.         ps++;
  485.     }
  486.     if(strlen((char*)buf.c_str())>0)addStr((char*)buf.c_str());
  487. }
  488. inline stack<int> Pxem::getStack() const{   return pStack;}
  489. inline void Pxem::print(){while(out());}
  490. inline bool Pxem::out(){
  491.     if(pStack.empty())return false;
  492.     int aaa=pStack.top();
  493.     putchar(aaa);
  494.     pStack.pop();
  495.     return true;
  496. }
  497. inline void Pxem::numOut(){
  498.     if(pStack.empty())return;
  499.     int aaa=pStack.top();
  500.     printf("%d",aaa);
  501.     pStack.pop();
  502. }
  503. inline void Pxem::input(){
  504.     int aaa=getchar();
  505.     pStack.push(aaa);
  506. }
  507. inline void Pxem::numInput(){
  508.     int aaa;
  509.     scanf("%d",&aaa);
  510.     pStack.push(aaa);
  511. }
  512. inline void Pxem::copy(){
  513.     int i=pStack.top();
  514.     pStack.push(i);
  515. }
  516. inline void Pxem::throwAway(){if(!pStack.empty())pStack.pop();}
  517. void Pxem::inverse(){
  518.     queue<int>fuga;
  519.     while(!pStack.empty()){
  520.         fuga.push((int)pStack.top());
  521.         pStack.pop();
  522.     }
  523.     while(!fuga.empty()){
  524.         pStack.push(fuga.front());
  525.         fuga.pop();
  526.     }
  527. }
  528. inline void Pxem::fileRead(){addStr(fCont);}
  529. void Pxem::emu(){
  530.     Pxem newPxem(fCont,fCont,pStack);
  531.     newPxem.run();
  532.     stack<int>aaa=newPxem.getStack();
  533.     stack<int>bbb;
  534.     while(!aaa.empty()){
  535.         bbb.push((int)aaa.top());
  536.         aaa.pop();
  537.     }
  538.     while(!bbb.empty()){
  539.         pStack.push(bbb.top());
  540.         bbb.pop();
  541.     }
  542. }
  543. inline void Pxem::getRand(){
  544.     int aaa=rand()%pStack.top();
  545.     pStack.pop();
  546.     pStack.push(aaa);
  547. }
  548. inline void Pxem::toTemp(){
  549.     if(pStack.empty())return;
  550.     temp=pStack.top();
  551.     pStack.pop();
  552.     used=true;
  553. }
  554. inline void Pxem::fromTemp(){
  555.     if(used)pStack.push(temp);
  556. }
  557. void Pxem::addition(){
  558.     if(pStack.size()<2)return;
  559.     int aa=pStack.top();
  560.     pStack.pop();
  561.     int bb=pStack.top();
  562.     pStack.pop();
  563.     pStack.push(aa+bb);
  564. }
  565. void Pxem::subtraction(){
  566.     if(pStack.size()<2)return;
  567.     int aa=pStack.top();
  568.     pStack.pop();
  569.     int bb=pStack.top();
  570.     pStack.pop();
  571.     pStack.push(abs(aa-bb));
  572. }
  573. void Pxem::multiplication(){
  574.     if(pStack.size()<2)return;
  575.     int aa=pStack.top();
  576.     pStack.pop();
  577.     int bb=pStack.top();
  578.     pStack.pop();
  579.     pStack.push(aa*bb);
  580. }
  581. void Pxem::getQuotient(){
  582.     if(pStack.size()<2)return;
  583.     int aa=pStack.top();
  584.     pStack.pop();
  585.     int bb=pStack.top();
  586.     pStack.pop();
  587.     pStack.push(aa>bb?aa/bb:bb/aa);
  588. }
  589. void Pxem::getSurplus(){
  590.     if(pStack.size()<2)return;
  591.     int aa=pStack.top();
  592.     pStack.pop();
  593.     int bb=pStack.top();
  594.     pStack.pop();
  595.     pStack.push(aa>bb?aa%bb:bb%aa);
  596. }
  597. void Pxem::getXor(){
  598.     if(pStack.size()<2)return;
  599.     int aa=pStack.top();
  600.     pStack.pop();
  601.     int bb=pStack.top();
  602.     pStack.pop();
  603.     pStack.push(aa^bb);
  604. }
  605. void Pxem::excHange(){
  606.     if(pStack.size()<2)return;
  607.     int aa=pStack.top();
  608.     pStack.pop();
  609.     int bb=pStack.top();
  610.     pStack.pop();
  611.     pStack.push(aa);
  612.     pStack.push(bb);
  613. }
  614. void Pxem::addStr(char* str){
  615.     int leng=strlen(str);
  616.     while(leng--)pStack.push((int)str[leng]);
  617. }
  618. int main(){
  619.     //puts(FILENAME),puts(CONTENT);
  620.     Pxem(FILENAME,CONTENT).run();
  621. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement