Comment detail

正整数のゲーデル数化? (Nested Flatten)

普通に書くとイマイチ面白くないかと思ってひねり出したコード。牛刀割鶏な感はありますが、ジェネレータを使って繰り返しを行うマクロを定義して、これに素数ジェネレータを渡しています。これくらいだと Lisp マクロの入門用としていい題材だったかもしれません。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
(defun make-prime-generator ()
  (let ((primes ()))
    (lambda ()
      (if (null primes)
          (setf primes (list 2))
        (do ((x (1+ (car primes)) (1+ x)))
            ((notany (lambda (p) (= (rem x p) 0)) primes)
             (push x primes))))
      (car primes))))

(defmacro loop-with-generator ((var generator)
                               (end-test &rest result) &body body)
  (let ((gvar (gensym)))
    `(do ((,gvar ,generator))
         (,end-test ,@result)
       (let ((,var (funcall ,gvar))) ,@body))))

(defun goedel (n)
  (let ((digits (do ((m n (floor m 10)) (ds ()))
                    ((= m 0) ds)
                  (push (rem m 10) ds)))
        (code 1))
    (loop-with-generator (p (make-prime-generator))
                         ((null digits) code)
      (setf code (* (expt p (pop digits)) code)))))

Index

Feed

Other

Link

Pathtraq

loading...