4. harjoitustehtävä

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 '()))
Lauri Alanko