Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@manonthemat
Created January 19, 2015 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save manonthemat/22b31d0c4ea9300e6495 to your computer and use it in GitHub Desktop.
Save manonthemat/22b31d0c4ea9300e6495 to your computer and use it in GitHub Desktop.
first draft of a simple roman calculator
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <cmath>
#include <regex>
#include <sstream>
using namespace std;
string toString(const int& i) {
stringstream s;
s << i;
return s.str();
}
string roman_from_value(const int& inum) {
int temp {inum};
string result;
int m = inum / 1000;
for(int i=0; i<m; ++i) result += "M";
temp = temp - m*1000;
if(temp >= 900) {
result += "CM";
temp -= 900;
}
else if(temp >= 500) {
result += "D";
temp -= 500;
}
else if(temp >=400) {
result += "CD";
temp -= 400;
}
if(temp >= 100) {
int c = temp/100;
for(int i=0; i<c; ++i) result += "C";
temp = temp - c*100;
}
if(temp >= 90) {
result += "XC";
temp -= 90;
}
else if(temp >= 50) {
result += "L";
temp -= 50;
}
else if(temp >= 40) {
result += "XL";
temp -= 40;
}
if(temp >= 10) {
int x = temp/10;
for(int i=0; i<x; ++i) result += "X";
temp = temp - x*10;
}
if(temp == 9) {
result += "IX";
temp -= 9;
}
else if(temp >= 5) {
result += "V";
temp -= 5;
}
else if(temp == 4) {
result += "IV";
temp -= 4;
}
if(temp >= 1) {
int i = temp/1;
for(int j=0; j<i; ++j) result += "I";
}
return result;
}
int value_from_roman(const string& rval) {
map<char,int> roman;
roman['I'] = 1;
roman['V'] = 5;
roman['X'] = 10;
roman['L'] = 50;
roman['C'] = 100;
roman['D'] = 500;
roman['M'] = 1000;
int temp {0};
char previous_char {' '};
for(int i=rval.size()-1; i>=0; --i) {
if((rval[i] != previous_char) && (roman[rval[i]] < temp)) {
temp -= roman[rval[i]];
} else {
temp += roman[rval[i]];
}
previous_char = rval[i];
}
return temp;
}
class Roman_invalid {};
class Roman_int {
public:
Roman_int() {};
Roman_int(const string& rnum);
Roman_int(const int& inum);
int as_int() const { return ival; };
string as_roman() const { return rval; };
private:
string rval;
int ival;
};
Roman_int::Roman_int(const string& rnum) {
rval = rnum;
ival = value_from_roman(rval);
}
Roman_int::Roman_int(const int& inum) {
rval = roman_from_value(inum);
ival = inum;
}
ostream& operator<<(ostream& os, const Roman_int& r) {
return os << r.as_roman();
}
istream& operator>>(istream& is, Roman_int& r) {
string rval;
is >> rval;
if(!is) return is;
regex re("^[MDCLXVI]+");
if(regex_match(rval, re) != 1) throw Roman_invalid {};
r = Roman_int(rval);
return is;
}
int operator+(const Roman_int& r1, const Roman_int& r2) {
return r1.as_int() + r2.as_int();
}
int operator-(const Roman_int& r1, const Roman_int& r2) {
return r1.as_int() - r2.as_int();
}
int operator*(const Roman_int& r1, const Roman_int& r2) {
return r1.as_int() * r2.as_int();
}
int main() {
cout << "Roman Calculator" << endl;
try {
Roman_int r1, r2, result;
char op;
while(cin >> r1 >> op >> r2) {
if(op == '+') result = Roman_int(r1+r2);
else if(op == '-') result = Roman_int(r1-r2);
else if(op == '*') result = Roman_int(r1*r2);
else {
cerr << "Error detected. Exiting..." << endl;
}
cout << r1 << op << r2 << "=" << result << endl
<< r1.as_int() << op << r2.as_int() << '=' << result.as_int() << endl;
}
cout << "Exiting..." << endl;
} catch (Roman_invalid) {
cerr << "Invalid Roman detected. Exiting." << endl;
return 1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment