Die Übersetzung der Q und P Funktion von The Little Schemer in Common Lisp?
-
19-09-2019 - |
Frage
In Kapitel 9 des Kleinen Schemer, stellt der Autor die folgenden beiden Funktionen
(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)))))))
und schlägt vor, dass sie mit der folgenden Ausführung bewertet werden:
(frontier (P (second$ (second$ int))) 10)
Wie würden Sie die P und Q-Funktionen in Common Lisp schreiben?
(Ich habe das Y-Combinator selbst übersetzt - aber ich finde dieses eine herausfordernde)
- Hilfsfunktionen -
(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 ))))))
(Disclaimer - Dies ist keine Hausaufgabe Frage - es ist für mein Verständnis und Lernen)
Lösung
Ich nahm an:
- In P-Definition, mit "(Q (str (erster $ str)))" Sie meinte: "(Q str (erster $ str))", wie Q eine zwei Argument Funktion
- build ist ein Helfer, der etwas tut, schafft, auf dem ersten $ und zweite $ Arbeit: Liste
Vor diesem Hintergrund gibt die direkte Übersetzung von Schema in 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)
, deren letzte Zeile Folgendes zurück:
(2 3 5 7 11 13 17 19 23 29)
, die eine bekannte Serie ist, so gehe ich davon die Übersetzung erfolgreich ist: -)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow