Thursday, 22 March 2012

Exercise 159: You know about first and rest from BSL, but BSL+ comes with even more selectors than that....


Exercise 159: You know about first and rest from BSL, but BSL+ comes with even more selectors than that. Determine the values of the following expressions:


  1. (first (list 1 2 3))
  2. (rest (list 1 2 3))
  3. (second (list 1 2 3))

Find out from the documentation whether third, fourth, and fifth exist.



This is a very straight forward exercise. As always with exercises of this type the hardest thing is making yourself do the exercise rather than just pasting the expressions into racket and seeing what they evaluate to.

I did not do as well as I expected - I got the first and third questions wrong. I was expecting them to return a list instead of the element.

A quick look at the documentation shows that not only do third, fourth and fifth exist, but so do sixth, seventh, eighth, nineth and tenth.

;(first (list 1 2 3))
(check-expect (first (list 1 2 3))
              1)


;(rest (list 1 2 3))
(check-expect (rest (list 1 2 3))
              (list 2 3))


;(second (list 1 2 3))
(check-expect (second (list 1 2 3))
              2)
     

Friday, 16 March 2012

Exercise 158: Determine the values of the following expressions...


Exercise 158: Determine the values of the following expressions:

  1. (list (string=? "a" "b") (string=? "c" "c") false)
  2. (list (+ 10 20) (* 10 20) (/ 10 20))
  3. (list "dana" "jane" "mary" "laura")

This is a pretty straight forward exercise. The hardest part here is to avoid the temptation to paste these directly in to the racket interpreter. I got 2/3 correct on my first pass though.


;1) (list (string=? "a" "b") (string=? "c" "c") false)
(check-expect (list (string=? "a" "b") (string=? "c" "c") false)
              (list false true false))
              
;2) (list (+ 10 20) (* 10 20) (/ 10 20))
(check-expect (list (+ 10 20) (* 10 20) (/ 10 20))
              (list 30 200 0.5))


;3) (list "dana" "jane" "mary" "laura")
(check-expect (list "dana" "jane" "mary" "laura")
              (list "dana" "jane" "mary" "laura"))

Tuesday, 13 March 2012

Exercise 157b: On some occasions lists are formed with cons and list. Reformulate the following lists using list exclusively


Exercise 157: On some occasions lists are formed with cons and list. Reformulate the following lists using list exclusively:;


;(cons "a" (list 0 false))
;
;(list (cons 1 (cons 13 empty)))
;
;(cons (list 1 (list 13 empty)) empty)
;
;(list empty empty (cons 1 empty))
;
;(cons "a" (cons (list 1) (list false empty)))

Whoops! Completely missed that second part about doing this also exclusively using list. Luckily this is a lot easier than doing them using cons exclusively. The tricky part about this exercise was doing it all in your head before pasting the source expression into racket - as soon as you do that, racket gives the answer formatted using list. Doh!



;1 Reformulate: (cons "a" (list 0 false))
(check-expect (cons "a" (list 0 false))
              (list "a" 0 false))


  
;2 Reformulate (list (cons 1 (cons 13 empty)))
(check-expect (list (cons 1 (cons 13 empty)))  
              (list (list 1 13) ))
              
;3 Reformulate (cons (list 1 (list 13 empty)) empty)
(check-expect (cons (list 1 (list 13 empty)) empty)
              (list (list 1 (list 13 empty))))


;4 Reformulate
;(list empty empty (cons 1 empty))
(check-expect (list empty empty (cons 1 empty))
              (list empty empty (list 1)))




;5 Reformulate (cons "a" (cons (list 1) (list false empty)))
(check-expect (cons "a" (cons (list 1) (list false empty)))
              (list "a" (list 1) false empty))

Tuesday, 6 March 2012

Exercise 157: On some occasions lists are formed with cons and list. Reformulate the following lists using cons and empty exclusively


Exercise 157: On some occasions lists are formed with cons and list. Reformulate the following lists using cons and empty exclusively



;(cons "a" (list 0 false))
;
;(list (cons 1 (cons 13 empty)))
;
;(cons (list 1 (list 13 empty)) empty)
;
;(list empty empty (cons 1 empty))
;
;(cons "a" (cons (list 1) (list false empty)))


