Convert to and from the factorial number system

APL, 39 37 characters

{A B←(9⍴10)(⌽1+⍳9)⌽⍨'!'∊⍵⋄A⊥B⊤⍎⍵~'!'}


      {A B←(9⍴10)(⌽1+⍳9)⌽⍨'!'∊⍵⋄A⊥B⊤⍎⍵~'!'}'1234'
      {A B←(9⍴10)(⌽1+⍳9)⌽⍨'!'∊⍵⋄A⊥B⊤⍎⍵~'!'}'!54321'

Python 2.7 (163 157 152)

exec("b='';a=362880;j=int(i);x=9;"+'b+=`j//a`;j%=a;a/=x;x-=1;'*9,"a=x=1;b=0;"+'b+=a*int(i[-x]);x+=1;a*=x;'*~-len(i))['!'in i]
print int(b)

More readable version:

if'!'in i:a=x=1;b=0;c='b+=a*int(i[-x]);x+=1;a*=x;'*~-len(i)
exec c;print int(b)


Factoradic -> Decimal, when i is in the form !(number)
a=1   #Factorial value (multiplied every iteration)
x=1   #Index value
b=0   #Output
iterate ~-len(i) times:    #PSEUDOCODE! bitwisenot(a) = ~a = -a-1
    b+=a*int(i[-x])        #add the value of the xth last character in the factoradic #
    x+=1                   #Increment x
    a*=x                   #Set a to x!, (x-1)! * x = x!

Decimal -> Factoradic
b=''                       #Output
a=362880                   #Factorial value, set to 9! here
j=int(i)                   #Integer value of the input
x=9                        #Index value
iterate 9 times:           #PSEUDOCODE! This block is in an exec() loop
    b+=`j/a`               #Add floor(j/a) to b
    j%=a                   #Take out all multiples of a in j
    a/=x                   #Set a to (x-1)!, x! / x = (x-1)!
    x-=1                   #Decrement x

GolfScript (48 44 43 chars)


This is a self-contained program. The factoriadic => decimal conversion is quite slow, because it does a search using the decimal => factoriadic conversion rather than a direct base conversion.

The input format allows for a very short mode switch: .~ copies the input string and evaluates it, so if the input is just a number we end up with e.g. "1234" 1234 on the stack, and if it starts with ! (logical not, with any non-empty string being truthy) we end up with e.g. 0 30311 on the stack. Then the value at the bottom of the stack is truthy for decimal => factoriadic and falsy for factoriadic => decimal.