;; CS101, Spring 2013 ;; Lecture #11 ;; ;; * BUILT-IN FUNCTIONS THAT CONSUME FLAT LISTS. ;; * WRITING FUNCTIONS THAT PRODUCE FLAT LISTS. ;; ;; All of the lists we've worked with so far have been so-called ;; FLAT LISTs, meaning there are no elements in the list that are ;; themselves constructed lists, and the empty list appears only ;; at the end of the list ; ; Handy built-in functions that work on flat lists: ; ; length Contract: (length lox) -> number ; Header: (define length (lambda (alox) ...)) ; Purpose: returns the number of elements in alox. ; ; append Contract: (append lox lox ...) -> lox ; Header: (define append (lambda (alox ...) ...)) ; Purpose: Creates a single list from several such ; that the elements in the output list are ; ordered left to right in same order given. ; ; list-ref Contract: (list-ref lox nat-num) -> x ; Header: (define list-ref (lambda (listx num) ...)) ; Purpose: Extracts the item at index num from listx. ; ; reverse Contract: (reverse lox) -> lox ; Header: (define reverse (lambda (listx) ...)) ; Purpose: return listx with all elements reversed. ; ; member? Contract: (member? x lox) -> boolean ; Header: (define member? (lambda (x lox) ... )) ; Purpose: Checks if x is an element of lox ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; WRITING FUNCTIONS THAT PRODUCE FLAT LISTS: ;; ;; To get an idea of how the append function works, write a ;; function that consumes two lists of any type and joins ;; them into one list such that all the elements from both ;; lists are in the same relative order. Call the function ;; MY-APPEND ;; A list of anything (lox) is either ;; 1. empty or ;; 2. it's a (cons x alox), where x is any valid type and alox ;; is an lox one element shorter than (cons x alox). ; Contract: (my-append lox lox) -> lox ; Header: (define my-append (lambda (lox1 lox2) ...)) ; Purpose: To join the elements of lox1 and lox2 into one list ; such that the elements are all in the same list and ; in the same order. ; Pre-function tests: (check-expect (my-append '(1 2 3) '(9 4 5)) '(1 2 3 9 4 5)) (check-expect (my-append empty '(a g c t)) '(a g c t)) (check-expect (my-append '(a g c t) empty) '(a g c t)) ; Function definition: (define my-append (lambda (lox1 lox2) (cond ;; base case is when lox1 is empty; ;; all cons operations in the recursive case ;; put elements of lox1 onto lox2 [(empty? lox1) lox2] ;; recursive case is when lox1 is not empty; ;; cons (first lox1) onto result of consing ;; rest of elements in lox1 onto lox2. [else (cons (first lox1) (my-append (rest lox1) lox2))]))) ; Post-function printf's: (printf "(my-append '(a b c) '(4 3 2)) => ~a~%" (my-append '(a b c) '(4 3 2))) (printf "(my-append '(a b c) '()) => ~a~%" (my-append '(a b c) '())) ;;;;;; DATA DEFINITION FOR A LIST OF BOOLEANS ;;;;;; ;; A list of booleans (LOB) is either: ;; 1. empty, or ;; 2. it's a (cons b lb), where b is a boolean and lb is a LOB. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Ex 1: Write a function that consumes a list of numbers (LON) ;; and produces a list containing true for every even ;; number on the list and false for every odd number. ;; Contract: (even-true lon (to be precise, list of integers)) -> lob ;; Header: (define even-true (lambda (numlist) ...)) ;; Purpose: Produce the list containing #t for every even integer ;; in numlist and #f for every odd integer. ;; Pre-function tests: (check-expect (even-true (list 1 2 3 4 5 6)) (list #f #t #f #t #f #t)) (check-expect (even-true (list 1111 1113 5 9 2)) (list #f #f #f #f #t)) (check-expect (even-true empty) empty) ;; Function definition: (define even-true (λ (numlist) (cond ;; base case, return smallest list [(empty? numlist) empty] [else ;; recursive case: cons #t on output list if first is even, ;; otherwise, cons #f on output list. (cons (if (even? (first numlist)) #t #f) (even-true (rest numlist)))]))) ;; Post-function printfs: (printf "(even-true (list 1 2 3 4 5 6)) => ~a~%" (even-true (list 1 2 3 4 5 6))) (printf "(even-true empty) => ~a~%" (even-true empty)) (printf "(even-true (list 1111 1113 5 9 2)) => ~a~%" (even-true (list 1111 1113 5 9 2)))