מבוא מורחב - שיעור 91 Lecture 9 Lists continued: Map, Filter, Accumulate, Lists as interfaces
מבוא מורחב - שיעור 82 Last Lecture: some basic list operations
מבוא מורחב - שיעור 83 Append: process (append list1 list2) (cons 1 (append ‘(2) list2)) (cons 1 (cons 2 (append ‘() list2))) (cons 1 (cons 2 list2)) (define (append list1 list2) (cond ((null? list1) list2) ; base (else (cons (car list1) ; recursion (append (cdr list1) list2))))) list2 list1 12 ( ) (define list1 (list 1 2)) (define list2 (list 3 4)) Quote: what you see is what you get.
6/10/20154 Reverse of a list (reverse (list )) (define (reverse lst) (cond ((null? lst) lst) (else ( (reverse (cdr lst)) ))))) append (list (car lst)) (append ) (reverse (cdr lst))(list (car lst)) Append: T(n) = c*n = (n) Reverse: T(n) = c*(n-1) + c*(n-2)+ … + c*1 = (n 2 )
מבוא מורחב - שיעור 85 Reverse (reverse (list 1 2 3)) (append (reverse (2 3)) (1)) (append (append (reverse (3)) (2)) (1)) (append (append (append (reverse ()) (3)) (2)) (1)) (append (append (append null (3)) (2)) (1)) (append (append (3) (2)) (1)) (append (3 2) (1)) (3 2 1) (define (reverse lst) (cond ((null? lst) lst) (else (append (reverse (cdr lst)) (list (car lst))))))) Append: T(n1) = c*n1 = (n1) (n1 is length of list1) Reverse: T(n) = c*(n-1) + c*(n-2) … c*1 = (n 2 ) (reverse (list 1 2 3)) (3 2 1)
מבוא מורחב - שיעור 86 Enumeration (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) (define (integers-between lo hi) (cond ((> lo hi) null) (else (cons lo (integers-between (+ 1 lo) hi))))) 234
מבוא מורחב - שיעור 87 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)) 42 57
מבוא מורחב - שיעור 88 Countleaves (countleaves my-tree ) ==> 4 (cl (4 (5 7) 2)) + (cl 4)(cl ((5 7) 2) ) + (cl (5 7))(cl (2)) + (cl 2) (cl null) + (cl 5) (cl (7)) + (cl 7) (cl null) my-tree
מבוא מורחב - שיעור 89 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))))))
מבוא מורחב - שיעור 810 List abstraction Find common high order patterns Distill them into high order procedures Use these procedures to simplify list operations Mapping Filtering Accumulating Patterns:
מבוא מורחב - שיעור 811 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) ==> ( )
מבוא מורחב - שיעור 812 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)
מבוא מורחב - שיעור 813 Generalized Mapping (map + (list 1 2 3) (list ) (list )) ==> ( ) (map (lambda (x y) (+ x (* 2 y))) (list 1 2 3) (list 4 5 6)) ==> ( ) (map … ) Returns a list in which proc is applied to the i-th elements of the lists respectively. We will see how to write such a procedure later!
מבוא מורחב - שיעור 814 Filtering (define (filter pred lst) (cond ((null? lst) null) ((pred (car lst)) (cons (car lst) (filter pred (cdr lst)))) (else (filter pred (cdr lst))))) (filter odd? (integers-between 1 10)) ( )
מבוא מורחב - שיעור 815 Filtering: process (define (filter pred lst) (cond ((null? lst) null) ((pred (car lst)) (cons (car lst) (filter pred (cdr lst)))) (else (filter pred (cdr lst))))) (filter odd? (list )) (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)
מבוא מורחב - שיעור 816 Finding all the Primes: Sieve of Eratosthenes (a.k.a. Beta)
מבוא מורחב - שיעור 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)))))) (cons 2 (sieve (filter (lambda (x) (not (divisible? X 2) (list …100 )))) ==> (sieve (list … 100))
מבוא מורחב - שיעור 818 How sieve works 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. (define (sieve lst) (if (null? lst) ‘() (cons (car lst) (sieve (filter (lambda (x) (not (divisible? x (car lst)))) (cdr lst))))))
מבוא מורחב - שיעור 819 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) (* n (+ n 1))) (integers-between 1 100) (lambda(n) (= 0 (remainder n 6))) Any bets on the result???? 66 (about two thirds)
מבוא מורחב - שיעור 920 A new pattern: Accumulation
מבוא מורחב - שיעור 921 Accumulating (define (add-up lst) (if (null? lst) 0 (+ (car lst) (add-up (cdr lst))))) (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))))) Add up the elements of a list Multiply all the elements of a list
מבוא מורחב - שיעור 922 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)) el n init op el n-1 el 1 …….. op...
מבוא מורחב - שיעור 923 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)
מבוא מורחב - שיעור 924 Length and append as accumulation (define (length lst) (accumulate (lambda (x y) (+ 1 y)) 0 lst)) (define (append lst1 lst2) (accumulate cons lst2 lst1) 0 el n +1 el n-1 el 1 …… el n lst2 el n-1 el 1 …….....
מבוא מורחב - שיעור 925 Implementing map and filter using 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))
מבוא מורחב - שיעור 926 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
מבוא מורחב - שיעור 927 Yet another example: dot product (dot-product x y) returns i x i y i (define (dot-product x y) (accumulate ) + 0 (map * x y) The generalized map!
6/10/2015 מבוא מורחב 28 Lists as interfaces
6/10/2015 מבוא מורחב 29 (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)))))) (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)) Common Structure
6/10/ 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 +
6/10/2015 מבוא מורחב 31 enumerate leaves filter map accumulate tree odd? square + 0 integers between map filter accumulate 0, n fib even? consnil even-fibs sum-odd-squares in a tree Interface: Along horizontal arrows flow lists of numbers
6/10/ even-fibs - Implementation (define (even-fibs n) (accumulate cons nil (filter even? (map fib (integers-between 0 n))))) integers between map filter accumulate 0, n fib even? consnil
6/10/ sum-odd-squares - Implementation (define (sum-odd-squares tree) (accumulate + 0 (map square (filter odd? (enumerate-leaves tree))))) enumerate leaves filter map accumulate tree odd? square + 0
מבוא מורחב - שיעור 934 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 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.
מבוא מורחב - שיעור 935 (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)))) even-fibs-prod
מבוא מורחב - שיעור 936 Even-fibs-prod Interface: Along horizontal arrows flow lists of numbers generate filter map accumulate lo, hi even? fib *0 integers between generate filter/map accumulate.... (optional) A common way to structure a computation:
מבוא מורחב - שיעור 937 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.