














Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Community
Ask the community for help and clear up your study doubts
Discover the best universities in your country according to Docsity users
Free resources
Download our free guides on studying techniques, anxiety management strategies, and thesis advice from Docsity tutors
Recursion Basic Beginner questions by stanford
Typology: Exercises
1 / 22
This page cannot be seen from the preview
Don't miss anything!
Recursion Recursion Recursion Recursion Recursion
Induction^ Induction Induction Induction Induction Induction
Recursive statements (also called self-referential) Recursively (inductively) defined sets Recursively defined functions and their algorithms Recursively defined data structures and recursive algorithms defined on those data structures Recursion vs Iteration 1 2
The Ouroboros is an ancient symbol implying self-reference or a “vicious circle”
This is not a pipe The Barber Paradox A barber shaves all and only those men who do not shave themselves if the barber does not shave himself, he must shave himself if the barber does shave himself, he cannot shave himself The Treachery of Images (1928-29), by René Magritte 3 4
7 8
he was told to sum the first 100 positive integers at a young age while in a class on arithmetic
(1 + 2 + 3 + ... + n) + (n + n-1 + n-2 + ... + 1) = (1+n) + (2+n-1) + (3+n-2)... + (n+1) = n+1 + n+1 + n+1 + ... + n+ = n * (n+1) = 2 * sum(n)
Ex: sum(100) = (100 * 101)/2 = 50*101 = 5050
// inductive sum (count up) int isum(int n) { int sum = 0; for (int i=1; i<=n; ++i) sum += i; return sum; } // recursive sum (count down) int rsum(int n) { assert(n > 0); if (n == 1) return 1; else return n + rsum(n-1); } 9 10
Arithmetic can then be defined recursively in terms of counting up (successor) and counting down (predecessor) succ, pred :: Nat -> Nat -- unary functions succ n = Succ n -- count up by prepending Succ to n pred (Succ n) = n -- count down by removing a Succ from n pred Zero = error “no predecessor of Zero” add, mult :: (Nat, Nat) -> Nat -- binary functions add (n, Zero) = n add (Zero, m) = m add (n, m) = succ(add(n, pred m)) -- succ of n, m times mult (n, Zero) = Zero mult (Zero, m) = Zero mult (n, m) = add(n, mult(n, pred m)) -- succ of n, n+m times
A calculator using Peano Arithmetic: PA> pred Zero *** Exception: no predecessor of Zero PA> succ Zero Succ (Zero) PA> pred (Succ Zero) Zero PA> add(Succ Zero, Succ (Succ Zero)) Succ (Succ (Succ (Zero))) PA> add(Succ Zero, Succ (Succ (Succ (Succ Zero)))) Succ (Succ (Succ (Succ (Succ (Zero))))) PA> mult(Succ (Succ Zero), Succ (Succ (Succ (Succ Zero)))) Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ(Zero)))))))) 13 14
gcd :: (Int, Int) -> Int gcd (x, y) = gcd’ (abs x) (abs y) where gcd’ x 0 = x gcd’ x y = gcd’ y (x mod y) gcd (-98, 16) = gcd’ 16 (98 mod 16) = gcd’ 16 2 = gcd’ 2 (16 mod 2) = gcd’ 2 0 = 2 15 16
data [a] = [] | a : [a] 3:[] = [3]; 2:[3] = [2,3]; 1:[2,3] = [1,2,3] = 1:2:3:[]
map :: (a -> b) -> [a] -> [b] map f xs = [ f x | x <- xs ] map square [1,2,3] => [1,4,9] filter :: (a -> bool) -> [a] -> [b] filter p xs = [ x | x <- xs, p x] cprod :: [a] -> [b] -> [(a,b)] cprod xs ys = [(x,y) | x <- xs, y <- ys] 19 20
length :: [a] -> Int -- [a] means a list of any type ‘a’ length [] = 0 -- empty list is the base case length (h:t) = 1 + length t sum :: (Num a) => [a] -> Int -- type of a must be subtype of Num sum [] = 0 -- empty list is the base case sum (h:t) = h + sum t mean :: (Num a) => [a] -> Float mean lst = sum lst / length lst -- Note: mean above requires 2 traversals of the list! -- Can we compute the mean using just one traversal? -- let (x,y) be an ordered pair and fst (x,y) = x, snd (x,y) = y sumlen :: (Num a) => [a] -> (Int,Int) -> (Int,Int) sumlen [] = p sumlen (h:t) p (^) = sumlen t (h + fst(p), 1 + snd(p)) mean lst = fst(p) / snd(p) where p = sumlen lst (0,0)
-- list concatenation infix operator (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) Ex: [1,2,3] ++ [4,5,6] => [1,2,3,4,5,6] -- index infix operator, starting at index 0 (!!) :: [a] -> Int -> a xs !! n | n<0 = error "Prelude.!!: negative index" [] !! _ = error "Prelude.!!: index too large" (x:) !! 0 = x (:xs) !! n = xs !! (n- Ex: [1,2,3,4,5] !! 4 => 5 take :: Int -> [a] -> [a] take n _ | n <= 0 = [] take _ [] = [] take n (x:xs) = x : take (n-1) xs Ex: take 5 [1..] => [1,2,3,4,5] 21 22
map :: (a -> b) -> [a] -> [b] map f (x:xs) = f x : map f xs -- or with a list comprehension: [f x | x <- xs] -- map any function of type (a->b) across a list map length [[],[1,2,3],[‘A’,‘C’,‘T’,’G’] => [0,3,4] map even [1,2,3,4,5] => [False,True,False,True,False] map Char.ord [‘A’,’T’,’C’,’G’] => [65,67,84,71] -- (+5) is called a “section” -- (+) :: a->a->a but (+5),(5+) :: a->a map (+5) [1,2,3,4,5] => [6,7,8,9,10] map (5+) [1,2,3,4,5] => [6,7,8,9,10] -- (\x -> x * x) is an anonymous “lambda” function map (\x -> x * x) [1,2,3,4,5] => [1,4,9,16,25]
fibs :: [Integer] fibs = 0 : 1 : zipWith (+) fibs (tail fibs) fiblist :: Int -> [Integer] fiblist n = take n fibs fib :: Int -> Integer fib n = fibs !! (n-1)
zipWith :: (a->b->c) -> [a] -> [b] -> [c] zipWith z (a:as) (b:bs) = z a b : zipWith z as bs zipWith _ _ _ = [] 25 26
p :: (Num a) => a -> [a] -> a p x coeffs = h x (reverse coeffs) where h x (a:[]) = a h x (a:as) = (h x as) * x + a 27 28
data BinTree a = Leaf a | Root a (BinTree a) (BinTree a) preorder :: BinTree a -> [a] preorder (Leaf v) = [v] preorder (Root v l r) = [v] ++ preorder l ++ preorder r inorder :: BinTree a -> [a] inorder (Leaf v) = [v] inorder (Root v l r) = inorder l ++ [v] ++ inorder r postorder :: BinTree a -> [a] postorder (Leaf v) = [v] postorder (Root v l r) = postorder l ++ postorder r ++ [v]
31 32
sort :: (Ord a) => [a] -> [a] sort [] = [] -- base case sort (x:[]) = [x] -- singleton list sort (pivot:rest) = sort left ++ [pivot] ++ sort right where left = [x | x <- rest, x <= pivot] right = [y | y <- rest, y > pivot] 33 34
requires O(1) stack space instead of O(n) stack space © M. C. Escher
int tfact (int n, int m=1) { return (n == 0 || n == 1)? m : tfact(n-1, m*n); }
n=3- m=1* Frame #1 Frame #1 Frame # n=2- m=3* 37 38
_tfact: pushl %ebp movl %esp, %ebp subl $40, %esp cmpl $1, 8(%ebp) je L cmpl $0, 8(%ebp) jne L L14: movl 12(%ebp), %eax movl %eax, -12(%ebp) jmp L L16: movl 12(%ebp), %eax imull 8(%ebp), %eax movl 8(%ebp), %edx subl $1, %edx movl %eax, 4(%esp) movl %edx, (%esp) call _tfact movl %eax, -12(%ebp) L17: movl -12(%ebp), %eax leave ret
_tfact: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl $1, %edx jbe L L26: imull %edx, %eax subl $1, %edx cmpl $1, %edx ja L L22: popl %ebp ret 39 40