TU Wien:Funktionale Programmierung VU (Knoop)/Prüfung 2010-01-21 (Lösung)

Aus VoWi
Zur Navigation springen Zur Suche springen

Prüfung 2010-01-21[Bearbeiten | Quelltext bearbeiten]

Original Angabe zu dieser Prüfung

Aufgabe 1[Bearbeiten | Quelltext bearbeiten]

50% Geben Sie Wert bzw. allgemeinsten Typ für t1 bis t7 an!

name = "Mustermann"
mnr = [0,1,2,3,4,5,6]

t1 = (27, [mnr!!0, mnr!!6], (head mnr, head name), (tail.tail) mnr );
{- t1 == ( 27, [                                         -}

t2 = (\x y z -> x(z)); {- Allgemeinster Typ! -}
{- t2 ::                                                 -}

t3 = t2 (product) (sum) (mnr)
{- t3 ==                                                 -}

t4 = ( [i|i<-mnr, i `mod` 2 == 0], [(i,i>4)|i<-mnr] );
{- t4 == ([                                              -}

t5 = [(i,sum[4..i])|i<-(tail mnr)];
{- t5 == [ (                                             -}

ml n l = [ l!!i | i<-[6,n,4], i< length l ];
t6 = (ml 5 mnr, [(i,i>j,j)|i<-ml 5 mnr, j<-ml 5 mnr, i<j] )
{- t6 == (                                               -}

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 == (                                               -}

Lösung[Bearbeiten | Quelltext bearbeiten]

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)); {- Allgemeinster Typ! -}
{- t2 :: (a -> b) -> c -> a -> b                         -}

t3 = t2 (product) (sum) (mnr)
{- t3 == 0                                               -}

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

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

ml n l = [ l!!i | i<-[6,n,4], i< length l ];
t6 = (ml 5 mnr, [(i,i>j,j)|i<- ml 5 mnr, j<-ml 5 mnr, i<j] )
{- t6 == ([6,5,4],[(5,False,6),(4,False,6),(4,False,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))                                  -}

{- t7 == ((5,6), (0,120)) -} -- meine Loesung ???

deine Lösung stimmt nicht p [0,1,2,3,4,5,6] [] [] -> p [2,3,4,5,6] [0] [1] -> p [4,5,6] [0,2] [1,3] -> p [6] [0,2,4] [1,3,5] => sum [0,2,4] = 6, product [1,3,5] = 15, daraus folgt t7 == ((5,6),(6,15)) ---- by SibaJebacDovlineMame

die Loesung von SJDM sehe ich auch so, allerdings wird auf dem Weg das a und b an den Kopf der List gehaengt. also: p [0,1,2,3,4,5,6] [] [] -> p [2,3,4,5,6] [0] [1] -> p [4,5,6] [2,0] [3,1] -> p [6] [4,2,0] [5,3,1] => sum [4,2,0] = 6, product [5,3,1] = 15 Auch wenn es hier wegen sum und product egal ist, kann es bei anderen Beispielen zu Fehlern fuehren. ---- cheers wastelandgummybear

Aufgabe 2[Bearbeiten | Quelltext bearbeiten]

5% Definieren Sie einen polymorphen algebraischen Datentyp TTree zur Darstellung von ternären Bäumen. Knoten und Blätter sollen neben einem Element Integer ein polymorphes Element enthalten. Es gibt also keine leeren Blätter.

Lösung[Bearbeiten | Quelltext bearbeiten]

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

Aufgabe 3[Bearbeiten | Quelltext bearbeiten]

5% Geben Sie einen konkreten TTree-Baum mit genau zwei Knoten (und passend vielen Blättern) als Zeichnung und in Haskell-Syntax an.

Lösung[Bearbeiten | Quelltext bearbeiten]

ttree :: TTree Char
ttree = (Node 100 'a'   (Node 400 'b' (Leaf 430 'c') (Leaf 420 'd') (Leaf 410 'e'))    (Leaf 120 'f')    (Leaf 110 'g') )

Aufgabe 4[Bearbeiten | Quelltext bearbeiten]

20% Definieren sie wiederholungsfrei, das für einen konkreten Baum genau dann wahr (True) ist, wenn beim Durchwandern des Baums keine zwei gleichen Integer-Einträge (in Blättern oder Knoten) unmittelbar hintereinander vorkommen.

Ein ternärer Knoten wird in folgender Reihenfolge durchwandert: Das Knotenelement, dritter, zweiter, erster Unterbaum.

wiederholungsfrei :: TTree a -> Bool;

Lösung[Bearbeiten | Quelltext bearbeiten]

-- Aufruf: wiederholungsfrei ttree

wiederholungsfrei :: TTree a -> Bool
wiederholungsfrei (Leaf _ _) = True
wiederholungsfrei t0@(Node x _ t3 t2 t1) = 
  wiederholungsfrei t1 &&
  wiederholungsfrei t2 &&
  wiederholungsfrei t3 &&
  notEqVal t0 t1 &&
  notEqVal t1 t2 &&
  notEqVal t2 t3
  
notEqVal :: TTree a -> TTree a -> Bool
notEqVal (Leaf x _) (Leaf y _) = x /= y
notEqVal (Leaf x _) (Node y _ _ _ _) = x /= y
notEqVal (Node x _ _ _ _) (Node y _ _ _ _) = x /= y
notEqVal (Node x _ _ _ _) (Leaf y _) = x /= y

Lösung by Aymeba[Bearbeiten | Quelltext bearbeiten]

wiederholungsfrei :: TTree a -> Bool
wiederholungsfrei (Leaf _ _) = True
wiederholungsfrei tree = checkList liste
			where liste = createList tree

createList :: TTree a -> [Integer]
createList (Leaf i a) = [i]
createList (Node i a t1 t2 t3) = [i] ++ createList t3 ++ createList t2 ++ createList t1

checkList :: [Integer] -> Bool
checkList [] = True
checkList [i] = True
checkList (a:b:l) = if a == b then False else checkList (b:l)

Lösung by patrikf für Schreibfaule[Bearbeiten | Quelltext bearbeiten]

wiederholungsfrei :: TTree a -> Bool;
wiederholungsfrei t = all (uncurry (/=)) $ zip elems $ tail elems
    where elems = walk t

walk :: (TTree a) -> [Integer]
walk (Leaf x _) = [x]
walk (Node x _ a b c) = [x] ++ (concatMap walk [c,b,a])

Lösung von thomas[Bearbeiten | Quelltext bearbeiten]

naive / intutive lösung.

der baum ist wf wenn

  • alle teilbäume wf sind und
  • der aktuelle knotenwert ungleich dem des linken, des mittleren und des rechten teilbaumes des aktuellen knotens ist

ein blatt ist axiomatisch wiederholungsfrei

wf :: TTree a -> Bool
wf (TNode i _ l m r) = (wf r && wf m && wf l) -- reihenfolge nach angabe
                       &&
                       (i /= val r && i /= val m && i /= val l)
  where
    val (TNode i _ _ _ _)	= i
    val (TLeaf i _)		= i
wf _ = True

sehr ähnliche Lösung[Bearbeiten | Quelltext bearbeiten]

whf :: TTree a -> Bool
whf (Leaf (x,y)) = True
whf (Node (x,y) t1 t2 t3) = (x /= (getInt t3)) && (x /= (getInt t2)) && (x /= (getInt t1)) && whf t3 && whf t2 && whf t1

getInt :: TTree a -> Integer
getInt (Leaf (x,y)) = x
getInt (Node (x,y) _ _ _) = x

Lösung Aufgabe 5[Bearbeiten | Quelltext bearbeiten]

20% DEfinieren Sie alle_von_bis t v b, das beim Durchwandern eines Baumes ab dem ersten Integer-Eintrag v bis einschließlich zum danach ersten Integer-Eintrag vorkommenden (polymorphen) Elemente als Paare liefert. Die Reihenfolge ist die gleiche wie bei wiederholungsfrei. Bei unpassenden v und b soll die leere Liste zurückgegeben werden.

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

Lösung[Bearbeiten | Quelltext bearbeiten]

-- Aufruf: alle_von_bis ttree 100 300

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

ttree :: TTree Char
ttree = (Node 100 'a'    (Leaf 500 'f') (Node 400 'b' (Leaf 430 'c') (Leaf 420 'd') (Leaf 410 'e'))       (Leaf 200 'g') )


alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer,a)]
alle_von_bis tree from to = avb (getTupelList tree []) from to []

getTupelList :: TTree a -> [(Integer,a)] -> [(Integer,a)]
getTupelList (Leaf x a) list = ((x,a):list)
getTupelList (Node x a t3 t2 t1) list = ((x,a):list) ++ (getTupelList t1 []) ++ (getTupelList t2 []) ++ (getTupelList t3 [])

avb :: [(Integer, a)] -> Integer -> Integer -> [(Integer,a)] -> [(Integer,a)]
avb [] _ _ _= []
avb ((x,a):rest) from to erg
  | x == from	= avb_to rest to ((x,a):erg)
  | otherwise   = avb rest from to erg
  
avb_to :: [(Integer, a)] -> Integer -> [(Integer,a)] -> [(Integer,a)]
avb_to [] _ _ = []
avb_to ((x,a):rest) to erg
  | x == to	= 
     reverse ((x,a):erg)
  | otherwise	= 
     avb_to rest to ((x,a):erg)

Lösung by aymeba[Bearbeiten | Quelltext bearbeiten]

alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer,a)]
alle_von_bis tree von bis = von_bis (convertPair tree) von bis

von_bis :: [(Integer,a)] -> Integer -> Integer -> [(Integer,a)]
von_bis [] _ _= []
von_bis (p:pairs) von bis = 
			if fst(p) == von then bisPair (p:pairs) bis 
			else von_bis pairs von bis

bisPair :: [(Integer,a)] -> Integer -> [(Integer,a)]
bisPair [] _ = []
bisPair (x:xs) bis = 
		if fst(x) == bis then [x] 
		else [x] ++ bisPair xs bis

convertPair :: TTree a -> [(Integer,a)]
convertPair (Leaf i a) = [(i,a)]
convertPair (Node i a t1 t2 t3) = [(i,a)] ++ convertPair t3 ++ convertPair t2 ++ convertPair t1

Lösung von mir![Bearbeiten | Quelltext bearbeiten]

treetolist :: TTree a -> [(Integer,a)]
treetolist (Leaf a i) = [(a,i)]
treetolist (Node a i l m r) = (a,i) :  treetolist (r) ++ treetolist (m) ++ treetolist (l)

alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer,a)]
alle_von_bis t v b = alle_von_bis_list (treetolist t) v b

