360 likes | 514 Views
Lecture 9 Lists continued: Map, Filter, Accumulate , Lists as interfaces. Last Lecture: some basic list operations. (append list1 list2) (cons 1 (append ‘(2) list2)) (cons 1 (cons 2 (append ‘() list2))) (cons 1 (cons 2 list2)). list2. list1. 4. 1. 2. 3. 1. 2. Append: process.
E N D
Lecture 9Lists continued: Map, Filter, Accumulate, Lists as interfaces מבוא מורחב - שיעור 9
Last Lecture: some basic list operations מבוא מורחב - שיעור 8
(append list1 list2) (cons 1 (append ‘(2) list2)) (cons 1 (cons 2 (append ‘() list2))) (cons 1 (cons 2 list2)) list2 list1 4 1 2 3 1 2 Append: process (define (append list1 list2) (cond ((null? list1) list2); base (else (cons (car list1); recursion (append (cdr list1) list2))))) Quote: what you see is what you get. • (define list1 (list 1 2)) • (define list2 (list 3 4)) (1 2 3 4) מבוא מורחב - שיעור 8
(reverse (cdr lst)) (list (car lst)) 3 2 4 1 1 3 2 4 Reverse of a list (define (reverse lst) (cond ((null? lst) lst) (else ( (reverse (cdr lst)) ))))) append (list (car lst)) (reverse (list 1 2 3 4)) (append ) Append: T(n) = c*n = (n) Reverse: T(n) = c*(n-1) + c*(n-2)+ … + c*1 = (n2)
(integers-between 2 4) (cons 2 (integers-between 3 4))) (cons 2 (cons 3 (integers-between 4 4))) (cons 2 (cons 3 (cons 4 (integers-between 5 4)))) (cons 2 (cons 3 (cons 4 null))) (2 3 4) 2 3 4 Enumeration (define (integers-between lo hi) (cond ((> lo hi) null) (else (cons lo (integers-between (+ 1 lo) hi))))) מבוא מורחב - שיעור 8
4 2 5 7 Count Leaves (define (countleaves tree) (cond ((null? tree) 0) ;base case ((leaf? tree) 1) ;base case (else ;recursive case (+ (countleaves (car tree)) (countleaves (cdr tree)))))) (define my-tree (list 4 (list 5 7) 2)) מבוא מורחב - שיעור 8
+ (cl 4) (cl ((5 7) 2) ) (cl (5 7)) (cl (2)) + + (cl 2) (cl null) + + 4 2 (cl 7) (cl null) (cl (7)) (cl 5) 5 7 Countleaves my-tree (countleaves my-tree) ==> 4 (cl (4 (5 7) 2)) 4 3 1 2 1 1 1 1 0 1 0 מבוא מורחב - שיעור 8
5 7 4 2 4 2 5 7 Enumerate-Leaves (define (enumerate-leaves tree) (cond ((null? tree) null) ;base case ((leaf? tree) (list tree)) ;base case (else ;recursive case (append(enumerate-leaves (car tree)) (enumerate-leaves (cdr tree)))))) מבוא מורחב - שיעור 8
List abstraction • Find common high order patterns • Distill them into high order procedures • Use these procedures to simplify list operations Patterns: • Mapping • Filtering • Accumulating מבוא מורחב - שיעור 8
Mapping (define (map proc lst) (if (null? lst) null (cons (proc (car lst)) (map proc (cdr lst))))) (define (square-list lst) (map square lst)) (define (scale-list lst c) (map (lambda (x) (* c x)) lst)) (scale-list (integers-between 1 5) 10) ==> (10 20 30 40 50) מבוא מורחב - שיעור 8
Mapping: process (define (map proc lst) (if (null? lst) null (cons (proc (car lst)) (map proc (cdr lst))))) (map square (list 1 2 3)) (cons (square 1) (map square (list 2 3))) (cons 1 (map square (list 2 3))) (cons 1 (cons (square 2) (map square (list 3)))) (cons 1 (cons 4 (map square (list 3)))) (cons 1 (cons 4 (cons (square 3) (map square null)))) (cons 1 (cons 4 (cons 9 (map square null)))) (cons 1 (cons 4 (cons 9 null))) (1 4 9) מבוא מורחב - שיעור 8
Generalized Mapping (map <proc> <list1>…<listn>) Returns a list in which proc is applied to the i-th elements of the lists respectively. (map + (list 1 2 3) (list 10 20 30) (list 100 200 300)) ==> (111 222 333) (map (lambda (x y) (+ x (* 2 y))) (list 1 2 3) (list 4 5 6)) ==> (9 12 15) We will see how to write such a procedure later! מבוא מורחב - שיעור 8
(define (filter pred lst) (cond ((null? lst) null) ((pred (car lst)) (cons (car lst) (filter pred (cdr lst)))) (else (filter pred (cdr lst))))) Filtering (filter odd? (integers-between 1 10)) (1 3 5 7 9) מבוא מורחב - שיעור 8
(define (filter pred lst) (cond ((null? lst) null) ((pred (car lst)) (cons (car lst) (filter pred (cdr lst)))) (else (filter pred (cdr lst))))) Filtering: process (filter odd? (list 1 2 3 4)) (cons 1 (filter odd? (list 2 3 4))) (cons 1 (filter odd? (list 3 4))) (cons 1 (cons 3 (filter odd? (list 4)))) (cons 1 (cons 3 (filter odd? null))) (cons 1 (cons 3 null)) (1 3) מבוא מורחב - שיעור 8
2 3 4 5 6 7 8 9 10 2 X X 7 X XX 11 12 13 14 15 16 17 18 19 20 XX XX XX XX XX XX 21 22 23 24 25 26 27 28 29 30 XX XX XX XX XX XX XX 3 5 X X XX 31 32 33 34 35 36 37 38 39 40 XX XX XX XX XX XX XX XX XX XX XX 41 42 43 44 45 46 47 48 49 50 XX XX XX XX XX XX XX XX XX XX XX XX XX 51 52 53 54 55 56 57 58 59 60 XX XX XX XX XX XX XX XX XX XX XX 61 62 63 64 65 66 67 68 69 60 XX XX XX XX XX XX XX XX XX XX XX XX 71 72 73 74 75 76 77 78 79 80 XX XX XX XX XX XX XX XX XX XX XX XX 81 82 83 84 85 86 87 88 89 90 XX XX XX XX XX XX XX XX XX XX XX XX XX 91 92 93 94 95 96 97 98 99 100 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX Finding all the Primes: Sieve of Eratosthenes (a.k.a. Beta) מבוא מורחב - שיעור 8
.. And here’s how to do it! (define (sieve lst) (if (null? lst) ‘() (cons (car lst) (sieve (filter (lambda (x) (not (divisible? x (car lst)))) (cdr lst)))))) ==> (sieve (list 2 3 4 5 … 100)) (cons 2 (sieve (filter (lambda (x) (not (divisible? X 2) (list 3 4 5 …100 )))) מבוא מורחב - שיעור 8
How sieve works (define (sieve lst) (if (null? lst) ‘() (cons (car lst) (sieve (filter (lambda (x) (not (divisible? x (car lst)))) (cdr lst)))))) • Sieve takes as argument a list of numbers L and returns a list M. • Take x, the first element of L and make it the first element in M. • Drop all numbers divisible by x from (cdr L). • Call sieve on the resulting list, to generate the rest of M. מבוא מורחב - שיעור 8
66 (about two thirds) Another example Find the number of integers x in the range [1…100] s.t.: x * (x + 1) is divisible by 6. (length (filter _____________________________________ (map _________________________________ _________________________________)))) (lambda(n) (= 0 (remainder n 6))) (lambda(n) (* n (+ n 1))) (integers-between 1 100) Any bets on the result???? מבוא מורחב - שיעור 8
A new pattern: Accumulation מבוא מורחב - שיעור 9
Accumulating Add up the elements of a list (define (add-up lst) (if (null? lst) 0 (+ (car lst) (add-up (cdr lst))))) Multiply all the elements of a list (define (mult-all lst) (if (null? lst) 1 (* (car lst) (mult-all (cdr lst))))) (define (accumulate op init lst) (if (null? lst) init (op (car lst) (accumulate op init (cdr lst))))) מבוא מורחב - שיעור 9
eln eln-1 init el1 …….. op op op ... op Accumulating (cont.) (define (accumulate op init lst) (if (null? lst) init (op (car lst) (accumulate op init (cdr lst))))) (define (add-up lst) (accumulate + 0 lst)) (define (mult-all lst) (accumulate * 1 lst)) מבוא מורחב - שיעור 9
1 2 3 1 2 3 Accumulate: process (define (accumulate op init lst) (if (null? lst) init (op (car lst) (accumulate op init (cdr lst))))) • (accumulate append ‘()(list (list 1) (list 2) (list 3))) (append ‘(1) (accumulate append ‘() ‘((2)(3)))) (append ‘(1) (append ‘(2) (accumulate append ‘()‘((3))))) (append ‘(1) (append ‘(2) (append ‘(3) (accumulate append ‘()‘())))) (append ‘(1) (append ‘(2) (append ‘(3) ‘()))) (append ‘(1) (append ‘(2) ‘(3))) (append ‘(1) ‘(2 3)) (1 2 3) מבוא מורחב - שיעור 9
eln eln-1 0 el1 …….. +1 +1 +1 ... +1 eln eln-1 lst2 el1 …….. ... Length and append as accumulation (define (length lst) (accumulate (lambda (x y) (+ 1 y)) 0 lst)) (define (append lst1 lst2) (accumulate cons lst2 lst1) מבוא מורחב - שיעור 9
Implementing map and filterusing accumulate (define (map proc lst) (accumulate (lambda (x y) (cons (proc x) y)) ‘() lst)) (define (filter pred lst) (accumulate (lambda (x y) (if (pred x) (cons x y) y) ‘() lst)) מבוא מורחב - שיעור 9
Another accumulate example We need to implement (more-evens lst), that receives a list of integers and returns #t iff lst contains more even integers than odd integers. (define (more-evens? l) (positive? (accumulate _________________________ _________________________ ___ l))) (lambda(x y) (+ y (if (even? x) 1 –1))) 0 מבוא מורחב - שיעור 9
(define (dot-product x y) (accumulate ) The generalized map! Yet another example: dot product (dot-product x y) returns Sixiyi + 0 (map * x y) מבוא מורחב - שיעור 9
Lists as interfaces מבוא מורחב
Common Structure (define (even-fibs n) (define (next k) (if (< n k) nil (let ((f (fib k))) (if (even? f) (cons f (next (+ k 1))) (next (+ k 1)))))) (next 0)) (define (sum-odd-squares tree) (cond ((null? tree) 0) ((leaf? tree) (if (odd? tree) (square tree) 0)) (else (+ (sum-odd-squares (car tree)) (sum-odd-squares (cdr tree)))))) מבוא מורחב
Even-fibs • Enumerates the integers from 0 to n • Computes the Fibonacci number for each integer • Filters them selecting the even ones • Accumulates the results using cons • Sum-odd-squares • Enumerates the leaves of a tree • Filters them, selecting the odd ones • Squares each of the selected ones • Accumulates the results using +
tree 0 + square odd? enumerate leaves accumulate map filter 0, n cons nil even? fib integers between accumulate filter map even-fibs sum-odd-squares in a tree Interface: Along horizontal arrows flow lists of numbers מבוא מורחב
0, n cons nil even? fib integers between accumulate filter map even-fibs - Implementation (define (even-fibs n) (accumulate cons nil (filter even? (map fib (integers-between 0 n)))))
tree 0 + square odd? enumerate leaves accumulate map filter sum-odd-squares - Implementation (define (sum-odd-squares tree) (accumulate + 0 (map square (filter odd? (enumerate-leaves tree)))))
Lists as interfaces • An algorithm as a series of steps performed on sequences (lists). • Each step performs a simple operation. • Start with a given list, or by creating a list. • Other steps use filter or map. • Finally, generate final result by accumulation. • Example : Even-fibs-prod (product of all fib numbers with even index between lo and hi) • Enumerate the integers from lo to hi • Filter them selecting the even ones • Compute the Fibonacci number for each integer using map • Accumulates the results using * and 1 מבוא מורחב - שיעור 9
even-fibs-prod (define (even-fibs-prod lo hi) (accumulate * 1 (map fib (filter even? (integers-between lo hi))))) Compare with: (define (even-fibs-prod lo hi) (cond ((> lo hi) 1) ((even? lo) (* (fib lo) (even-fibs-prod (+ lo 1) hi))) (else (even-fibs-prod (+ lo 1) hi)))) מבוא מורחב - שיעור 9
integersbetween lo, hi * 0 fib even? (optional) generate generate accumulate map filter accumulate .... filter/map filter/map Even-fibs-prod Interface: Along horizontal arrows flow lists of numbers A common way to structure a computation: מבוא מורחב - שיעור 9
What did we gain • A conventional way to partition a problem into small tasks. • Resulting code is clearer, easier to design and understand. • But sometimes less efficient. מבוא מורחב - שיעור 9