Lösungen

Werbung
1 - Niemand mag: [ ] Java; [ ] Prolog; [ ] Haskell; [ ] Klausuren schreiben
Java
1)
2)
3)
4)
5)
e
a, c
keine Antwort ist korrekt
a, d
a, c
Prolog
6)
7)
8)
9)
10)
d
a, b, d, e
a
d
a, b, c
Haskell
11)
12)
13)
14)
15)
a
keine Antwort ist korrekt
b, d, e
a, b, e
b, c, d
2 - Hobby: Constraint- und Metaprogrammierung
:- use_module(library(clpfd)).
xkcd(Xs) :Xs = [Fruits,Fries,Salad,Wings,Sticks,Plate],
Xs ins 0..10,
Total = 1505,
Fruits * 215 + Fries * 275 +
Salad * 335 + Wings * 355 +
Sticks * 420 + Plate * 580
#= Total,
labeling([],Xs).
/*
?- xkcd([Fruits,Fries,Salad,Wings,Sticks,Plate]).
Fries = Salad, Salad = Sticks, Sticks = 0,
Fruits = Plate, Plate = 1,
Wings = 2;
Fries = Plate, Plate = Salad, Salad = Sticks, Sticks = Wings, Wings = 0,
Fruits = 7.
*/
proveList(true,[]) :- !.
proveList((G1,G2),Ls) :-
1
!,
proveList(G1,Ls1),
proveList(G2,Ls2),
append(Ls1,Ls2,Ls).
proveList(L,[L|Ls]) :- clause(L,G), proveList(G,Ls).
3 - Refactoring
ggT :: Integer -> Integer -> Integer
ggT a b = if b==0
then a
else ggT b (mod a b)
ggT' a 0 = a
ggT' a b = ggT b (mod a b)
isPrefixOf :: Eq a => [a] -> [a] -> Bool
isPrefixOf x (y:ys) = if length x == 0
then True
else isPrefixOf x (y:ys)
isPrefixOf x (y:ys) = if head x == y
then isPrefixOf (tail x) ys
else False
isPrefixOf' []
_
= True
isPrefixOf' (x:xs) (y:ys) = x == y && isPrefixOf xs ys
----catJusts :: [Maybe a] -> [a]
catJusts []
= []
catJusts (m:ms) = case m of
Just x -> x : catJusts ms
Nothing -> catJusts ms
catJusts' ms = [ x | Just x <- ms ]
catJusts'' ms = foldr (\m acc -> maybe id (\v -> (v:)) m acc) [] ms
allPairs :: [a] -> [b] -> [(a,b)]
allPairs xs ys = concatMap (\x -> map (\y -> (x,y)) ys) xs
allPairs' xs ys = [ (x,y) | x <- xs, y <- ys ]
----fa :: Ord a => [a] -> a -> [a]
fa [] y = [y]
fa (x:xs) y = case y <= x of
True -> y : x : xs
False -> x : fa xs y
fb :: (a -> Bool) -> b -> b -> a -> b
fb a b c d = if a d then b else c
fc :: a -> b -> a
fc x y = x
2
fd :: [a] -> (b -> a -> b) -> b -> b
fd [] g z = z
fd (x:xs) g z = (fd xs g (g z x))
fe :: (a -> b) -> b -> Maybe a -> b
fe x y Nothing = y
fe x y (Just v) = x v
4 - Fahrkarten, bitte!
data Ticket = TrainTicket City City TrainClass
| BusTicket City City
deriving Eq
from :: Ticket -> City
from (TrainTicket start _ _) = start
from (BusTicket
start _ ) = start
to :: Ticket -> City
to (TrainTicket _ dest _) = dest
to (BusTicket
_ dest ) = dest
data TrainClass = First | Second
deriving (Eq,Show)
type Journey = [Ticket]
data City = Berlin | Bonn | Frankfurt | Freiburg
deriving (Eq,Show)
example1 :: Ticket
example1 = TrainTicket Hamburg Kiel First
example2 :: Ticket
example2 = BusTicket Freiburg Frankfurt
valid :: Journey -> Bool
valid [ ] = True
valid [t1] = True
valid (t1:t2:ts) = to t1 == from t2 && valid (t2:ts)
-- bonus point with foldr
-- valid (t:ts) =
-snd (foldr (\t2 (t1,acc) -> (t2, acc && to t1 == from t2))
-(t,True)
-ts)
instance Show Ticket where
show (TrainTicket start dest cls) =
"Train (" ++ show cls
++ "): "
++ show start
++ " ~> "
++ show dest
show (BusTicket start dest) =
"Bus: " ++ show start
3
++ " ~> "
++ show dest
5 - Nichtdeterministisches Sortieren
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
?- swap([4,3,2],Xs). (*)
|- { A1 -> 4, B1 -> 3, Xs -> [3,4,2] }
?- 3 < 4.
Ausgabe: Xs = [3,4,2]
Backtracking, weiter mit Regel 2 bei (*)
|- { A1 -> 4, L1 -> [3,2], Xs -> [4 | N1] }
?- swap ([3,2], N1) (**)
|- { A2 -> 3, B2 -> 2, L2 -> [], N1 -> [2,3 | []] }
?- 2 < 3.
Ausgabe: Xs = [4,2,3]
Backtracking, weiter mit Regel 2 bei (**)
|- { A2 -> 3, L2 -> [2], N1 -> [3 | N2] }
?- swap([2], N2). # 2te Regel, da 1te nicht anwendbar
|- { A3 -> 2, L3 -> [], N2 -> [2 | N3] }
?- swap([],N2).
Fehlschlag, keine Regel passt -- keine weitere Regel anwendbar
bubble(L, R) :- swap(L, N), !, bubble(N, R).
bubble(L, L).
Nachdem einmal swap erfolgreich durchgeführt wurde, kommt der Cut-Operator zum Tragen, so dass keine
zweites swap durchgeführt wird. Die Restliste wird dann entsprechend weiter sortiert; für alle weiteren swapRelationen gilt wieder, dass nur der erste Pfad genommen wird.
6 - Die Philosophie ist eine Art Rache an der Wirklichkeit – Friedrich
Nietzsche
Implementierungsfehler
1. Fehler in Klasse Stick, Zeile 6 Beim Zurücklegen des Sticks fehlt die Anweisung isUsed = false, da der
Stick sonst nie von einem anderen Philosophen genutzt werden kann.
Richtig wäre also:
public synchronized void put() {
isUsed = false;
notify();
}
2. Fehler in Klasse Stick, Zeile 11 Innerhalb des try-Blocks muss die Aufnahme eines Sticks mit Hilfe einer
wait()-Anweisung blockiert werden, da der Stick bereits verwendet wird.
Richtig wäre also:
public synchronized void take() {
while (isUsed) {
try { wait(); } catch (InterruptedException e) {}
}
isUsed = true;
}
4
3. Fehler in Klasse Philosopher, Zeile 29 - 33 Das wait auf dem linken Stick macht zum einen keinen Sinn,
da das anschließende left.take() unter Umständen ebenfalls warten würde. Zum anderen ist bereits klar, dass
der Stick nicht verwendet werden kann. Es muss einen alternativen Fall geben, der durch else eingeleitet wird.
Richtig wäre also:
right.take();
if (left.isUsed()) {
right.put();
} else {
left.take();
System.out.println("Eating.");
}
left.put();
right.put();
5
Herunterladen