This exercise was pretty straight forward. I just built up the lists from scratch only using cons.

;1 Reformulate: (cons "a" (list 0 false))
(check-expect (cons "a" (cons 0 (cons false empty)))
              (cons "a" (list 0 false)))




;2 Reformulate: (list (cons 1 (cons 13 empty)))
(check-expect (list (cons 1 (cons 13 empty)))  
              (cons (cons 1 (cons 13 empty)) empty) )
    
          
;3 Reformulate (cons (list 1 (list 13 empty)) empty)
;  this one is a little more interesting - we are making 
;  a list of empty lists - easy enough to do though with 
;  a (cons empty empty)
(check-expect (cons (list 1 (list 13 empty)) empty)
              (cons (cons 1 (cons (cons 13 
                            (cons empty empty)) empty)) empty))


;4 Reformulate: (list empty empty (cons 1 empty))
(check-expect (list empty empty (cons 1 empty))
              (cons empty (cons empty (cons 
                                      (cons 1 empty) empty))))




;5 Reformulate: (cons "a" (cons (list 1) (list false empty)))
(check-expect (cons "a" (cons (list 1) (list false empty)))
              (list "a" (list 1) false empty))

Tuesday, 21 February 2012

Exercise 156: Use cons and empty to construct lists.


Exercise 156: Use cons and empty to construct the equivalent of the following lists:

; 1) (list 0 1 2 3 4 5)
; 2) (list (list "adam" 0) (list "eve" 1) (list "louisXIV" 2))
; 3) (list 1 (list 1 2) (list 1 2 3))

I found this exercise a little harder than expected. This is because I very quickly got tired of using cons to build up lists and have been using list most of the time.
It's good to have the theory and knowledge of lists being constructed of cons and empty, but in practise it is far too tedious.



1) This is very straight forward - just a list of cons...


(check-expect (cons 0 (cons 1 (cons 2 (cons 3 (cons 4 (cons 5 empty ))))))              
              (list 0 1 2 3 4 5))






2) This is a little more complex - each sublist needs to be cons back into the main list. 


(check-expect (cons (cons "adam" (cons 0 empty))
                    (cons (cons "eve"  (cons 1 empty))
                          (cons (cons "louisXIV" (cons 2 empty)) empty)))
              (list (list "adam" 0) (list "eve" 1) (list "louisXIV" 2)))






3) Again, a little more complex. I found it easier to build this up from the inside.


(check-expect (cons 1 
                    (cons (cons 1 (cons 2 empty)) 
                          (cons (cons 1 (cons 2 (cons 3 empty))) empty)))
              (list 1 (list 1 2) (list 1 2 3)))

Tuesday, 14 February 2012

Question 155: List Processing


Before we start . . . you may ask what happened to question 154? Well, there doesn't seem to be a question 154 in the book! There is an exercise there, but they give you the answer! So, on to question 155...

I had actually 'cheated' somewhat here, and given up on cons a long time ago. A quick hunt through the manual showed the list command and and I've been using that since right near the start.

This is very straight forward exercise:


; Question 1
(check-expect (list "a" "b" "c" "d" "e")
    (cons "a" 
          (cons "b" 
                (cons "c" 
                      (cons "d" 
                            (cons "e" empty))))))
; Question 2
(check-expect (list (list 1 2))
              (cons (cons 1 (cons 2 empty)) empty))


; Question 3
(check-expect (list "a" (list 1) false)
              (cons "a" (cons (cons 1 empty) (cons false empty))))


; Question 4
(check-expect (list (list 1 2) (list 2))
              (cons (cons 1 (cons 2 empty)) (cons (cons 2 empty) empty)))


