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)

War es hilfreich?

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
scroll top