CS 3343/3341
  Introduction to Algorithms  
  Roman Numeral  
Conversion

The top row gives Java and C programs that convert an input integer into traditional Roman numbers. They use a straightforward greedy strategy that works perfectly. Note that every other iteration, the inner while loop is executed at most once.

The second row does exactly the same conversion in a way that is difficult to figure out, using as data only a single string of length 7. (The best program I ever wrote!)

The table at the bottom gives a even more thoroughly obfuscated Roman numeral conversion program. First is the C source code. Second is the command line to invoke the compiler. On Unix systems the executable will be named a.out by default. (Try it out!)

Roman Numeral Conversion
JavaC
// Roman.java: convert to Roman Numerals
public class Roman {





   public static void main(String[] args) {
      int r = Integer.parseInt(args[0]);
      System.out.println(trans(r));
   }




   static String trans(int r){
      String[] s = 
         {"M","CM","D","CD","C","XC",
          "L","XL","X","IX","V","IV","I"};
      int[] u = 
         {1000, 900, 500, 400, 100, 90,
            50, 40, 10, 9, 5, 4, 1};
      String t = "";
      for (int i = 0; i < 13; i++)
         while (r >= u[i]) {
            t += s[i];
            r -= u[i];
         }
      return t;
   }
}
// roman.c: convert to Roman Numerals
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* trans(int , char* );

int main(){
   int r;
   scanf("%i", &r);
   char* t = (char*)malloc(20); 
   t[0] = '\0';
   printf("%s\n", trans(r, t));
}

char* trans(int r, char* t){
   char* s[] = 
      {"M","CM","D","CD","C","XC",
       "L","XL","X","IX","V","IV","I"};
   int u[] = 
      {1000, 900, 500, 400, 100, 90,
       50, 40, 10, 9, 5, 4, 1};
   int i;
   for (i = 0; i < 13; i++)
      while (r >= u[i]) {
         strcat(t, s[i]);
         r -= u[i];
      }
   return t;
}
// RomanWeird.java: obscure conversion
public class RomanWeird {

   public static void main(String[] args) {
      int r = Integer.parseInt(args[0]);
      System.out.println(trans(r));
   }

   static String trans(int r){
      String s = "IVXLCDM", t = "";
      int y = 1000, k = 13, x = 0;
      while(k > 0){
         if (k%4 == 1){
            x = y;
            y = x/10;
         }
         x -= y*(k%4-1)*(k%4-1);
         while(r >= x){
            r -= x;
            if (k%2 == 0)
               t += s.charAt((k-2)/4*2);
            t += s.charAt((k+2)/2-1);
         }
         k--;
      }
      return t;
   }
}
// romanweird.c: obscure conversion
main(){
   int r;
   do{
      scanf("%i",&r);
      trans(r);
   } while(r);
}
trans(int r){
   char rom[] = "IVXLCDM";
   int y = 1000, k = 13, x;
   while(k > 0){
      if(k%4 == 1){
         x = y;
         y = x/10;
      }
      x -= y*(k%4-1)*(k%4-1);
      while(r >= x){
         r -= x;
         if( k%2 == 0)
            putchar(rom[(k-2)/4*2]);
         putchar(rom[(k+2)/2-1]);
      }
      k--;
   }
   putchar(10);
}

Obfuscated Roman Numeral Conversion, First C source code ("roman.c"), then the C compiler command line (executable: "a.out")

 #include <stdio.h>
 M I IV;XCIX XIX"%i",&IV);XL(IV);}V IV);}XL(I IV){CIX XC[]=L;I IX=VI*VI*VI*VI*VI-VI*VI-VI-VI,C=VI*VI-VI+CX,D;V C>VI-XI-XI){CXC CM==CX){D=IX;IX=D/(VI*XI+XI);}D-=IX*CD*CD;V IV>=D){IV-=D;CXC C%XI==XI-CX-CX)X XC[((C-XI)/VI)*XI]);X XC[(C+XI)/XI-CX]);}C--;}X VI*XI+XI);}


cc -DVI=4 -DCX=1 -DX="putchar(" -DV="while(" -DCM=C%VI -DI=int -DCD="(CM-CX)" -DL='"IVXLCDM"' -DM="main(){" -DXIX="scanf(" -DCXC="if(" -DCIX=char -DXCIX="do{" -DXI=2 roman.c


Revision date: 2011-12-059. (Please use ISO 8601, the International Standard Date and Time Notation.)