TU Wien:Funktionale Programmierung VU (Knoop)/Prüfung 2009-06-25

Aus VoWi
Zur Navigation springen Zur Suche springen

Aufgabe 1[Bearbeiten | Quelltext bearbeiten]

50% Geben sie den Wert bzw. allgemeinsten Typ fuer t1 bis t7 an! (Die Werte sind mit mnr=[0,1,2,3,4,5,6] und name = "Mustermann, Max" zustande gekommen)

t1 = ( ( 27, mnr!!0, mnr!!6), (head mnr, head name), (tail.tail) mnr );
-- t1 == ((27,0,6),(0,'M'),[2,3,4,5,6])

t2 = (\x y z -> x(z));
-- t2::(a -> b) -> c -> a -> b

t3 = t2 (sum) (product) (mnr) 
-- t3=21

t4 = ( [i|i <-mnr, i `mod` 3 == 0], [(i,i-i)|i<-mnr] );
-- t4 == ([0,3,6],[(0,0),(1,0),(2,0),(3,0),(4,0),(5,0),(6,0)])

t5 = [(i, sum[5..i])|i<-(tail mnr)];
-- t5 == [(1,0),(2,0),(3,0),(4,0),(5,5),(6,11)]

ml n l = [ l!!i | i <- [6,n,4], i < length l];

t6 = ( ml 5 mnr, [(i,j)|i<- ml 5 mnr, j<- ml 5 mnr, i<j] )
-- t6 == ([6,5,4], [(5,6),(4,6),(4,5)])

p (a:b:l) xs ys = p l ( a:xs) ( b:ys );

p _ xs ys = (sum xs, product ys);

t7 = ( p [ mnr!!5, mnr!!6] [] [], p mnr [] []);
-- t7 == ((5,6),(6,15))

Aufgabe 2[Bearbeiten | Quelltext bearbeiten]

Polymorphen Datentyp TTree definieren: darzustellen ist ein Ternärer Baum mit einem Integer und einem polymorphem Element sowohl in den Blättern als auch in den Knoten.


data TTree a = Node Integer a (TTree a) (TTree a) (TTree a)| Leaf Integer a

Aufgabe 3[Bearbeiten | Quelltext bearbeiten]

(Node 0 'a' (Node 1 'b' (Leaf 4 'e') (Leaf 5 'f') (Leaf 6 'g')) (Leaf 2 'c') (Leaf 3 'd'))

		N:0,a
	     /    |    \
	N:1,b	L:2,c	L:3,d
      /   |   \
 L:4,e  L:5,f  L:6,g

Aufgabe 4[Bearbeiten | Quelltext bearbeiten]

wiederholungsfrei :: TTree a -> Bool wenn zwei unmittelbar hintereinanderfolgende Werte gleich sind soll False ausgegeben werden. Die Durchmusterungsreihenfolge war: Unterbaum1, Unterbaum2, Unterbaum3, Knoten.

Lösung 1[Bearbeiten | Quelltext bearbeiten]

Nicht besonders performant, aber sollte beim Test so durchgehen.

wiederholungsfrei :: TTree a -> Bool
wiederholungsfrei tree = whf_helper (tail (tTreeToList tree)) (head (tTreeToList tree))

whf_helper :: [Integer] -> Integer -> Bool
whf_helper [] v = True
whf_helper (x:xs) v
	| x == v	= False
	| otherwise	= whf_helper xs x

tTreeToList :: TTree a -> [Integer]
tTreeToList (Leaf x _) = [x]
tTreeToList (Node x _ t1 t2 t3) = tTreeToList t1 ++ tTreeToList t2 ++ tTreeToList t3 ++ [x]

sollte nun stimmen (whf_helper: otherwise-rekursion eingebaut) --85.127.102.66 13:43, 20. Jan. 2010 (CET)

Lösung 2[Bearbeiten | Quelltext bearbeiten]

wiederholungsfrei :: TTree a -> Bool
wiederholungsfrei t = not $ elem True [ fst (l!!i) == fst (l!!(i+1)) | i <- [0..((length l) - 2)]]
					  where l = flatten t

flatten :: TTree a -> [(Integer,a)]
flatten (Leaf i v) = [(i,v)]
flatten (TT i v n1 n2 n3) = flatten n1 ++ flatten n2 ++ flatten n3 ++ [(i,v)]

Aufgabe 5[Bearbeiten | Quelltext bearbeiten]

alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer, a)]

alle_von_bis t v b

soll den Baum wie in Beispiel 4 durchgehen. zurückgegeben werden soll eine liste mit tupeln, die den integer und polymorphen wert aller knoten vom ersten auftreten des werts v bis zum ersten auftreten des werts b enthält. zB.:

alle_von_bis (Node 3 'a' (Node 1 'b' (Leaf 2 'c') 
                                     (Leaf 1 'a') 
                                     (Leaf 3 'a')) 
                         (Leaf 4 'x') 
                         (Leaf 5 'x')) 1 4 
                         == [(1,'a'),(3,'a'),(1,'b'),(4,'x')]

Lösung[Bearbeiten | Quelltext bearbeiten]

alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer, a)] 
alle_von_bis tree v b = alle_bis (alle_von (tTreeToList2 tree) v) [] b

alle_von :: [(Integer,a)] -> Integer -> [(Integer,a)]
alle_von [] v = []
alle_von (x:xs) v
	| fst(x) == v	= (x:xs)
	| otherwise	= alle_von xs v
	
alle_bis :: [(Integer,a)] -> [(Integer,a)] -> Integer -> [(Integer,a)]
alle_bis [] result _ = result
alle_bis (x:xs) result b
	| fst(x) == b	= result ++ [x]
	| otherwise	= alle_bis xs (result ++ [x]) b

tTreeToList2 :: TTree a -> [(Integer, a)]
tTreeToList2 (Leaf v g)			= [(v,g)]
tTreeToList2 (Node v g t1 t2 t3)	= tTreeToList2 t1 ++ tTreeToList2 t2 ++ tTreeToList2 t3 ++ [(v,g)]



andere lösung 28.02.2010


alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer, a)] 
alle_von_bis tree v b = alle_bis (alle_von (tTreeToList2 tree) v) b
 
alle_von :: [(Integer,a)] -> Integer -> [(Integer,a)]
alle_von [] v = []
alle_von (x:xs) v
	| fst(x) == v	= (x:xs)
	| otherwise	= alle_von xs v

alle_bis :: [(Integer,a)] -> Integer -> [(Integer,a)]
alle_bis [] a = []
alle_bis (x:xs) b
	| fst(x) /= b	= [x] ++ alle_bis xs b
	| otherwise	= [x]

tTreeToList2 :: TTree a -> [(Integer, a)]
tTreeToList2 (Leaf v g)			= [(v,g)]
tTreeToList2 (Node v g t1 t2 t3)	= tTreeToList2 t1 ++ tTreeToList2 t2 ++ tTreeToList2 t3 ++ [(v,g)]

für Schreibfaule


alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer, a)]
alle_von_bis tree v b = 
    takeWhile (\x -> fst(x) /= b) (dropWhile (\x -> fst(x) /= v) treelist)
    where
    treelist = treetolist tree

treetolist :: TTree a -> [(Integer, a)]
treetolist (Leaf i elem) = [(i, elem)]
treetolist (Node i elem left middle right) = treetolist left ++ treetolist middle ++ treetolist right ++ [(i, elem)]

Dir geht dann aber das letzte Element verloren:
[(1,'a'),(3,'a'),(1,'b')]

noch eine Lösung 19.01.2011


alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer,a)]
alle_von_bis t v b = reverse (dropTo (reverse (dropTo (treeToList t) v)) b)
    where
    treeToList :: TTree a -> [(Integer,a)]
    treeToList (Leaf x y) = [(x,y)]
    treeToList (Node x y first second third) = (x,y) : rest
	where
	rest = (treeToList third) ++ (treeToList second) ++ (treeToList first)

    dropTo :: [(Integer,a)] -> Integer -> [(Integer,a)]
    dropTo [] _ = []
    dropTo ((x,y):xs) b
	| x == b	= ((x,y):xs)
	| otherwise	= dropTo xs b

weitere Lösung [14.01.2013]


-- Funktion laut Angabe. Helper-Funktion wird mit einem False-Flag aufgerufen, dh es wurde
-- noch kein Element ermittelt, welches in die Ziel-Liste gehört (Initialisierungsdefault).
alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer, a)]
alle_von_bis t v b = alle_von_bis_helper l v b False
	                 where l = flatten t

-- Läuft die Liste durch, und anhand eines Flags, welches bei 'von' auf True gesetzt wird, 
-- werden nachfolgend alle Elemente bis 'bis' genommen.
alle_von_bis_helper :: [(Integer, a)] -> Integer -> Integer -> Bool -> [(Integer, a)]
alle_von_bis_helper [] _ _ _ = []
alle_von_bis_helper t@(e@(i,w):r) v b f = if f == False && i == v then
	                                        [e] ++ alle_von_bis_helper r v b True
	                                      else if f == True && i /= b then
	                                      	[e] ++ alle_von_bis_helper r v b True
	                                      else if f == True && i == b then
	                                      	[e]
	                                      else
	                                      	alle_von_bis_helper r v b f

-- Alternative zu alle_von_bis_helper ohne if-else
alle_von_bis_helper2 :: [(Integer, a)] -> Integer -> Integer -> Bool -> [(Integer, a)]
alle_von_bis_helper2 [] _ _ _ = []
alle_von_bis_helper2 t@(e@(i,w):r) v b f
  | f == False && i == v  = [e] ++ alle_von_bis_helper2 r v b True
  | f == True  && i /= b  = [e] ++ alle_von_bis_helper2 r v b True
  | f == True  && i == b  = [e]
  | otherwise             = alle_von_bis_helper2 r v b f

-- Plättet den Baum und liefert das Integer und den Polymorphen Wert zurück.
flatten :: TTree a -> [(Integer,a)]
flatten (Leaf i v) = [(i,v)]
flatten (TT i v n1 n2 n3) = flatten n1 ++ flatten n2 ++ flatten n3 ++ [(i,v)]