Python 201 characters
m={'IV':4,'IX':9,'XL':40,'XC':90,'CD':400,'CM':900,'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
f=lambda s:m[s] if s in m else(m[s[:2]]+f(s[2:])if s[:2]in m else m[s[0]]+f(s[1:]))
f(raw_input())
Example:
>>> m={'IV':4,'IX':9,'XL':40,'XC':90,'CD':400,'CM':900,'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000};f=lambda s:m[s] if s in m else(m[s[:2]]+f(s[2:])if s[:2]in m else m[s[0]]+f(s[1:]));f(raw_input())
MMMCMLXXXVII
3987
119 117 characters
>>> X=[dict(zip('MDCLXVI',(1e3,500,100,50,10,5,1)))[x]for x in raw_input()];sum((x,-x)[x<y]for x,y in zip(X,X[1:]))+X[-1]
MMMCMLXXXVII
3987.0
Expanded form:
>>> # Maps roman numbers to their decimal counterpart
>>> roman_map = dict(zip('MDCLXVI',(1e3,500,100,50,10,5,1)))
>>> # Maps the list of input number to the corresponding decimals
>>> X=[roman_map[x]for x in raw_input()]
>>> # A number will be added (x) or subtracted (-x) depending on its value vs the next number
>>> # For instance CM -> [100, 1000], 100 < 1000, therefore -100, +1000
>>> result = sum((x,-x)[x<y] for x,y in zip(X,X[1:])) # True = 1, False = 0
>>> # Adding the last element (which is always added)
>>> result += X[-1]
How should we represent ten thousand?
MMMMMMMMMM
or something else? – ProgramFOX – 2013-12-27T15:34:50.693@ProgramFOX That sounds right. I've changed the spec to under 10,000. – Ben Reich – 2013-12-27T15:37:37.873