; Mathematical functions in Scheme ; - some neat procedures we can write fairly simply ; - procedures that are complicated to analyze the runtime of ; ; an example Euclid's Greatest Common Divisor Algorithm ; - one of the very algorithms ; - very efficient ; - interesting to analyze (define Euclid-GCD (lambda (a b) (if (= b 0) a (Euclid-GCD b (remainder a b))))) ; the principle that it relies on is: ; if d divides a and d divides b, then d divides (remainder a b) ; to see this, write a = qb + r ; so if d divides a and b then d also divides r (the remainder) ; notice that after two steps ; (Euclid-GCD a b) ; becomes ; (Euclid-GCD (remainder a b) (remainder b (remainder a b))) ; ; how large is (remainder a b) in comparison to a? ; answer: b-1 ; a = qb + r ; > b + r ; > r + r ; so r < a/2 ; so if initially, a>b, then after two steps, a has been cut in half ; so how many times is Euclid-GCD called total? ; at most 2*(# of times we can cut a in half until a<= 1) ; what is (# of times we can cut a in half until a<= 1)? ; let i = (# of times we can cut a in half until a<= 1) ; for the rest of this section lg = log base 2 ; then i = lg(a) ; so if a is initially greater than b, (Euclid-GCD a b) is called at most 2*lg(a) times ; what if b>a initially? then the procedure just switches the arguments! ; so (Euclid-GCD 128964898924689123647891607895613894517836571365896389589165789623789562348962589235897235897238957238957238957893735897238957238957523897235897589723890572389075239075903725907239057823590723590 789235783572387589235789357892357893578923578923578935789357289235789235789735897358273589) ; should run very quickly -- and it does!