Mercurial > 12ws.info2
view exercises/src/Exercise_12.hs @ 39:9a7b9e0c9eb0 default tip
week 15 tutorial
author | Markus Kaiser <markus.kaiser@in.tum.de> |
---|---|
date | Fri, 08 Feb 2013 00:06:20 +0100 |
parents | 21721a110098 |
children |
line wrap: on
line source
module Exercise_12 where {---------------------------------------------------------------------} {- Aufgabe G12.1 -} {- 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) (2 * 3) Innermost (\x -> 1 + x) (2 * 3) Outermost -} {---------------------------------------------------------------------} {- Aufgabe G12.2 -} inf :: a -> [a] inf x = x : inf x f :: [Int] -> [Int] -> [Int] -> Int f (x:xs) (y:ys) zs | x > y = y 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) 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 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. -} {---------------------------------------------------------------------} {- Aufgabe G12.4 -} hamming :: [Integer] 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 ..] {---------------------------------------------------------------------} {- Aufgabe H12.1 -} wordsOf :: [a] -> [[a]] wordsOf = undefined {---------------------------------------------------------------------} {- Aufgabe H12.2 -} sumOfPrefixes :: Num a => [a] -> [a] sumOfPrefixes = undefined {---------------------------------------------------------------------} {- Aufgabe H12.3 -} findByFilter :: (a -> Bool) -> [a] -> Maybe a findByFilter = undefined {---------------------------------------------------------------------} {- Aufgabe H12.4 -} {-WETT-} censoredWordsOf :: Eq a => [a] -> [[a]] -> [[a]] censoredWordsOf = undefined {-TTEW-}