Lähes kaikissa palautetuissa töissä oli joitain ongelmia. Kaikkein
yleisintä oli, että tavujen analysoinnissa käsiteltiin vain pieniä
kirjaimia. Tästä ei kuitenkaan sakotettu. Monissa
words-toteutuksissa oletettiin, että sanoja erottaa
tasan yksi välimerkki. Tehtävänanto ei oikeuttanut tällaista
tulkintaa, joten proseduuri ei saisi palauttaa ylimääräisiä tyhjiä
merkkijonoja.
Yleisin virhe boundary?-proseduurissa oli, että
sananalkukin hyväksyttiin tavurajaksi tehtävänannon vastaisesti.
Parissa työssä esiintyi myös tulkinta, jonka mukaan "kohta, jota
seuraa konsonantti" tarkoittaa, että konsonantin pitää olla vasta
indeksissä k+1 eikä jo k:ssa. Tästä ei itsessään rangaistu, mutta
se saattoi toki vaikuttaa syllables:in toimintaan.
Useimmat syllables-toteutukset olettivat, että
parametri on yhtenäinen epätyhjä kirjainjono. Tämä oli ihan
hyväksyttävää. Joissain töissä esiintyi virheitä, kun sana alkoi
vokaalilla tai päättyi konsonanttiin.
;; Sormiharjoitus
(define (index string k pred none)
(define length (string-length string))
(define (loop i)
(if (>= i length)
none
(if (pred (string-ref string i))
i
(loop (+ i 1)))))
(loop k))
;; Varsinaiset tehtävät
;; 1.
(define (char-black? c)
(not (char-whitespace? c)))
(define (words string)
(define length (string-length string))
(define (loop k acc)
(let ((start (index string k char-black? #f)))
(if start
(let ((end (index string start char-whitespace? length)))
(loop end (cons (substring string start end) acc)))
(reverse acc))))
(loop 0 '()))
;; 2.
(define (charset string)
(lambda (c)
(and (index string 0 (lambda (x) (char=? c x)) #f) #t)))
(define consonant? (charset "bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ"))
(define vowel? (charset "aeiouyåäöAEIOUYÅÄÖ"))
(define (boundary? word k)
(and (< 0 k (- (string-length word) 1))
(consonant? (string-ref word k))
(vowel? (string-ref word (+ 1 k)))))
;; 3.
(define (syllables word)
(define length (string-length word))
(define (loop prev k acc)
(if (>= k length)
(reverse (cons (substring word prev k) acc))
(if (boundary? word k)
(loop k (+ k 1) (cons (substring word prev k) acc))
(loop prev (+ k 1) acc))))
(loop 0 0 '()))