I had a couple funny ideas over lunch today. One of which was a loose connection to run length encoding and your compressed tables. Nothing groundbreaking but I thought I'd share my application to the Roman Numeral example:
(defun arabic->roman (i)
(assert (and (integerp i) (<= 0 i 3999)))
(let ((store "IIIVIIIXXXLXXXCCCDCCCMMM")
(run #(0 0 0 0 2 3 3 3 3 6))
(length #(0 1 2 3 2 1 2 3 4 2)))
(defun digit->roman (power &aux (digit (mod (floor i (expt 10 power)) 10)))
(make-array
(list (aref length digit))
:element-type 'character
:displaced-to store
:displaced-index-offset (+ (* 7 power) (aref run digit))))
(write-string (digit->roman 3))
(write-string (digit->roman 2))
(write-string (digit->roman 1))
(write-string (digit->roman 0)))
nil)