alle_von_bis_list :: [(Integer,a)] -> Integer -> Integer -> [(Integer,a)]
alle_von_bis_list l v b
	| (length main) < (length main_trail) = main ++ [ main_trail!!(length main)]
	| otherwise = main -- oder [] je nach interpretation
	where
		main_trail = (dropWhile (\x -> (fst x) /= v) l)
		main = takeWhile (\x -> (fst x) /= b) main_trail

Lösung von r0f1[Bearbeiten | Quelltext bearbeiten]

alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer,a)];
alle_von_bis t v b = if(v>b) then [] else takeWhile (\(x,y) -> x>=v && x<=b) (toList t)

toList :: TTree a -> [(Integer, a)]
toList (Node i j l m r) = [(i,j)] ++ toList r ++ toList m ++ toList l
toList (Leaf i j) = [(i,j)]

Anmerkung von high_stick: Ich nehme an, die Integer-Werte sind nicht aufsteigend, daher darf keine Sortierung oder ähnliches vorausgesetzt werden.

Lösung von high_stick[Bearbeiten | Quelltext bearbeiten]

pairs :: TTree a -> [(Integer,a)]
pairs (Leaf n x) = [(n,x)]
pairs (Node n x a b c) = [(n,x)] ++ pairs c ++ pairs b ++ pairs a

