Optimal short-hand roman numeral generator
C++, 345 characters of code, 25021 roman numeral digits = 25366

int N[]={1,5,10,50,100,500,1000};int V(int s,int L){if(!L)return 0;int K=0,B,m=s%7+1;for(int k=1,b=7;k&lt;L;k++,b*=7){if(s/b%7&gt;=m){K=k;B=b;m=s/b%7;}}return K?V(s/B,L-K)-V(s%B,K):N[s%7]+V(s/7,L-1);}char r[99];char*f(int n){for(int L=1,B=7,i,j;1;L++,B*=7){for(i=0;i&lt;B;i++){if(V(i,L)==n){for(j=0;j&lt;L;j++){r[j]="IVXLCDM"[i%7];i/=7;}r[L]=0;return r;}}}}


deobfuscated a bit, with a driver:

int N[]={1,5,10,50,100,500,1000};
int V(int s,int L){
  if(!L)return 0;
  int K=0,B,m=s%7+1;
  for (int k=1,b=7;k&lt;L;k++,b*=7) {
    if(s/b%7&gt;=m){K=k;B=b;m=s/b%7;}
  }
  return K ? V(s/B,L-K)-V(s%B,K) : N[s%7]+V(s/7,L-1);
}
char r[99];
char *f(int n){
  for(int L=1,B=7;1;L++,B*=7) {
    for(int i=0;i&lt;B;i++) {
      if(V(i,L)==n){
        for(int j=0;j&lt;L;j++) {
          r[j]="IVXLCDM"[i%7];i/=7;
        }
        r[L]=0;
        return r;
      }
    }
  }
}
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
int main(int argc, char *argv[]) {
  printf("%s\n", f(atoi(argv[1])));
}


V computes the numerical value of a given roman numeral string s of length L.  Strings are encoded base 7 (first digit is s%7, second digit is s/7%7, ...).  Each digit is encoded with I=0, V=1, ..., M=6.  f does a brute-force enumeration of possible roman numeral strings to find one that V evaluates to n.

The total number of roman numeral digits is optimal.  The longest roman numeral needed for [-1000,3000] is 11 digits (e.g. -827=CMDDMLXXIII), which takes about 5 minutes on my machine.