2. harjoitustehtävä

Ehdottomasti yleisin virhe oli taas tehtävänannon huolimaton lukeminen. Tehtävässä mainittiin kahteen kertaan, että puu voi olla paitsi lauseke- tai sanasolmu, myös pelkkä merkkijono. Monet olivat kuitenkin koodanneet fringe- ja trim-proseduurit olettaen, että syöte toteuttaa joko phrase? tai word?-predikaatin.


;; Sormiharjoitukset

;; 1.
;; 
;; (length (cons 'a (cons 'b '()))) => 1
;; (length (list (list 'a 'b 'c))) => 1
;; (length (list 'a) '() '(list 'b)) => 3

;; 2.

; Käsin:

(define (epal-aux l acc)
  (if (null? l)
      acc
      (cons (car l) (epal-aux (cdr l) (cons (car l) acc)))))

(define (epal l)
  (epal-aux l '()))

; Kirjastoproseduureja käyttäen yksinkertaisesti:

(define (epal-2 l)
  (append l (reverse l)))

;; 3.

(define (opal-aux l acc)
  (if (null? (cdr l))
      acc
      (cons (car l) (opal-aux (cdr l) (cons (car l) acc)))))

(define (opal l)
  (opal-aux l))

(define (opal-2 l)
  (append l (cdr (reverse l))))


;; Varsinainen tehtävä

;; 1.

(define (phrase? t)
  (or (ap? t) (np? t) (pp? t) (vp? t) (xp? t)))

(define (word? t)
  (or (a? t) (n? t) (p? t) (v? t) (x? t)))

;; 2.

; Yksinkertainen, tehoton versio
(define (fringe t)
  (cond ((phrase? t) (append (fringe (left t)) (fringe (right t))))
        ((word? t) (fringe (word t)))
        (else (list t))))

; Hieman monimutkaisempi mutta paljon tehokkaampi
(define (fringe-2-aux t acc)
  (cond ((phrase? t) (fringe-2-aux (left t) (fringe-2-aux (right t) acc)))
        ((word? t) (fringe-2-aux (word t) acc))
        (else (cons t acc))))

(define (fringe-2 t)
  (fringe-2-aux t '()))

;; 3.

; Ensin monimutkainen mutta "siisti" versio: tutkitaan puun tyyppiä ja sen
; mukaan päätetään, millä proseduurilla rakennetaan uusi samantyyppinen puu

(define (phrase-maker p)
  (cond ((ap? p) make-ap)
        ((np? p) make-np)
        ((pp? p) make-pp)
        ((vp? p) make-vp)
        ((xp? p) make-xp)
        (else #f)))

(define (trim t)
  (let ((maker (phrase-maker t)))
    (cond (maker (maker (trim (left t)) (trim (right t))))
	  ((word? t) (word t))
          (else t))))

; Yksinkertaisempi ratkaisu, joka kuitenkin vaatii, että lausepuita
; käsitellään "suoraan" listoina, eikä vain annettujen apuproseduurien
; kautta.

(define (trim-2 t)
  (cond ((phrase? t) (list (car t) (trim-2 (left t)) (trim-2 (right t))))
        ((word? t) (trim-2 (word t)))
        (else t)))


Lauri Alanko