2009-11-11 73 views
3

在小策士的第9章中,作者提出了以下兩種功能將Little Schemer的Q和P函數轉換爲Common Lisp?

(define Q 
    (lambda (str n) 
    (cond 
     ((zero? (remainder (first$ str) n)) 
     (Q (second$ str) n)) 
     (t (build (first$ str) 
     (lambda () 
      (Q (second$ str) n))))))) 

(define P 
    (lambda (str) 
    (build (first$ str)(lambda() (P (Q str (first$ str))))))) 

,並建議他們與以下執行評估:

(frontier (P (second$ (second$ int))) 10) 

你會怎麼寫P和Q Common Lisp中的函數?

(我有翻譯在Y Combinator的自己 - 但我發現這一個挑戰)

--Helper Functions--

(define frontier 
    (lambda (str n) 
    (cond 
     ((zero? n) (quote())) 
     (t (cons (first$ str) (frontier (second$ str) (sub1 n))))))) 

(define str-maker 
    (lambda (next n) 
    (build n (lambda() (str-maker next (next n)))))) 

(define int (str-maker add1 0)) 

(define second$ 
    (lambda (str) 
    ((second str)))) 

(define first$ first) 

(define build 
    (lambda (a1 a2) 
    (cond 
     (t (cons a1 
     (cons a2 (quote()))))))))) 

(define first 
    (lambda (p) 
    (cond 
     (t (car p))))) 

(define second 
    (lambda (p) 
    (cond 
     (t (car (cdr p)))))) 

(define add1 
    (lambda (n) 
    (+ 1 n))) 

(define remainder 
    (lambda (n m) 
    (cond 
     (t (- n (* m (/ n m)))))) 

(免責聲明 - 這是不是一門功課的問題 - 這是我的理解和學習)

+0

爲什麼'Q'和'frontier'定義完全一樣? 「second $」和「first $」的定義是什麼(它們與「second」和「first」相同)? – Svante 2009-11-11 17:13:55

+0

謝謝 - 更正 – hawkeye 2009-11-11 21:39:40

回答

6

我認爲:

  • P中的定義,用「(Q(STR(第一個$ str)))「你的意思是:」(Q str(first $ str))「,因爲Q是一個雙參數函數。
  • 構建是做一個幫手創造一件對第一$和第二$工作:列表

考慮到這一點,直接翻譯計劃到Common Lisp的給出了:

(defun first$ (list) (first list)) 
(defun second$ (list) (funcall (second list))) 
(defun build (a b) (list a b)) 

(defun frontier (str n) 
    (if (zerop N) 
    () 
    (cons (first$ str) (frontier (second$ str) (1- n))))) 

(defun str-maker (next n) 
    (list n (lambda() (str-maker next (funcall next n))))) 

(setq int-maker (str-maker #'1+ 0)) 

(defun Q (str n) 
    (if (zerop (rem (first$ str) n)) 
    (Q (second$ str) n) 
    (list (first$ str) (lambda() (Q (second$ str) n))))) 

(defun P (str) 
    (list (first$ str) (lambda() (P (Q str (first$ str)))))) 

(frontier (P (second$ (second$ int-maker))) 10) 

誰最後一行返回:

(2 3 5 7 11 13 17 19 23 29) 

這是一個衆所周知的系列,所以我假設翻譯是成功的:-)