S22: Thursday

In Class

We'll start with questions and answers, and then I'll provide an introduction to pattern matching. 

There isn't any explicit reading or practice dealing with pattern matching. The reason for this is that pattern matching is just a fancy way of getting cond-like behavior out of our code, but with a twist. We will work with it in-class on Tuesday.

Take Away

This is it. The Final Countdown.


You're being sent off with a scad of list problems. Follow the design recipe for each problem, and increase the number of tests you have for each function. Use Piazza to ask questions of me and your peers if you get stuck.

Once we work through these questions, we're Ready 2 Rokk.


The Questions

; You can copy-paste this whole bit into DrRacket. I think.

; These are due before class on Tuesday.

#lang racket

(require test-engine/racket-tests)


;; In all cases, it may make sense to write a helper procedure. For example, if you are given a string and asked to count how many vowels are in it, you may want to convert the string to a list of characters. You could write:


;; (define (count-vowels str)

;;   (count-vowels-helper (string->list str)))


;; and in the function count-vowels-helper do the interesting work. Not all problems benefit from the use of a helper, but it is sometimes the case that we can solve a problem more simply by writing more than one function.


;; 1. This is a problem about using first, second, third, and rest to access elements of a list. Requirements regarding contract and purpose statements are suspended for this question.


(define message 

   '(oh ((there once) 

         (was (a)) 

         man (from (nantucket)))))


;; a. Write a function called message-a that extracts the list (was (a)) from the message.


(define (message-a) 

  '...)

(check-expect (message-a) '(was (a)))


;; b. Write a function called message-b that extracts the symbol 'a from the message. It should make use of the function message-a.


(define (message-b) 

  '...)

(check-expect (message-b) 'a)


;; c. Write a function called message-c that extracts the symbol 'from from the message.

(define (message-c)

  '...)

(check-expect (message-c) 'from)


;; 2. Using symbols, cons, and empty, define the value build-message that is equal to

;;    '((was (a)) man)


(define build-message '...)

(check-expect build-message '((was (a)) man))


;; 3. Write a function called ice-cream-flavor-maker that consumes a list of four symbols, and returns two lists of length two. The input type is (list-of symbol), and the output type is (list-of (list-of symbol)). For example:


;; (check-expect (ice-cream-flavor-maker '(the amazing chocolate fudge))

;;               '((the amazing) (chocolate fudge)))

;; (check-expect (ice-cream-flavor-maker '(an exquisite vanilla bean))

;;               '((an exquisite) (vanilla bean)))


;; 4. Write a function called all-divisible-by? that consumes a number and a (list-of number). It should return a boolean if every number in the list is divisible by the first argument. For example:


;; (check-expect (all-divisible-by? 3 empty) true)

;; (check-expect (all-divisible-by? 5 '(10 20)) true)


;; 5. Write a function called all-lists?. It should consume a list of anything and return true if all of the elements of the list are lists.


;; (check-expect (all-lists? '((a b) (c d))) true)

;; (check-expect (all-lists? '((a b) c)) false)


;; 6. Write a function called only-symbols?. It consumes a deep-list-of-symbols, where any element could be a list or a symbol. We might define a deep-list-of-symbols (abbreviated DLOS) as follows:


;; A DLOS is EITHER

;;  - empty OR

;;  - (cons symbol DLOS) OR

;;  - (cons DLOS DLOS)


;; Your function should return true if the data we are given conforms to this definition---meaning our data is only composed of symbols and lists.


;; For example:


;; (check-expect (only-symbols? '(a b c)) true)

;; (check-expect (only-symbols? '(a (b) c)) true)

;; (check-expect (only-symbols? '((the amazing) (chocolate fudge))) true)


;; 7. Write a function reverse-list that consumes a list and rebuilds it in reverse order. Your function may not use the built-in function reverse. This would be a good time to use a helper and program in the accumulator-passing style.


;; (check-expect (reverse-list '(1 2 3)) '(3 2 1))


;; 8. Write a function append-lists that consumes two lists and returns a single list. Your solution may not use the built-in function append.


;; (check-expect (append-lists '(1 2 3) '(4 5 6)) '(1 2 3 4 5 6))


;; 9. Write a function called palindrome? that consumes a list and determines whether that list contains the same sequence of symbols forwards and backwards. I solved this with a helper that recurred on indices, but I think you can solve it other ways as well. (For example, you could use 'reverse' and recur on two lists.)


;; (check-expect (palindrome? '(x p e d e x)) true)


;; 10. Write a function called flatten that consumes a DLOS and returns a flattened list.


;; (check-expect (flatten '(a (b c (d e)) f (g))) '(a b c d e f g))


;; 11. Define a function called fact that consumes a single number and calculates the factorial of that number.


;; (check-expect (fact 5) 120)


;; 12. Write a function called compress that eliminates sequential duplicates from a list.


;; (check-expect (compress '(a a a a b c c a a d e e e e))

;;               '(a b c a d e))


;; 15. Write a function dupli that duplicates each element of a list.


;; (check-expect (dupli '(a b c)) '(a a b b c c))


;; 16. Write a function repli that replicates each element of a list some number of times.


;; (check-expect (repli '(a b c) 3) '(a a a b b b c c c))


;; 17. Write a function, drop, that drops every n'th element of a list.


;; (check-expect (drop '(a b c d e f g h i) 3) '(a b d e g h))


;; 18. Write a function, slice, that slices a list.


;; (check-expect (slice '(a b c d e f g) 3 5) '(d e f))


;; 19. Write a function called checked-slice that first checks that the slice range is valid, and if it is, calls slice. If it is incorrect, use the function error to produce an error message.


;; 20. Write a function called split that takes a list and an index and splits the list after the given index. It should return a list of two lists.


;; (check-expect (split '(a b c d e f g) 3) '((a b c d) (e f g)))


;; 21. Write a function, rotate, that rotates a list n places to the left. This can make use of functions you've written previously, as well as list and append.


;; (check-expect (rotate '(a b c d e f g) 3) '(d e f g a b c))


;; 22. Write a function, range, that generates a list of numbers in a given range.


;; (check-expect (range 5 10) '(5 6 7 8 9 10))


;; 23. Write a function, rand-select, that selects a number of random elements from a list. Search the help desk for "random."


;; ;; Testing this is a bit tricky. You could do better.

;; (check-expect (length (rand-select '(a b c d e f) 3)) 3)


;; 24. Write a function called lotto that draws N random numbers from a given range. Using previously written functions is a good idea.


;; ;; For example:

;; ;; (lotto 5 15 30) => '(7 28 19 8 15)

;; (check-expect (length (lotto 5 15 30)) 5)


;; 25. Write a function called set-equal? that determines if two sets (represented as lists) contain all of the same elements. For example:


;; (check-expect (set-equal? '(1 2 3) '(2 3 1)) true)

;; (check-expect (set-equal? '(1 2) '(2 3 1)) false)


;; 26. Write a function called union that takes two sets and returns a set containing... er, their union. There should be no duplicates.


;; (check-expect (union '(1 2 3) '(2 4)) '(1 2 3 4)) ; Order does not matter in sets.

;; (check-expect (union '(1 2 3) '(1 2 3)) '(1 2 3))


;; 27. Write a function called intersect that takes two sets and returns a set containing only those elements in both of the sets.


;; (check-expect (intersect '(1 2 3) '(2)) '(2))

;; (check-expect (intersect '(1 2 3) '(1 3)) '(3))

;; (check-expect (intersect '(1 2 3) empty) empty)


(test)


Creative Commons License This work is licensed under a Creative Commons BY-SA 3.0 License.