CS 37

Clab 9: map and filter


First, do exercises 2.21, 2.23 on pages 106-107. Then, go on to exercises 2.30, 2.31, 2.32 on pages 112-113. You can find them by scrolling down a couple of screens from: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html#%_sec_2.2.2
If necessary review the material on pages 105 and 112. Remember to substitute '() for nil wherever the text uses nil or put (define nil '()) in your definitions window.

Here is the procedure filter from page 115 of the text.

(define filter (lambda (pred? l) (cond ((null? l) '()) ((pred? (car l)) (cons (car l) (filter pred? (cdr l)))) (else (filter pred? (cdr l)))))) Many problems can be thought of effectively as signals going through a cascade of stages. enumerate, map, filter, and accumulate are powerful tools to implement the stages.

Use filter to define a procedure remove-neg that given an input list of integers, returns a list of all the non-negative integers in the input list.

> (remove-neg '(1 -3 4 5 -6 -7)) (1 4 5) Let's look together at some examples of map and flatmap (define (accumulate op initial sequence) (if (null? sequence) initial (op (car sequence) (accumulate op initial (cdr sequence))))) (define (flatmap proc seq) (accumulate append '() (map proc seq))) (define (map proc seq) ;;overriding built-in map (if (null? seq) '() (cons (proc (car seq)) (map proc (cdr seq))))) (define enumerate-interval (lambda (beg end) (cond ((> beg end) '()) (else (cons beg (enumerate-interval (+ beg 1) end)))))) (define make-pairs1 ;; with flatmap and map (lambda (n) (flatmap (lambda (i) (map (lambda (j) (list i j)) (enumerate-interval 1 n))) (enumerate-interval 1 n)))) (define make-pairs2 ;; with 2 maps (lambda (n) (map (lambda (i) (map (lambda (j) (list i j)) (enumerate-interval 1 n))) (enumerate-interval 1 n)))) (define make-pairs3 ;; with 2 flatmaps (lambda (n) (flatmap (lambda (i) (flatmap (lambda (j) (list i j)) (enumerate-interval 1 n))) (enumerate-interval 1 n)))) Consider: > (enumerate-interval 1 3) (1 2 3) > (map (lambda (j) (list 3 j)) (enumerate-interval 1 3)) ((3 1) (3 2) (3 3)) > (flatmap (lambda (j) (list 3 j)) (enumerate-interval 1 3)) (3 1 3 2 3 3) Now try: > (make-pairs1 3) > (make-pairs2 3) > (make-pairs3 3) Think about why the results are different. Any of the outputs could be useful depending on what you want to do. Just be aware that there is a difference between using map and flatmap. > (cons '((3 1) (3 2) (3 3)) '()) (((3 1) (3 2) (3 3))) > (append '((3 1) (3 2) (3 3)) '()) ((3 1) (3 2) (3 3)) > (cons '((2 1) (2 2) (2 3)) '(((3 1) (3 2) (3 3)))) (((2 1) (2 2) (2 3)) ((3 1) (3 2) (3 3))) > (append '((2 1) (2 2) (2 3)) '((3 1) (3 2) (3 3))) ((2 1) (2 2) (2 3) (3 1) (3 2) (3 3))

Let's look at the text's permutations function

(define filter (lambda (pred? l) (cond ((null? l) '()) ((pred? (car l)) (cons (car l) (filter pred? (cdr l)))) (else (filter pred? (cdr l)))))) (define (permutations s) (if (null? s) ; empty set? (list '()) ; sequence containing empty set (flatmap (lambda (x) ; try map instead of flatmap (map (lambda (p) (cons x p)) (permutations (remove x s)))) s))) (define (remove item sequence) (filter (lambda (x) (not (equal? x item))) sequence))

Note that these ideas, especially map, are really used! See: http://en.wikipedia.org/wiki/MapReduce

Now a challange

Finish the 8-queens problem, ex 2.42 page 124-126. You can find it by scrolling up a couple of screens from: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-15.html#%_sec_2.2.4


Solutions for Clab8 functions. Here is some code for deep versions of subst and remove-all: ;; subst* returns a list that substitutes new for old in an arbitrary ;; list, l, of symbols: (define subst* (lambda (old new l) (cond ((null? l) '()) ((list? (car l)) (cons (subst* old new (car l)) (subst* old new (cdr l)))) ((eq? (car l) old) (cons new (subst* old new (cdr l)))) (else (cons (car l) (subst* old new (cdr l))))))) ;; remove-all* removes all occurrences of sym from an arbitrarily ;; nested list: (define remove-all* (lambda (sym l) (cond ((null? l) '()) ((list? (car l)) (cons (remove-all* sym (car l)) (remove-all* sym (cdr l)))) ((eq? (car l) sym) (remove-all* sym (cdr l))) (else (cons (car l) (remove-all* sym (cdr l)))))))

If you have any questions from last clab, begin with it and get your questions answered.

ask any questions you may have.