Nbrevu

Tuenti Contest 2 (Pablo Moreno)

Jun 20th, 2011
1,017
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.     Author: Pablo Moreno Olalla
  3.     Email address: darthbrevu@yahoo.es
  4. */
  5. #include "BigNumber.h"
  6.  
  7. #include <list>
  8. #include <cstdio>
  9. #include <string>
  10. #include <iostream>
  11. #include <algorithm>
  12.  
  13. using namespace std;
  14.  
  15. inline bool add(const list<Number> &in,Number &out) {
  16.     if (in.empty()) return false;
  17.     list<Number>::const_iterator it=in.begin();
  18.     out=*it;
  19.     list<Number>::const_iterator end=in.end();
  20.     for (++it;it!=end;++it) out+=*it;
  21.     return true;
  22. }
  23.  
  24. inline bool mul(const list<Number> &in,Number &out) {
  25.     if (in.empty()) return false;
  26.     list<Number>::const_iterator it=in.begin();
  27.     out=*it;
  28.     list<Number>::const_iterator end=in.end();
  29.     for (++it;it!=end;++it) out*=*it;
  30.     return true;
  31. }
  32.  
  33. inline bool sub(const list<Number> &in,Number &out) {
  34.     if (in.empty()) return false;
  35.     list<Number>::const_reverse_iterator it=in.rbegin();
  36.     out=*it;
  37.     out.flipSign();
  38.     list<Number>::const_reverse_iterator rend=in.rend();
  39.     for (++it;it!=rend;++it) out+=*it;
  40.     return true;
  41. }
  42.  
  43. string numberChrs="+-0123456789";
  44.  
  45. string validChars="=#@";
  46.  
  47. bool parse(const string &in,Number &out,size_t &pos);
  48.  
  49. bool parseNumber(const string &in,Number &out,size_t &pos)  {
  50.     size_t pos2=in.find_first_not_of(numberChrs,pos);
  51.     if (pos2==string::npos) pos2=in.size();
  52.     try {
  53.         out=Number(in.substr(pos,pos2-pos));
  54.     }   catch (const runtime_error &)   {
  55.         return false;
  56.     }
  57.     pos=pos2;
  58.     return true;
  59. }
  60.  
  61. bool parseExpr(const string &in,Number &out,size_t &pos)    {
  62.     //Whenever this method is called, we're sure that the first character is "^". So, skip it.
  63.     ++pos;
  64.     while (pos<in.size()&&in[pos]==' ') ++pos;
  65.     if (pos==in.size()) return false;
  66.     char op=in[pos];
  67.     if (validChars.find(op)==string::npos) return false;
  68.     ++pos;
  69.     list<Number> parsed;
  70.     Number tmpN;
  71.     for (;;)    {
  72.         while (pos<in.size()&&in[pos]==' ') ++pos;
  73.         if (pos==in.size()) return false;
  74.         if (in[pos]=='$') break;
  75.         if (!parse(in,tmpN,pos)) return false;
  76.         parsed.push_back(tmpN);
  77.     }
  78.     ++pos;  //So we point just AFTER the '$'.
  79.     if (op=='=') return add(parsed,out);
  80.     else if (op=='#') return mul(parsed,out);
  81.     else if (op=='@') return sub(parsed,out);
  82. }
  83.  
  84. bool parse(const string &in,Number &out,size_t &pos)    {
  85.     if (pos>=in.size()) return false;
  86.     while (in[pos]==' ')    {
  87.         ++pos;
  88.         if (pos>=in.size()) return false;
  89.     }
  90.     //Not sure if this is correct.
  91.     if (in[pos]=='^') return parseExpr(in,out,pos);
  92.     else if (numberChrs.find(in[pos])) return parseNumber(in,out,pos);
  93.     else return false;
  94. }
  95.  
  96. int main(int argc,char **argv)  {
  97.     //The first two lines are not strictly necessary, but make the code a little more handy.
  98.     if (argc>=2) freopen(argv[1],"r",stdin);
  99.     if (argc>=3) freopen(argv[2],"w",stdout);
  100.     string tmp;
  101.     Number n;
  102.     size_t pos;
  103.     do  {
  104.         pos=0;
  105.         getline(cin,tmp);
  106.         if (parse(tmp,n,pos)) cout<<static_cast<string>(n)<<endl;
  107.     }   while (!cin.eof());
  108.     return 0;
  109. }
RAW Paste Data