[plt-scheme] Loosing sleep over htdp exercise 12.4.2

From: Horace Dynamite (horace.dynamite at googlemail.com)
Date: Sat Mar 6 15:01:15 EST 2010

Dear reader,

M-x doctor suggested I consult with specialists as per aforementioned
conditions, I pray this is the right list.

I'm having a very hard time with this exercise 12.4.2. I've faithfully
followed the design recipes, but when it comes to the crunch, my lists
aren't coming out right.

Please find below my exercise computer file, I've included all my data
definitions, templates, examples, procedures and tears.


; A word is either
; 1. empty; or
; 2. (cons a w) where a is a symbol ('a, 'b, ... 'z) and w is a word.

; (define (fun-for-word a-word)
;   (cond
;     [(empty? a-word) ...]
;     [else ... (first a-word) ...
;           ... (fun-for-word (rest a-word)) ...]))

; A list-of-words is either
; 1. empty; or
; 2. (cons w low) where w is a word and low is a list-of-words

; (define (fun-for-list-of-words a-low)
;   (cond
;     [(empty? a-low) ...]
;     [else ... (first a-low) ...
;           ... (fun-for-a-list-of-words (rest a-low)) ...]))

;  EXAMPLES FOR DATA
;  words;
;   empty,
;   1-letter word: (cons 'a empty)
;   3-letter word: (cons 'a (cons 'p (cons 'e empty)))
;   n-letter word: (cons x1 (cons x2 ( ... (cons xn-1 (cons xn empty)))
;  low;
;    0 words: empty
;    1-word: (cons (cons 'a empty) empty)
;    3-words: (cons (cons (cons 'a empty)
;                         (cons (cons 'b empty)
;                               (cons (cons 'c empty)
;                                     empty)))
;                   empty)


;; arrangements  : word -> list-of-words
;; to create a list of all rearrangements of the letters in a-word
;; (I have a hard copy of the book, which gives a nice example for this)
(define (arrangements a-word)
  (cond
    [(empty? a-word) empty]
    [else (insert-everywhere/in-all-words (first a-word)
                                          (arrangements (rest a-word)))]))

;; insert-everywhere/in-all-words : symbol list-of-words -> list-of-words
;; to insert s between and around all the letters of all the words of a-low
; EXAMPLES
; (insert-everywhere/in-all-words 'd
;                                 (cons (cons 'e (cons 'r empty))
;                                       (cons (cons 'r (cons 'e empty))
;                                             empty)))
; --->
; (cons (cons 'd (cons 'e (cons 'r empty)))
;       (cons (cons 'e (cons 'd (cons 'r empty)))
;             (cons (cons 'e (cons 'r (cons 'd empty)))
;                   (cons (cons 'd (cons 'r (cons 'e empty)))
;                         (cons (cons 'r (cons 'd (cons 'e empty)))
;                               (cons (cons 'r (cons 'e (cond 'd empty)))
;                                     empty))))))

(define (insert-everywhere/in-all-words s a-low)
  (cond
    [(empty? a-low) empty]
    [else (append (insert-everywhere/in-one-word s (first a-low))
                  (insert-everywhere/in-all-words s (rest a-low)))]))

;; insert-everwhere/in-one-word symbol word -> list-of-words
;; to insert s between all letters and around a-word.
; EXAMPLES
; (insert-everywhere/in-one-word 'd (cons 'e (cons 'r empty)))
; --->
; (cons (cons 'd (cons 'e (cons 'r empty)))
;       (cons (cons 'e (cons 'd (cons 'r empty)))
;             (cons (cons 'e (cons 'r (cons 'd empty)))
;                   empty)))

(define (insert-everywhere/in-one-word s a-word)
  (cond
    [(empty? a-word) empty]
    [else (append (insert-around-word s a-word)
                (insert-between-word s a-word))]))

;; insert-around-word : symbol word -> list-of-words
;; to insert s on the front and back of a-word
; EXAMPLES
; (insert-around-word 'd (cons 'e (cons 'r empty)))
; --->
; (cons (cons 'd (cons 'e (cons 'r empty)))
;       (cons (cons 'e (cons 'r (cons d empty)))
;             empty))

(define (insert-around-word s a-word)
  (cons (cons s a-word)
        (cons (append a-word (cons s empty))
              empty)))

;; insert-between-word : symbol word -> list-of-words
;; to insert s inbetween all the adjacent letters
; EXAMPLES
; (insert-between-word 'd (cons 'e (cons 'r empty)))
; --->
; (cons (cons 'e (cons 'd (cons 'r empty)))
;       empty)
;
; (insert-between-word 'd (cons 'a (cons 'p (cons 'e empty))))
; --->
; (cons (cons 'a (cons 'd (cons 'p (cons 'e empty))))
;       (cons (cons 'a (cons 'p (cons 'd (cons 'e empty))))
;             empty))

(define (insert-between-word s a-word)
  (cond
    [(empty? (rest a-word)) empty]
    [else (cons (cons (first a-word) (cons s (rest a-word)))
                (insert-between-word (cons (first (rest a-word))
                                           (cons s empty))
                                     (cons (first a-word) (rest (rest
a-word)))))]))

If you got this far, it's this last definition above that's causing my
symptoms. For example:

> (insert-between-word 'd (cons 'a (cons 'p (cons 'e empty))))
(cons (cons 'a (cons 'd (cons 'p (cons 'e empty)))) (cons (cons 'a (cons
(cons 'p (cons 'd empty)) (cons 'e empty))) empty))

(I peaked a little ahead in the book, and found that I can write this output
more succinctly like so:
((a d p e) (a (p d) e))
)

Thank you for reading all this. Any pointers on where I'm going wrong with
the DR (I'm using the one on p132) would be much appreciated.

Yours Sincerely,

Horace.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20100306/69a43285/attachment.html>

Posted on the users mailing list.