alle_von_bis :: TTree a -> Integer -> Integer -> [(Integer,a)]
alle_von_bis t v b 
	| elem b (map fst list) = takeWhile not_b list ++ [head (dropWhile not_b list ) ]
	| otherwise = []
	where
		list = dropWhile (\(x,y) -> x /= v) (pairs t)
		not_b = \(x,y) -> x /= b

Lösung von alexf91[Bearbeiten | Quelltext bearbeiten]

avb :: TTree a -> Integer -> Integer -> [(Integer, a)]
avb t v b = avb_drop_after (avb_drop_to (flatten t) v) b

flatten :: TTree a -> [(Integer, a)]
flatten (Leaf x y) = [(x,y)]
flatten (Node x y t1 t2 t3) = [(x,y)] ++ concatMap flatten [t3, t2, t1]

avb_drop_to :: [(Integer, a)] -> Integer -> [(Integer, a)]
avb_drop_to [] _ = []
avb_drop_to (x:xs) b  
    | (fst x) == b = (x:xs)
    | otherwise = avb_drop_to xs b
     
avb_drop_after :: [(Integer, a)] -> Integer -> [(Integer, a)]
avb_drop_after [] _ = []
avb_drop_after (x:xs) b
    | (fst x) /= b = x:(avb_drop_after xs b)
    | otherwise = [x]