(def '0 '()) (def '1 '(1)) (def '2 '(2 1)) (def '3 '(3 2 1)) (def '4 '(4 3 2 1)) (def '5 '(5 4 3 2 1)) (def '+ append) (def 'sub1 cdr) (defun - (a b) (if (eq b 0) a (- (cdr a) (cdr b)))) (defun * (a b) (if (eq a 0) 0 (+ b (* b (cdr a))))) (defun length-equal (a b) (if (null a) (null b) (if (null b) 'nil (length-equal (cdr a) (cdr b))))) (defun length-less (a b) (if (null a) (not (null b)) (if (null b) 'nil (length-less (cdr a) (cdr b))))) (def '== length-equal) (def '< length-less) (assert (== '(7 6 5 4 3 2 1) (+ '(3 2 1) '(4 3 2 1)))) (assert (== '(12 11 10 9 8 7 6 5 4 3 2 1) (* '(3 2 1) '(4 3 2 1)))) (assert (< 2 3)) (assert (not (< 3 3))) (assert (not (< 4 3))) (assert (not (< 0 0))) (assert (== 2 (- 2 0))) (assert (== 1 (- 2 1))) (assert (== 0 (- 2 2))) (assert (== 0 (- 0 0))) (def '10 (* 2 5)) (def '50 (* 10 5)) (def '100 (* 10 10)) (defun roman-do-I (x) (if (< x 1) '. (implode (list 'I (roman-do-I (- x 1)))))) (defun roman-do-V (x) (if (< x 5) (roman-do-I x) (implode (list 'V (roman-do-V (- x 5)))))) (defun roman-do-X (x) (if (< x 10) (roman-do-V x) (implode (list 'X (roman-do-X (- x 10)))))) (defun roman-do-L (x) (if (< x 50) (roman-do-X x) (implode (list 'L (roman-do-L (- x 50)))))) (defun roman-do-C (x) (if (< x 100) (roman-do-L x) (implode (list 'C (roman-do-C (- x 100)))))) (defun roman (x) (roman-do-C x)) (assert-equal '. (roman 0)) (assert-equal 'I. (roman 1)) (assert-equal 'III. (roman 3)) (assert-equal 'V. (roman 5)) (assert-equal 'VI. (roman (+ 5 1))) (assert-equal 'XII. (roman (+ 10 2))) (assert-equal 'LX. (roman (+ 50 10))) (assert-equal 'CX. (roman (+ 100 10))) (defun reverse-range (n) (if (eq n 0) (list) (let n-1 (sub1 n) (cons n-1 (reverse-range n-1))))) (defun range (n) (reverse (reverse-range n))) (assert-equal '( VIIII. VIII. VII. VI. V. IIII. III. II. I. . ) (mapcar (reverse-range 10) roman)) (assert-equal '( . I. II. III. IIII. V. VI. VII. VIII. VIIII. ) (mapcar (range 10) roman)) (defun peano (x) (let xx (explode x) a (car xx) (if (str-le a '9) (peano-of-decimal xx) (peano-of-roman xx)))) (defun peano-of-decimal (xx) (if (length-equal xx 1) (peano-of-decimal-digit (car xx)) (let rxx (reverse xx) units (car rxx) others (reverse (cdr rxx)) (+ (peano-of-decimal-digit units) (* 10 (peano-of-decimal others)))))) (defun peano-of-decimal-digit (d) (if (eq '0 d) 0 (+ 1 (peano-of-decimal-digit (pred d))))) (def 'roman-lookup-list (list 'I 1 'V 5 'X 10 'L 50 'C 100 'i 1 'v 5 'x 10 'l 50 'c 100)) (defun peano-of-roman-digit (d) (assoc d roman-lookup-list)) (defun peano-of-roman (xx) (if (null xx) 0 (+ (peano-of-roman-digit (car xx)) (peano-of-roman (cdr xx))))) (defun assoc (key lst) (if (null lst) 'nil (if (eq key (first lst)) (second lst) (assoc key (cddr lst))))) (assert (length-equal 0 (peano '0))) (assert (length-equal 1 (peano '1))) (assert (length-equal 5 (peano '5))) (assert (length-equal 10 (peano '10))) (assert (length-equal (+ 2 (* 4 10)) (peano '42))) (assert (length-equal (+ 2 (* 4 100)) (peano '402))) (assert-equal 'CLXXXXVIIII. (roman (peano '199))) (assert-equal 'CLXXVIII. (roman (peano 'CLXXVIII))) (assert-equal 'CLXXVIII. (roman (peano 'clxxviii))) (defun div (a b) (if (length-less a b) 0 (+ 1 (div (- a b) b)))) (defun decimal (x) (if (length-less x 10) (decimal-digit x) (let quotient (div x 10) remainder (- x (* quotient 10)) (implode (list (decimal quotient) (decimal remainder)))))) (defun decimal-digit (d) (if (eq d 0) '0 (succ (decimal-digit (sub1 d)))))