מבוא מורחב 1 lecture #8. מבוא מורחב 2 shall we have some real fun.. lets write a...
Post on 21-Dec-2015
220 views
TRANSCRIPT
מבוא מורחב1
Lecture #8
מבוא מורחב6
Extracting common patterns:High order procedures to handle lists
מבוא מורחב7
Transforming a List (map)
(define (square-list lst) (if (null? lst) nil (cons (square (car lst)) (square-list (cdr lst)))))
(define (double-list lst) (if (null? lst) nil (cons (* 2 (car lst)) (double-list (cdr lst)))))
(define (map proc lst) (if (null? lst) nil (cons (proc (car lst)) (map proc (cdr lst)))))
(define (square-list lst) (map square lst))
(define (double-list lst) (map (lambda (x) (* 2 x)) lst))
define (scale-list lst f) (map (lambda (x) (* f x)) lst))
(scale-list 1-to-4 10) ==>(10 20 30 40)
מבוא מורחב8
Pick odd elements out of a list
(define (odds lst) (cond ((null? lst) nil)
((odd? (car lst)) (cons (car lst) (odds (cdr lst)))) (else (odds (cdr lst)))))
(odds 1-to-4) ==> (1 3)
מבוא מורחב9
Filtering a List (filter)
(define (filter pred lst) (cond ((null? lst) nil) ((pred (car lst)) (cons (car lst) (filter pred (cdr lst)))) (else (filter pred (cdr lst)))))
(filter odd? 1-to-4) ==> (1 3)(filter even? 1-to-4) ==>(2 4)
מבוא מורחב10
More examples
In tirgul:
(define (fib n) (cond ((= n 0) 0) ((= n 1) 1) (else (+ (fib (- n 1)) (fib (- n 2))))))
(map fib (integers-between 10 20)) ==> (55 89 …. 6765)
(filter even? (map fib (integers-between 10 20)))
(map fib (filter even? (integers-between 10 20)))
מבוא מורחב11
Accumulating Results (accumulate)
(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)))))
מבוא מורחב12
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))
eln init
op
eln-1 el1 ……..
opop
op...
מבוא מורחב13
Length as accumulation
(define (length lst) (if (null? lst) 0 (+ 1 (length (cdr lst)))))
(define (accumulate op init lst) (if (null? lst) init (op (car lst) (accumulate op init (cdr lst)))))
(define (length lst) (accumulate (lambda (x y) (+ 1 y))) 0 lst))
מבוא מורחב14
Append as accumulation
(define (append list1 list2) (if (null? list1) list2 (cons (car list1) (append (cdr list1) list2))))
(define (accumulate op init lst) (if (null? lst) init (op (car lst) (accumulate op init (cdr lst)))))
• Rewrite append as an accumulation
(define (append lst1 lst2) (accumulate cons lst2 lst1)
מבוא מורחב15
What did we gain ?
Using our tools:
(define (easy lo hi) (accumulate * 1 (map fib (filter even? (integers-between lo hi)))))
Without:
(define (hard lo hi) (cond ((> lo hi) 1) ((even? lo) (* (fib lo) (hard (+lo 1) hi))) (else (hard (+ lo 1) hi))))
מבוא מורחב16
XX XX
XX
XX
XX XX
XX
XX XX
XX
XX XX
XX
7
XX XX XX XX XX
XX XX XX XX XX
XX XX XX XX XX
XX XX XX XX XX
XX XX XX XX XX
XX XX XX XX XX
XX XX XX XX XX
XX XX XX XX XX
XX XX XX XX XX
XXXX X 2
Finding all the primes
XX XX XX
XX XX XX XX
XX XX XX
XX XX XX
XX XX XX XX
XX XX XX
XX XX XX
XX XX XX XX
XX XX XX
X X 3
100999897969594939291
90898887868584838281
80797877767574737271
60696867666564636261
60595857565554535251
50494847464544434241
40393837363534333231
30292827262524232221
20191817161514131211
1098765432
XX XX
XX XX
XX XX
XX XX
XX XX
XX XX
XX XX
XX XX
XX XX
XX 5
מבוא מורחב17
.. And here’s how to do it!
(define (sieve lst)
(if (null? lst)
nil
(cons (car lst)
(sieve
(filter (lambda (x)
(not (divisible? x (car lst))))
(cdr lst))))))
(sieve (integers-between 2 420))(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419)
מבוא מורחב18
View a list as a tree
מבוא מורחב19
Trees
2 4
6 8
2
6 8
4
rootchildren or subtrees
(define tree (list 2 (list 6 8) 4))
We can view a list of possibly other lists and atoms as a tree.
(length tree) ==>
(countleaves tree) ==>
3
4
מבוא מורחב20
countleaves
• Strategy• base case: count of an empty tree is 0• base case: count of a leaf is 1• recursive strategy: the count of a tree is the sum of the countleaves
of each child in the tree.
• Implementation:
(define (countleaves tree) (cond ((null? tree) 0) ;base case ((leaf? tree) 1) ;base case (else ;recursive case (+ (countleaves (car tree)) (countleaves (cdr tree))))))
(define (leaf? x) (not (pair? x)))
מבוא מורחב21
countleaves and substitution model – pg. 2
(define (countleaves tree) (cond ((null? tree) 0) ;base case ((leaf? tree) 1) ;base case (else ;recursive case (+ (countleaves (car tree)) (countleaves (cdr tree))))))
(define (leaf? x) (not (pair? x)))
• Example #2
(countleaves (list 5 7))(countleaves )
(countleaves (5 7) )(+ (countleaves 5) (countleaves (7) ))(+ 1 (+ (countleaves 7) (countleaves nil)))(+ 1 (+ 1 0))==> 2
75
22
countleaves – bigger example
(define my-tree (list 4 (list 5 7) 2))
(countleaves my-tree)(countleaves (4 (5 7) 2) )(+ (countleaves 4) (countleaves ((5 7) 2) ))==> 4
4 2
5 7
my-tree
(cl (4 (5 7) 2))
+
(cl 4) (cl ((5 7) 2) )
+
(cl (5 7)) (cl (2))+
(cl 2) (cl nil)
+
(cl 5) (cl (7))+
(cl 7) (cl nil)
1
1
1 0
1 0
מבוא מורחב23
Your Turn: scale-tree
• Goal: given a tree, produce a new tree with all the leaves scaled
• Strategy• base case: scale of empty tree is empty tree• base case: scale of a leaf is product• otherwise, recursive strategy: build a new tree from a scaled version
of the first child and a scaled version of the rest of children
• Implementation:
(define (scale-tree tree factor) (cond ((null? tree) nil) ;base case ((leaf? tree) (* tree factor)) (else ;recursive case (cons
(scale-tree (cdr tree) )))))
(scale-tree (car tree) factor)
factor
24
Alternative scale-tree
• Strategy
• base case: scale of empty tree is empty tree
• base case: scale of a leaf is product
• otherwise: build a new tree from a scaled version of the children
• recognize that a tree is a list of subtrees and use a list oriented HOP!
• Alternative Implementation using map:
(define (scale-tree tree factor) (cond ((null? tree) nil) ((leaf? tree) (* tree factor)) (else ;it’s a list of subtrees (map (lambda (child) (scale-tree child factor)) tree))))
מבוא מורחב25
Lists as interfaces
מבוא מורחב26
(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 (< k n) nil (let ((f (fib k))) (if (even? f) (cons f (next (+ k 1))) (next (+ k 1)))))) (next 0))
27
Sum-odd-squares
• enumerates the leaves of a tree
• filters them, selecting the odd ones
• squares each of the selected ones
• accumulate the results using +
Even-fibs
• enumerates the integers from 0 to n
• computes the Fibonacci number for each integer
• filters them selecting the even ones
• accumulated the results using cons
מבוא מורחב28
enumerate leaves
filter map accumulate
treeodd? square + 0
integersbetween
map filter accumulate
0, nfib even? cons nileven-fibs
sum-odd-squares
On horizontal arrows flow lists of numbers (interface)
29
Implementation
(define (sum-odd-squares tree) (accumulate + 0 (map square (filter odd? (enumerate-tree tree))))) (define (even-fibs n) (accumulate cons nil (filter even? (map fib
(integers-between 0 n))))) (define (enumerate-tree tree) (cond ((null? tree) nil) ((leaf? tree) (list tree)) (else (append (enumerate-tree (car tree)) (enumerate-tree (cdr tree))))))
מבוא מורחב30
How does the interpreter prints lists and pairs ??
מבוא מורחב31
First version, using dot notation
(define (print-list-structure x) (define (print-contents x) (print-list-structure (car x)) (display " . ") (print-list-structure (cdr x))) (cond ((null? x) (display "()")) ((atom? x) (display x)) (else (display "(") (print-contents x) (display ")"))))
(p-l-s (list 1 2 3)) ==> (1 . (2 . (3 . ())))
32
Second version, try to identify lists
(define (print-list-structure x) (define (print-contents x) (print-list-structure (car x)) (cond ((null? (cdr x)) nil) ((atom? (cdr x)) (display " . ") (print-list-structure (cdr x))) (else (display " ") (print-contents (cdr x))))) (cond ((null? x) (display "()")) ((atom? x) (display x)) (else (display "(") (print-contents x) (display ")"))))
(p-l-s (list 1 2 3)) ==> (1 2 3)
מבוא מורחב33
More examples
How to create the following output ?
( 1 2 . 3)
(cons 1 (cons 2 3))
(1. 2 3)
cannot