#include <cassert>
#include <initializer_list>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using namespace std;
int fromRoman(const string& x) {
auto first = crbegin(x);
const auto last = crend(x);
auto decimalDigitFromRoman = [&](char unit, char five, char ten) {
int num = 0;
for (; first != last && *first == unit; ++first) ++num;
while (first != last && (*first == ten || *first == five)) {
num += *first == ten ? 10 : 5;
for (++first; first != last && *first == unit; ++first) --num;
}
return num;
};
int num = 0, pow = 1;
for (auto syms : {"IVX", "XLC", "CDM"}) {
num += decimalDigitFromRoman(syms[0], syms[1], syms[2]) * pow;
pow *= 10;
}
return num;
}
int main() {
vector<pair<string, int>> testRomans{
{"I", 1}, {"II", 2}, {"III", 3}, {"IV", 4}, {"V", 5},
{"VI", 6}, {"VII", 7}, {"VIII", 8}, {"IX", 9}, {"X", 10},
{"XI", 11}, {"XII", 12}, {"XIII", 13}, {"XIV", 14}, {"XV", 15},
{"XVI", 16}, {"XVII", 17}, {"XVIII", 18}, {"XIX", 19}, {"XX", 20},
{"XXI", 21}, {"XXII", 22}, {"XXIII", 23}, {"XXIV", 24}, {"XXV", 25},
{"XXVI", 26}, {"XXVII", 27}, {"XXVIII", 28}, {"XXIX", 29}, {"XXX", 30},
{"XL", 40}, {"L", 50}, {"LIX", 59}, {"LX", 60}, {"LXIV", 64},
{"XCIX", 99}, {"C", 100}, {"MCMXCIX", 1999}, {"MMXIV", 2014}, {"IIII", 4},
{"VIIII", 9}, {"XIIX", 18}, {"XIIIII", 15}, {"MDCCCCX", 1910}, {"MDCDIII", 1903},
{"XXXXXX", 60}};
for (const auto& x : testRomans) {
auto num = fromRoman(x.first);
assert(num == x.second);
cout << num << ", ";
}
cout << endl;
}
I2luY2x1ZGUgPGNhc3NlcnQ+CiNpbmNsdWRlIDxpbml0aWFsaXplcl9saXN0PgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8dmVjdG9yPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmludCBmcm9tUm9tYW4oY29uc3Qgc3RyaW5nJiB4KSB7CiAgICBhdXRvIGZpcnN0ID0gY3JiZWdpbih4KTsKICAgIGNvbnN0IGF1dG8gbGFzdCA9IGNyZW5kKHgpOwoKICAgIGF1dG8gZGVjaW1hbERpZ2l0RnJvbVJvbWFuID0gWyZdKGNoYXIgdW5pdCwgY2hhciBmaXZlLCBjaGFyIHRlbikgewogICAgICAgIGludCBudW0gPSAwOwogICAgICAgIGZvciAoOyBmaXJzdCAhPSBsYXN0ICYmICpmaXJzdCA9PSB1bml0OyArK2ZpcnN0KSArK251bTsKICAgICAgICB3aGlsZSAoZmlyc3QgIT0gbGFzdCAmJiAoKmZpcnN0ID09IHRlbiB8fCAqZmlyc3QgPT0gZml2ZSkpIHsKICAgICAgICAgICAgbnVtICs9ICpmaXJzdCA9PSB0ZW4gPyAxMCA6IDU7CiAgICAgICAgICAgIGZvciAoKytmaXJzdDsgZmlyc3QgIT0gbGFzdCAmJiAqZmlyc3QgPT0gdW5pdDsgKytmaXJzdCkgLS1udW07CiAgICAgICAgfQogICAgICAgIHJldHVybiBudW07CiAgICB9OwoKICAgIGludCBudW0gPSAwLCBwb3cgPSAxOwogICAgZm9yIChhdXRvIHN5bXMgOiB7IklWWCIsICJYTEMiLCAiQ0RNIn0pIHsKICAgICAgICBudW0gKz0gZGVjaW1hbERpZ2l0RnJvbVJvbWFuKHN5bXNbMF0sIHN5bXNbMV0sIHN5bXNbMl0pICogcG93OwogICAgICAgIHBvdyAqPSAxMDsKICAgIH0KCiAgICByZXR1cm4gbnVtOwp9CgppbnQgbWFpbigpIHsKICAgIHZlY3RvcjxwYWlyPHN0cmluZywgaW50Pj4gdGVzdFJvbWFuc3sKICAgICAgICB7IkkiLCAxfSwgICAgICB7IklJIiwgMn0sICAgICB7IklJSSIsIDN9LCAgICAgICAgeyJJViIsIDR9LCAgICAgICAgIHsiViIsIDV9LAogICAgICAgIHsiVkkiLCA2fSwgICAgIHsiVklJIiwgN30sICAgIHsiVklJSSIsIDh9LCAgICAgICB7IklYIiwgOX0sICAgICAgICAgeyJYIiwgMTB9LAogICAgICAgIHsiWEkiLCAxMX0sICAgIHsiWElJIiwgMTJ9LCAgIHsiWElJSSIsIDEzfSwgICAgICB7IlhJViIsIDE0fSwgICAgICAgeyJYViIsIDE1fSwKICAgICAgICB7IlhWSSIsIDE2fSwgICB7IlhWSUkiLCAxN30sICB7IlhWSUlJIiwgMTh9LCAgICAgeyJYSVgiLCAxOX0sICAgICAgIHsiWFgiLCAyMH0sCiAgICAgICAgeyJYWEkiLCAyMX0sICAgeyJYWElJIiwgMjJ9LCAgeyJYWElJSSIsIDIzfSwgICAgIHsiWFhJViIsIDI0fSwgICAgICB7IlhYViIsIDI1fSwKICAgICAgICB7IlhYVkkiLCAyNn0sICB7IlhYVklJIiwgMjd9LCB7IlhYVklJSSIsIDI4fSwgICAgeyJYWElYIiwgMjl9LCAgICAgIHsiWFhYIiwgMzB9LAogICAgICAgIHsiWEwiLCA0MH0sICAgIHsiTCIsIDUwfSwgICAgIHsiTElYIiwgNTl9LCAgICAgICB7IkxYIiwgNjB9LCAgICAgICAgeyJMWElWIiwgNjR9LAogICAgICAgIHsiWENJWCIsIDk5fSwgIHsiQyIsIDEwMH0sICAgIHsiTUNNWENJWCIsIDE5OTl9LCB7Ik1NWElWIiwgMjAxNH0sICAgeyJJSUlJIiwgNH0sCiAgICAgICAgeyJWSUlJSSIsIDl9LCAgeyJYSUlYIiwgMTh9LCAgeyJYSUlJSUkiLCAxNX0sICAgIHsiTURDQ0NDWCIsIDE5MTB9LCB7Ik1EQ0RJSUkiLCAxOTAzfSwKICAgICAgICB7IlhYWFhYWCIsIDYwfX07CgogICAgZm9yIChjb25zdCBhdXRvJiB4IDogdGVzdFJvbWFucykgewogICAgICAgIGF1dG8gbnVtID0gZnJvbVJvbWFuKHguZmlyc3QpOwogICAgICAgIGFzc2VydChudW0gPT0geC5zZWNvbmQpOwogICAgICAgIGNvdXQgPDwgbnVtIDw8ICIsICI7CiAgICB9CiAgICBjb3V0IDw8IGVuZGw7Cn0K