00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <math.h>
00020
00021
00022 #include <iostream>
00023 #include <string>
00024 #include <vector>
00025 #include <stdexcept>
00026 using namespace std;
00027
00028 #include <boost/algorithm/string/trim.hpp>
00029 using namespace boost;
00030 using namespace boost::algorithm;
00031
00032
00033
00034
00036 class SVMException : public std::exception
00037 {
00038 private:
00039 const std::string Message;
00040
00041 public:
00045 SVMException( const std::string & Msg ) : Message( Msg )
00046 {}
00047
00051 SVMException( const char * Msg ) : Message( Msg )
00052 {}
00053
00057 virtual const char * what( void ) const throw()
00058 { return Message.c_str(); }
00059
00061 virtual ~SVMException() throw () {}
00062
00063 private:
00064 SVMException();
00065 };
00066
00067
00068
00069
00071 class SCalculator
00072 {
00073 public:
00077 SCalculator( const vector< string > & code ) :
00078 Code( code )
00079 {
00080
00081 Stack.reserve( Code.size() );
00082 }
00083
00087 double Calculate( const double & Value )
00088 {
00089
00090 Stack.clear();
00091
00092
00093 for ( vector< string >::const_iterator k( Code.begin() );
00094 k != Code.end(); ++k )
00095 {
00096 if ( *k == "ADD" )
00097 {
00098 double Temp( Stack.back() );
00099 Stack.pop_back();
00100 Stack[ Stack.size() - 1 ] = Stack.back() + Temp;
00101 continue;
00102 }
00103 if ( *k == "SUB" )
00104 {
00105 double Temp( Stack.back() );
00106 Stack.pop_back();
00107 Stack[ Stack.size() - 1 ] = Stack.back() - Temp;
00108 continue;
00109 }
00110 if ( *k == "DIV" )
00111 {
00112 double Temp( Stack.back() );
00113 Stack.pop_back();
00114 Stack[ Stack.size() - 1 ] = Stack.back() / Temp;
00115 continue;
00116 }
00117 if ( *k == "MULT" )
00118 {
00119 double Temp( Stack.back() );
00120 Stack.pop_back();
00121 Stack[ Stack.size() - 1 ] = Stack.back() * Temp;
00122 continue;
00123 }
00124 if ( *k == "NEGATE" )
00125 {
00126 Stack[ Stack.size() - 1 ] = - Stack.back();
00127 continue;
00128 }
00129 if ( *k == "VALUE" )
00130 {
00131 Stack.push_back( Value );
00132 continue;
00133 }
00134 if ( *k == "SIN" )
00135 {
00136 Stack[ Stack.size() - 1 ] = sin( Stack.back() );
00137 continue;
00138 }
00139 if ( *k == "COS" )
00140 {
00141 Stack[ Stack.size() - 1 ] = cos( Stack.back() );
00142 continue;
00143 }
00144 if ( (*k).compare( 0, 4, "PUSH" ) == 0 )
00145 {
00146 Stack.push_back( atof( (*k).c_str() + sizeof( "PUSH" ) ) );
00147 continue;
00148 }
00149
00150 throw SVMException( "Unexpected virtual machine command '" +
00151 *k + "'" );
00152 }
00153
00154 if ( Stack.size() != 1 )
00155 {
00156 throw SVMException( "Unexpected size of stack at the end "
00157 "of calculation. " );
00158 }
00159
00160 return Stack.back();
00161 }
00162
00163 private:
00164 vector< string > Code;
00165 vector< double > Stack;
00166 };
00167
00168
00169
00170
00171
00172
00173 int main( int argc, char ** argv )
00174 {
00175
00176
00177 if ( argc >= 3 )
00178 {
00179
00180 cerr << "Unexpected arguments. Type " << argv[ 0 ]
00181 << " --help for usage." << endl;
00182 return 1;
00183 }
00184
00185
00186
00187 if ( ( argc == 2 && string( argv[ 1 ] ) == "-h" ) ||
00188 ( argc == 2 && string( argv[ 1 ] ) == "--help" ) )
00189 {
00190 cout << "Usage: " << argv[ 0 ] << " <double value | -h | --help>" << endl;
00191 return 0;
00192 }
00193
00194
00195
00196 double Value( 0.0 );
00197 if ( argc == 2 )
00198 {
00199 Value = atof( argv[ 1 ] );
00200 }
00201
00202
00203
00204 vector< string > Code;
00205
00206
00207
00208 for ( ; ; )
00209 {
00210 char Buffer[ 256 ];
00211
00212 cin.getline( Buffer, sizeof( Buffer ) );
00213
00214 if ( cin.eof() ) break;
00215 if ( cin.fail() )
00216 {
00217 cerr << "Wrong input stream" << endl;
00218 return 2;
00219 }
00220
00221 string Line( Buffer );
00222
00223 trim( Line );
00224 Code.push_back( Line );
00225 }
00226
00227
00228 try
00229 {
00230
00231
00232 SCalculator Calculator( Code );
00233
00234
00235 cout << Calculator.Calculate( Value ) << endl;
00236 }
00237 catch ( exception & Exception )
00238 {
00239 cerr << Exception.what() << endl;
00240 return 3;
00241 }
00242 catch ( ... )
00243 {
00244 cerr << "Unknown exception." << endl;
00245 return 3;
00246 }
00247
00248 return 0;
00249 }
00250