Mercurial > 12ws.info2
changeset 32:21721a110098
week 12 tutorial
author | Markus Kaiser <markus.kaiser@in.tum.de> |
---|---|
date | Sat, 19 Jan 2013 18:33:53 +0100 |
parents | d14aab8bbf36 |
children | 71b56f8b3069 |
files | exercises/src/Exercise_12.hs |
diffstat | 1 files changed, 163 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/exercises/src/Exercise_12.hs Wed Jan 16 19:21:23 2013 +0100 +++ b/exercises/src/Exercise_12.hs Sat Jan 19 18:33:53 2013 +0100 @@ -7,21 +7,35 @@ {- Ausdruck: 1 + (2 * 3) +(2 * 3) Innermost +1 + (2 * 3) Outermost Ausdruck: (1 + 2) * (2 + 3) +(1 + 2) Innermost +(2 + 3) Innermost +(1 + 2) * (2 + 3) Outermost Ausdruck: fst (1 + 2, 2 + 3) +(1 + 2) Innermost +(2 + 3) Innermost +fst (1 + 2, 2 + 3) Outermost Ausdruck: fst (snd (1, 2 + 3), 4) +(2 + 3) Innermost +snd (1, 2 + 3) +fst (snd (1, 2 + 3), 4) Outermost -Ausdruck: (\x. 1 + x) (2 * 3) +Ausdruck: (\x -> 1 + x) (2 * 3) +(2 * 3) Innermost +(\x -> 1 + x) (2 * 3) Outermost + +-} --} {---------------------------------------------------------------------} {- Aufgabe G12.2 -} @@ -34,25 +48,147 @@ f (x1:x2:xs) ys (z:zs) = x1 a = f (inf (1+0)) (inf (1+1)) (inf (1+2)) +{- +f (inf (1+0)) (inf (1+1)) (inf (1+2)) +-> f ((1+0) : inf (1+0)) ((1+1) : inf (1+1)) (inf (1+2)) +-> f (1 : inf 1) (2 : inf 2) (inf (1+2)) +-> f (1 : 1 : inf 1) (2 : inf 2) ((1+2) : inf (1+2)) +-> 1 +-} + b = f (inf (1+2)) (inf (1+1)) (inf (1+0)) +{- +f (inf (1+2)) (inf (1+1)) (inf (1+0)) +-> f ((1+2) : inf (1+2)) ((1+1) : inf (1+1)) (inf (1+0)) +-> f (3 : inf 3) (2 : inf 2) (inf (1+0)) +-> 2 +-} + c = f (inf (1+0)) [] (inf (1+1)) +{- +f (inf (1+0)) [] (inf (1+1)) +-> f ((1+0) : inf (1+0)) [] (inf (1+1)) +-> f ((1+0) : (1+0) : inf (1+0)) [] ((1+1) : inf (1+1)) +-> (1+0) +-> 1 +-} + +{- Musterlösung -} +{- Aufruf: + - f (inf (1+0)) (inf (1+1)) (inf (1+2)) + - Argumente + - inf (1+0) ~~> 1 : 1: inf 1 + - inf (1+1) ~~> 2 : inf 2 + - inf (1+2) ~~> (1+2) : inf (1+2) + - Warum? + - Zur Auswertung von f wird zunächst Pattern Matching gemacht gegen die erste + - Regel gemacht. Haskell muss also feststellen, ob das erste und zweite + - Argument die Form _:_ (statt []) hat. Das dritte Argument ist nur eine + - Variable, hier muss also noch nichts ausgewertet werden. + - inf (1+0) ~> (1+0) : inf (1+0) + - inf (1+1) ~> (1+1) : inf (1+1) + - inf (1+2) ~> inf(1+2) + - Jetzt wird (unter anderem) x = 1+0 und y = 1+1 gebunden. + - In einem zweiten Schritt muss "x > y" getestet werden, dazu müssen x und y + - ausgewertet werden: + - (1+0) : inf (1+0) ~> 1 : inf 1 + - (1+1) : inf (1+1) ~> 2 : inf 2 + - inf (1+2) ~> inf(1+2) + - Warum wurden jetzt beide 1+0 zu 1 (bzw. beide 1+1 zu 2 ausgewertet)? Weil es + - jeweils der selbe (nicht nur der gleiche Ausdruck war). + - + - "x > y" ist False, deswegen muss jetzt noch die zweite Regel getestet werden. + - Dafür ist es notwendig, das erste Argument zu der Form _:_:_ und das dritte + - Argument zu der Form _:_ auszuwerten: + - 1 : inf 1 ~> 1 : 1 : inf 1 + - 2 : inf 2 ~> 2 : inf 2 + - inf (1+2) ~> (1+2) : inf (1+2) + - Der Rückgabewert ist jetzt 1, was schon vollständig ausgewertet ist und daher + - für die Anzeige nicht weiter ausgewertet werden muss. + -} + +{- Aufruf: + - f (inf(1+2)) (inf(1+1)) (inf(1+0)) + - Argumente: + - inf (1+2) ~> 3 : inf 3 + - inf (1+2) ~> 2 : inf 2 + - inf (1+0) ~> inf (1+0) + - Ähnlich wie oben, nur schlägt hier der Test "x > y" nicht fehl, daher wird das + - dritte Argument nie ausgewertet. + -} + +{- Aufruf + - f (inf (1+0)) [] (inf 0) + - Argumente: + - inf (1+0) ~> 1 : inf 1 + - inf 0 ~> 0 : inf 0 + - Hier wird der Test "x > y" nie erreicht (denn das zweite Argument hat die Form []). + - 1+0 wird dennoch zu 1 ausgewertet, da es der Rückgabewert der Funktion ist und daher + - ausgewertet werden muss, um angezeigt zu werden. + -} + {---------------------------------------------------------------------} {- Aufgabe G12.3 -} +-- Beispiel: Zweierpotenzen +-- powersOfTwo == [1,2,4,8,16,...] +powersOfTwo :: [Integer] +powersOfTwo = 1 : map (*2) powersOfTwo + +-- powerSeriers == [x^y, x^(y+1), x^(y+2), x^(y+3),...] +powerSeries :: Integer -> Integer -> [Integer] +powerSeries x y = x^y : powerSeries x (y+1) + +{- +powersOfTwo +-> 1 : map (*2) powersOfTwo +-> 1 : map (*2) (1 : map (*2) powersOfTwo) +-> 1 : 2 : map (*2) (map (*2) powersOfTwo) +-> 1 : 2 : map (*2) (map (*2) (1 : map ...)) +-> 1 : 2 : map (*2) (2 : (map (*2) (map ...))) +-> 1 : 2 : 4 : map ... +-} + + +-- Aufgabe fib :: Integer -> Integer fib 0 = 0 fib 1 = 1 fib n = fib (n - 1) + fib (n - 2) +fib1 :: [Integer] +fib1 = 0 : 1 : zipWith (+) fib1 (tail fib1) -fib1 :: [Integer] -fib1 = undefined +fib2 :: Integer -> Integer -> [Integer] +fib2 x y = x : fib2 y (x+y) + + +{- +fib1 +-> 0 : 1 : zipWith (+) fib1 (tail fib1) +-> 0 : 1 : zipWith (+) (0 : 1 : zipWith ...) (1 : zipWith ...) +-> 0 : 1 : 1 : zipWith (+) (1 : 1 : zipWith ...) (1 : zipWith ...) +-> 0 : 1 : 1 : 2 : zipWith (+) (1 : 2 : zipWith ...) (2 : zipWith ...) +-> 0 : 1 : 1 : 2 : 3 : zipWith (+) (2 : 3 : zipWith ...) (3 : zipWith ...) -fib2 :: Integer -> Integer -> [Integer] -fib2 x y = undefined +fib2 0 1 +-> 0 : fib2 1 (0+1) +-> 0 : 1 : fib2 (0+1) (1+(0+1)) +-> 0 : 1 : (0+1) : fib2 (1+(0+1)) ((0+1)+((0+1)+1)) +-> 0 : 1 : 1 : fib2 (1+1) (1+(1+1)) +-> 0 : 1 : 1 : (1+1) : fib2 (1+(1+1)) ((1+1)+((1+1)+1)) +-> 0 : 1 : 1 : 2 : fib2 (1+2) (2+(2+1)) +-} + + +{- Um fib n auszuwerten, muss fib (n-1) 2-mal, fib (n - 2) 4-mal, fib (n-3) + - 8-mal, ... ausgewertet werden. Zur Auswertung von fib1 !! n müssen nur die + - ersten (n+1) Elemente von fib1 jeweils 1-mal ausgewertet werden. + - Die Laufzeit ist also linear statt exponentiell. + -} @@ -60,7 +196,27 @@ {- Aufgabe G12.4 -} hamming :: [Integer] -hamming = undefined +hamming = 1 : sort z (sort x y) + where + x = map (*2) hamming + y = map (*3) hamming + z = map (*5) hamming + + sort (x:xs) (y:ys) + | x < y = x : sort xs (y:ys) + | x > y = y : sort (x:xs) ys + | x == y = x : sort xs ys + + +productOf :: [Integer] -> Integer -> Bool +productOf xs y = go xs y + where + go _ 1 = True + go [] y = False + go (z:zs) y = if y `mod` z == 0 then go xs (y `div` z) else go zs y + +hamming' :: [Integer] +hamming' = filter (productOf [2,3,5]) [1 ..]