; Question 5
(check-expect (list (list "a" 2) "hello")
              (cons (cons "a" (cons 2 empty)) (cons "hello" empty))eB.


; Question 1
(check-expect (list "a" "b" "c" "d" "e")
    (cons "a" 
          (cons "b" 
                (cons "c" 
                      (cons "d" 
                            (cons "e" empty))))))
; Question 2
(check-expect (list (list 1 2))
              (cons (cons 1 (cons 2 empty)) empty))


; Question 3
(check-expect (list "a" (list 1) false)
              (cons "a" (cons (cons 1 empty) (cons false empty))))


; Question 4
(check-expect (list (list 1 2) (list 2))
              (cons (cons 1 (cons 2 empty)) (cons (cons 2 empty) empty)))


; Question 5
(check-expect (list (list "a" 2) "hello")
              (cons (cons "a" (cons 2 empty)) (cons "hello" empty)))

Wednesday, 8 February 2012

Exercise 153: Yet More Text Editing

Note: This question is building on the answers to the questions preceding it. Rather than include the code from the last questions each time, I am only including that code which is specific to this question. If I seem to be missing a function or two, I suggest you go look at one of the previous answers!


 Exercise 153: Design the functions

;; Editor -> Editor
;; move the cursor position one 1String left, if possible
;(define (editor-lft ed)
;  ed)

;; Editor -> Editor
;; move the cursor position one 1String right, if possible
;(define (editor-rgt ed)
;  ed)

;; Editor -> Editor
;; delete one 1String to the left of the cursor, if possible
;(define (editor-del ed)
;  ed)


These are all fairly straight forward functions - simple list manipulation with no recursion to worry about. The challenge here lies in coming up with a reasonable test suite. 


; Editor -> Editor
; move the cursor position one 1String left, if possible
; All we need to do is remove the leading character of the
; 'pre' list and append it to the start of the 'post' list
(define (editor-lft ed)
  (cond ((empty? (editor-pre ed)) ed)
        (else (make-editor (rest (editor-pre ed)) 
                           (cons (first (editor-pre ed)) 
                                 (editor-post ed))))))


; simple case - text on both sides, should move cursor to
; the left
(check-expect (editor-lft (create-editor "eht" "word"))
              (create-editor "ht" "eword"))




; empty on left hand side - shouldn't change state
(check-expect (editor-lft (create-editor "" "word"))
              (create-editor "" "word"))


I can't think of any other test cases we need to cover here - if editor-post is populated or empty, it shouldn't make any difference to our functions.




; Editor -> Editor
; move the cursor position one 1String right, if possible
; This is the inverse of editor-lft - remove the first character
; from the 'post' text and prepend that to the 'pre' text
(define (editor-rgt ed)
  (cond ((empty? (editor-post ed)) ed)
        (else (make-editor (append   
                            (explode (first (editor-post ed))) 
                            (editor-pre ed) )
                           (rest (editor-post ed))))))


; simple case - text on both sides, should move cursor to the right
; Bear in mind that editor-pre is stored reversed, so we need to add chars to the front
; of it.
(check-expect (editor-rgt (create-editor "eht" "cat"))
              (create-editor "ceht" "at"))


; empty on right hand side - shouldn't change state
(check-expect (editor-rgt (create-editor  "word" ""))
              (create-editor  "word" ""))


; empty on both sides - shouldn't change state
(check-expect (editor-rgt (create-editor  "" ""))
              (create-editor  "" ""))



; Editor -> Editor
; delete one 1String to the left of the cursor, if possible
(define (editor-del ed)
    (cond ((empty? (editor-pre ed)) ed)
        (else (make-editor (rest (editor-pre ed)) 
                           ( editor-post ed)))))
  




; simple case - string populated on both sides should just
; delete the first chart to the left
(check-expect (editor-del (create-editor  "eht" "cat"))
              (create-editor  "ht" "cat"))


; if the editor-pre is not populated, then nothing should change
; (as there is nothing to delete)
(check-expect (editor-del (create-editor  "" "cat"))
              (create-editor  "" "cat"))


; if the editor-post is not populated, then should still
; be a straight forward delete
(check-expect (editor-del (create-editor  "eht " ""))
              (create-editor  "ht " ""))


; if the editor-post *and* editor-pre are not populated, 
; then nothing should happen
(check-expect (editor-del (create-editor  "" ""))
              (create-editor  "" ""))


; and finally, check what happens when there is exactly
; one character to delete
(check-expect (editor-del (create-editor  "a" "xxx"))
              (create-editor  "" "xxx"))