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)))