99 Lisp ProblemsをLOOPマクロのみで解く。

L-99: Ninety-Nine Lisp Problems
リスト処理の問題集だそうだ。これをLOOPマクロのみで解いている。P01からP07まで解いた。
使っていい関数は引数のサイズによらずに定数時間で終了する関数のみ。つまり再帰呼び出しや#'EQUALは不可。ただし前にLOOPで書いた関数は使用して良い。

REVERSEくらいだと簡単だが

(DEFUN P05 (LIST)
  (LOOP :FOR ELEM :IN LIST
        :WITH ACC := NIL
     :DO (PUSH ELEM ACC)
     :FINALLY (RETURN ACC)))

(EXAMPLE (P05 '(A B C D E))
         => (E D C B A))

FLATTENになるともう…だめ…。

(DEFUN P07 (LIST)
  (LOOP :WITH ACC := NIL
        :WITH STACK := `(,LIST)
        :WITH LS
     :IF (NULL STACK)
       :RETURN (P05 ACC)
     :ELSE
       :DO
         (SETF LS (POP STACK))
         (LOOP :FOR SUBLS :ON LS
               :FOR ELEM := (CAR SUBLS)
            :WHILE (ATOM ELEM)
              :DO (PUSH ELEM ACC)
            :FINALLY
              (WHEN SUBLS
                (PUSH (CDR SUBLS) STACK)
                (PUSH (CAR SUBLS) STACK)))))

(EXAMPLE (P07 '((1 2 (3 4)) (5 (6 7 (8 9 (10) (11 (12)))) 13 (14) 15)))
         => (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))

(EXAMPLE (P07 '(1 () 3))
         => (1 NIL 3))

gist:481179 · GitHub