#include #include /* ** State machine for romantoint ** ** M D C L X V I ** 0: +1000/0 +500/0 +100/1 +50/0 +10/2 +5/0 +1/3 ** 1: +800/0 -- +100/0 +50/0 +10/2 +5/0 +1/3 ** 2: -- -- +80/0 +30/0 +10/2 +5/0 +1/3 ** 3: -- -- -- -- +8/0 +3/0 +1/3 ** */ int FromRoman(char *s) { int n=0; int prev=0; while (index(" \n\t",*s) == NULL) { switch (toupper(*s)) { case 'M': n += 1000 - prev*2; prev=0; break; case 'D': n += 500 - prev*2; prev=0; break; case 'C': n += 100; if (prev < 100) n -= 2*prev; prev=100; break; case 'L': n += 50; if (prev < 50) n -= 2*prev; prev=0; break; case 'X': n += 10; if (prev < 10) n -= 2*prev; prev=10; break; case 'V': n += 5; if (prev < 5) n -= 2*prev; prev=0; break; case 'I': n += 1; prev=1; break; } s++; } return n; } void PrintRoman(int n) { if (n<=0 || n>4999) { printf("out of range exception\n"); return; } while (n/1000) { printf("M"); n -= 1000; } switch(n/100) { case 0: break; case 1: printf("C"); break; case 2: printf("CC"); break; case 3: printf("CCC"); break; case 4: printf("CD"); break; case 5: printf("D"); break; case 6: printf("DC"); break; case 7: printf("DCC"); break; case 8: printf("DCCC"); break; case 9: printf("CM"); break; } n %= 100; switch(n/10) { case 0: break; case 1: printf("X"); break; case 2: printf("XX"); break; case 3: printf("XXX"); break; case 4: printf("XL"); break; case 5: printf("L"); break; case 6: printf("LX"); break; case 7: printf("LXX"); break; case 8: printf("LXXX"); break; case 9: printf("XC"); break; } n %= 10; switch(n) { case 0: break; case 1: printf("I"); break; case 2: printf("II"); break; case 3: printf("III"); break; case 4: printf("IV"); break; case 5: printf("V"); break; case 6: printf("VI"); break; case 7: printf("VII"); break; case 8: printf("VIII"); break; case 9: printf("IX"); break; } printf("\n"); } #define STACKSIZE 1024 int nitems=0; int stack[STACKSIZE]; int Pop() { if (!nitems) { printf("stack underflow\n"); return 0; } return stack[--nitems]; } void Push(int n) { if (nitems == STACKSIZE-1) { printf("stack overflow\n"); return; } stack[nitems++] = n; } int PrintTop(void) { if (!nitems) { printf("stack underflow\n"); return -1; } else { PrintRoman(stack[nitems-1]); return 0; } } int PerformAdd(void) { int x,y; if (nitems < 2) { printf("stack underflow\n"); return -1; } y = Pop(); x = Pop(); Push(x+y); return 0; } int PerformSub(void) { int x,y; if (nitems < 2) { printf("stack underflow\n"); return -1; } y = Pop(); x = Pop(); Push(x-y); return 0; } int PerformMul(void) { int x,y; if (nitems < 2) { printf("stack underflow\n"); return -1; } y = Pop(); x = Pop(); Push(x*y); return 0; } int PerformDiv(void) { int x,y; if (nitems < 2) { printf("stack underflow\n"); return -1; } y = Pop(); x = Pop(); if (y!=0) Push(x/y); else { printf("division by zero exception\n"); Push(x); } return 0; } main() { char line[256]; while (fgets(line,sizeof(line),stdin)) { if (line[0] == '=') PrintTop(); else if (line[0] == '+') PerformAdd(); else if (line[0] == '-') PerformSub(); else if (line[0] == '*') PerformMul(); else if (line[0] == '/') PerformDiv(); else { int n = FromRoman(line); if (n > 0) { Push(n); } } } }