Funktionale Programmierung (ALP 1), WS 2011/12 — 1. ¨Ubungsblatt

Werbung
Funktionale Programmierung (ALP 1), WS 2011/12 — 1. Übungsblatt
Test ab 24. Oktober 2011
Bei Funktionen ist generell eine geeignete Typdeklaration anzugeben.
1. Dreiecke (10 Punkte)
Schreiben Sie eine Funktion zum Testen, ob x, y, z die Seitenlängen eines Dreiecks (mit
positiver Fläche) sind. (Entartete Dreiecke, wo zum Beispiel zwei Ecken zusammenfallen, sind ausgeschlossen.)
2. Negative Argumente (10 Punkte)
Die zweistelligen Funktionen mod x y und div x y bestimmen den Rest von x bei
Division durch y, beziehungsweise den ganzzahligen Quotienden der Division unter
Vernachlässigung des Restes.
(a) Finden Sie durch Probieren heraus, was passiert, wenn für x und y auch negative
Werte oder 0 eingesetzt werden.
(b) Welche Beziehung gilt immer (mit wenigen Ausnahmen; mit welchen?) zwischen
x - mod x y und div x y?
(c) Fassen Sie Ihre Ergebnisse zu Aufgabe (a) in möglichst einfache Regeln.
3. Überlauf (10 Punkte)
Im Gegensatz zum Typ Integer haben Größen vom Typ Int einen Wert von höchstens
231 − 1 = 2.147,483.647 beziehungsweise 263 − 1 = 9,223.372,036.854,775.807.
(a) Was passiert, wenn bei einer Rechnung mit Größen vom Type Int diese Grenze
überschritten wird?
(b) Welches ist der kleinste Wert, der im Typ Int dargestellt werden kann?
4. Zinseszinsberechnung (10 Punkte)
Die folgende Funktion bestimmte die Zinsen einer Anlage von zinsfuß %.
zinsen kapital zinsfuß = kapital * zinsfuß * 0.01
(a) Definieren Sie unter Zuhilfenahme von zinsen eine Funktion endwert (mit geeigneten Parametern), die den Wert der Anlage (Kapital+Zinsen) am Ende einer
Zinsperiode bestimmt.
(b) Definieren Sie eine Funktion endwert2, die den Wert nach zwei Zinsperioden berechnet, wenn die Zinsen am Ende der ersten Periode wieder angelegt werden.
(c) Funktioniert es auch mit der folgenden Definition?
zinsen kapital zinsfuß = kapital * zinsfuß / 100
5. Gleitkommarechnungen (10 Punkte)
Vom mathematischen Standpunkt aus müsste die folgende Funktion immer 0 liefern:
zero:: Float -> Float
zero x = (1/x)*x - 1
Wegen Rundungsfehlern ist dies nicht immer der Fall. Finden Sie Werte x, bei denen das
Ergebnis von 0 verschieden ist. (Ändert sich das Ergebnis beim Übergang zu Double?)
6. (10 Punkte) Schreiben Sie eine Funktion von drei Integer-Parametern, die ausgibt,
wie viele der Eingabeparameter größer als der Durchschnittswert sind.
1
Funktionale Programmierung (ALP 1), WS 2011/12 — 2. Übungsblatt
Korrigierte Fassung von Aufgabe 11b–c (29.10.) — Test ab 31. Oktober 2011
Bei allen Funktionen ist generell eine Typdeklaration anzugeben.
7. Uhrzeiten (10 Punkte)
Uhrzeiten wie 10:30 Uhr oder 23:59 Uhr sollen als geordnete Paare (10, 30) beziehungsweise (23,59) dargestellt werden.
Schreiben Sie eine Funktion, die die Dauer zwischen zwei Uhrzeiten in Stunden und
Minuten berechnet (negativ, falls die zweite Uhrzeit vor der ersten liegt).
Sie sollten das Problem in Teilprobleme zerlegen und geeignete Hilfsfunktionen definieren.
8. Uhrzeiten (10 Punkte)
Im angelsächsischen Raum werden Uhrzeiten in einem 12-Stunden-Bereich angegeben
und mit dem Zusatz a.m. (Vormittag), p.m. (Nachmittag), noon oder midnight versehen: 0:00 = 12:00 midnight, 0:13 = 12:13 a.m., 10:30 = 10:30 a.m., 12:00 = 12:00 noon,
12:55 = 12:55 p.m., 13:20 = 1:20 p.m., 23:59 = 11:59 p.m.. Die Stundenzahl ist also
immer zwischen 1 und 12.
Schreiben Sie eine Funktion, die dieses Format (als Zeichenkette) berechnet, wenn die
Eingabe wie in Aufgabe 7 gegeben ist. Wenn die Eingabe keine gültige Uhrzeit darstellt,
soll der Text ungültig ausgegeben werden.
9. Multiplikationstabelle (10 Punkte)
| 1 2 10
---+---------1 | 1 2 10
2 | 2 4 20
10 | 10 20 100
Erstellen Sie eine Tabelle für das kleine Einmaleins (die Produkte
aller Zahlenpaare zwischen 1 und 10) als Zeichenkette. Die einzelnen Zeilen sind mit ’\n’ abgeschlossen. Das reduzierte Beispiel
rechts zeigt, wie so eine Tabelle aussehen könnte, wenn man sie
mit putStr ausgibt. Die Spalten ihrer Tabelle müssen vertikal ausgerichtet sein.
(Hinweis: die Funktion show wandelt eine Zahl in eine Zeichenkette um.)
10. Bedingte Ausdrücke (10 Punkte)
Schreiben Sie die folgende Funktion als einen einzigen (nicht geschachtelten) if-thenelse-Ausdruck:
test x y z
| x <= y
= True
| y <= z
= False
| otherwise = x < z
Zusatzfrage (0 Punkte): Kommt man auch ganz ohne if-then-else-Ausdruck aus?
11. Perfekte Zahlen (10 Punkte)
(a) Schreiben Sie eine Funktion, die zu einer Zahl n die Liste ihrer (positiven) Teiler
berechnet.
(b) Bestimmen Sie jede Zahl n zwischen 1 und 1000, bei der die Summe ihrer von n
verschiedenen Teiler größer ist als die Zahl n selbst.
(Hinweis: Die Funktion sum berechnet die Summe der Elemente einer Liste)
(c) Bestimmen Sie alle perfekten Zahlen zwischen 1 und 1000: die Zahlen n, die gleich
der Summe ihrer von n verschiedenen Teiler sind.
2
Funktionale Programmierung (ALP 1), WS 2011/12 3. Übungsblatt
Bei allen Funktionen ist
generell
Test ab 7. November 2011
eine Typdeklaration anzugeben.
12. Sichtbarkeitsbereiche (10+10 Punkte)
Geben Sie für jeden eingeführten Namen den Sichtbarkeitsbereich an.
(a)
(b)
x = 25:: Integer
biggerThanAVG3:: Integer->Integer->Integer->Integer
biggerThanAVG3 x y z =
sum (map (\x -> if fromIntegral x > avg3 x y z then 1 else 0)
[x ,y, z])
where avg3:: Integer->Integer->Integer->Double
avg3 a b c = fromIntegral (a+b+c) / 3
test1:: Integer
test1 = biggerThanAVG3 3 4 5
fläche:: Float -> Float
fläche x = 2*x^2*pi -- Fläche eines Kreises mit Radius x
f x y =
let n = 3 in take n (g y) ++ take n (g x)
where g x = take n xys
where
xys = [x] ++ yxs
yxs = [y] ++ xys
n = 10
13. (10 Punkte) Schreiben Sie eine Funktion, die berechnet, wie viele Zahlen in einer Liste
von
Integer-Werten
kleiner
als der Durchschnittswert sind.
14. Preisberechnung (10 Punkte)
Listen der beiden folgenden Datentypen
type Einkaufsliste = [(String, Float)]
type Preisliste
= [(String, Float)]
geben an,
was
zum Beispiel
gekauft werden soll und
vieviel
(in einer passenden Einheit, z. B. kg),
[("Mehl",0.5), ("Butter",0.25)],
und andererseits den Preis in Euro
pro Einheit für jeden Artikel.
(a) Denieren Sie eine Funktion
preis:: Preisliste -> Einkaufsliste -> (Float,[String])
zur Berechnung des Gesamtpreises aller Artikel einer Einkaufsliste. Die zweite Komponente des Ergebnisses soll die Liste der Artikelnamen enthalten, die in der Preisliste nicht gefunden wurden.
(b) Erweitern Sie die Funktion so, dass der Preis für jeden gekauften Artikel der Einkaufsliste auf Cent gerundet wird.
3
15. Funktionsiteration (10 Punkte)
Die folgende Funktion
gument
x
iter
wendet eine Funktion
f n-mal
hintereinander auf ein Ar-
iter 3 f x das Ergebnis f (f (f (x))), das man
f 3 (x) oder noch genauer f (3) (x) schreibt, damit man
an. Zum Beispiel liefert
der Mathematik manchmal als
nicht mit der Potenz
(f (x))3
in
es
verwechselt.
iter n f x
| n==0 = x
| n>0 = f (iter (n-1) f x)
(a) Welchen Typ hat
iter?
iter n f ohne den Parameter x.
der Funktion iter und der Lösung
(b) Geben Sie eine alternative Denition als Funktion
(c) Lösen Sie Aufgabe 4b (Zinseszinsen) mit Hilfe
von Aufgabe 4a. (Achten Sie auf die Reihenfolge der Argumente.)
16. Iterierter Logarithmus (10 Punkte)
logBase a x = loga x
y , für die ay = x ist.
Die Funktion
ist die Zahl
berechnet den Logarithmus von
(a) Bestimmen Sie die kleinste Zahl
(b) Bestimmen Sie die kleinste Zahl
x,
x,
für die
für die
x
zur Basis
logBase 2 x >= 5 ist.
iter 3 (logBase 2) x >= 2
a;
das
ist.
17. Potenzieren, Summe und Produkt (10 Punkte)
Das Potenzieren mit einer natürlich Zahl als Exponent kann man als iteriertes Multiplizieren denieren:
xn := x · x · x · · · x
mit
n
Faktoren:
potenz x n = iter n (x*) 1
x
xx
·x
··
turm x k = x ↑ k :=
ist eine geschachtelte Potenz, bei
x insgesamt k -mal vorkommt. (Potenzieren
ist rechtsassoziativ!) Denieren Sie diese Funktion unter Verwendung von potenz
und iter.
(a) Die Turmfunktion
der in dem Turm auf der rechten Seite
(b) Die
Multiplikation
kann als iterierte Addition aufgefasst werden. Schreiben Sie eine
entsprechende Funktion
mal a b, die analog zur Funktion potenz das Produkt als
iterierte Summe deniert.
(c) Welche Funktion muss man iterieren, damit man die
a+b
Summenfunktion plus a b =
erhält? Schreiben Sie eine entsprechende Funktionsdenition für
plus.
18. Funktionsiteration (10 Punkte)
(a) Jemand hat die Funktion
aus der Funktion
alle
n≥0
g
g = iter 23 deniert. Wie können Sie das Argument 23
entdecke, die für
herausnden? Schreiben Sie eine Funktion
die folgende Beziehung erfüllt:
entdecke (iter n) == n,
(b) Addition: Schreiben Sie eine Funktion
sumiter
mit der Eigenschaft
sumiter (iter a) (iter b) == iter (a+b),
Verwenden Sie nicht einfach
entdecke
und
+,
für alle
a, b ≥ 0.
sondern suchen Sie eine direktere
Denition.
(c) Multiplikation: Schreiben Sie eine analoge Funktion
a
und
b.
4
proditer für das Produkt von
Funktionale Programmierung (ALP 1), WS 2011/12 4. Übungsblatt
Test ab 14. November 2011
19. Funktionen höherer Ordnung (5 Punkte)
Drücken Sie die Funktion length mit Hilfe von sum und map und geeigneten selbstdenierten Funktionen aus. (Eine Zeile sollte für die Denition reichen.)
20. Listenfunktionen (10 Punkte)
Denieren Sie die Funktionen
takeWhile :: (a -> Bool) -> [a] -> [a]
splitAt :: Int -> [a] -> ([a],[a])
Der Ausdruck takeWhile p x erzeugt das Anfangsstück einer Liste x, solange die Elemente das Prädikat p erfüllen. splitAt n x spaltet die Liste x nach den ersten n Elementen in zwei Teile auf. (Diese Funktionen sind in Haskell schon deniert. Zum Testen
müssen Sie daher andere Funktionennamen wählen.)
21. (5 Punkte) Welchen Typ hat der Ausdruck map ( zinsen 2.25) im Zusammenhang
von Aufgabe 4? Was bewirkt diese Funktion?
22. Nichtassoziative Faltung von Listen (10 Punkte)
Beschreiben Sie das Ergebnis der Funktion
differenzen:: Integer -> Integer -> Integer -> Integer
differenzen a b c = foldr (-) a [b..c]
durch eine explizite Formel in den Gröÿen a, b, c (oder mehrere Formeln). Beweisen Sie
Ihre Formel (zum Beispiel durch vollständige Induktion nach c − b, oder auch direkt).
23. Strukturelle Induktion (40 Punkte)
(a) (5 Punkte) Beweisen Sie: map f (a ++ b) = map f a ++ map f b
(b) (5+10 Punkte) Wie kann man foldr g z (a ++ b) durch foldr auf den Listen
a und b ausdrücken? Beweisen Sie Ihre Formel.
(c) (5 Punkte) Drücken Sie elem x l durch map und foldr aus, und beweisen Sie
damit
elem x (a ++ b) = elem x a || elem x b,
indem Sie Aufgabe (a) und (b) verwenden.
(d) (10 Punkte) Beweisen Sie (take k) . (take l) = take (min k l)
Ergänzen Sie bei jeder Behauptung den Gültigkeitsbereich der in der Gleichung vorkommenden Variablen.
24. Lauflängenkodierung (run-length encoding)
(a) (10 Punkte) Bei der Lauflängenkodierung wird eine Kette "aaaabbaaa" mit vielen
wiederholten Zeichen komprimiert, indem man die Länge jedes Laufes von gleichen
Zeichen nimmt: [(4,'a'), (2,'b'), (3,'a')]. Schreiben Sie eine Funktion, die
diese Kodierung berechnet, und auch die Umkehrfunktion für die Dekodierung.
(b) (10 Punkte) Unter der Annahme, dass die Eingabekette keine Ziern enthält, kann
man die komprimierte Fassung kompakter als Kette "4a2b3a" darstellen. Erweitern
Sie die vorige Aufgabe auf diese Darstellung
5
Funktionale Programmierung (ALP 1), WS 2011/12 5. Übungsblatt
Test ab 21. November 2011
Bei allen Funktionen ist wie immer eine Typdeklaration anzugeben.
25. Sichtbarkeitsbereiche (5 Punkte)
Korrigieren Sie die Benennung der Variablen in der Funktion
biggerThanAVG3 von Auf-
gabe 12a (3. Übungsblatt) so, dass die Funktion berechnet, wie viele der drei Eingabeparameter gröÿer als der Durchschnittswert sind (Aufgabe 6 vom 1. Übungsblatt).
26. Anonyme Funktionen (λ-Ausdrücke) (15 Punkte)
Wandeln Sie folgende Funktionsdenitionen in anonyme Funktionen um, ohne lokale
Denitionen mit
where oder let zu verwenden. Ihre Lösung soll mit f = \. . .
(a) Die Funktion
f = biggerThanAVG3
(b) Die Funktion
f
beginnen.
von Aufgabe 12a (3. Übungsblatt)
von Aufgabe 12b (3. Übungsblatt)
(c) Ihre Lösung von Aufgabe 25.
(d)
f x y z = x^3 - g (x + g (y - g z) + g (z^2))
where g x = 2*x^2 + 10*x + 1
Ein Trick: Sie können sich das explizite Hineinkopieren der Funktion
g
an mehrere
Stellen sparen, indem Sie zunächst g als zusätzlichen (ersten) Parameter Ihrer
Funktion denieren.
27. Zinseszinsen (10 Punkte)
Die Funktionen
Funktion
foldr
scanr
und
scanl liefern
foldl:
eine Liste mit allen Zwischenergebnissen der
beziehungsweise
scanr:: (a
scanl:: (b
scanr op z
scanr op z
-> b -> b) -> b -> [a] -> [b]
-> a -> b) -> b -> [a] -> [b]
[]
= [z]
(x:xs) = (x op q) : q:qs
where (q:qs) = scanr op z xs
scanl op a []
= [a]
scanl op a (x:xs) = a : scanl op (a op x) xs
k0 über mehrere Jahre entwi[z1 , z2 , . . . , zn ] der jährlichen Verzinsungen gegeben ist. Verwenden
Funktion scanr oder scanl, sowie geeignete Funktionen von Aufgabe 4.
Eine Funktion soll berechnen, wie sich ein Anfangskapital
ckelt, wenn die Folge
Sie dazu die
28. Abarbeiten von Listen (15 Punkte)
(a) Welche Beziehung besteht zwischen dem Ergebnis von
und
scanr (+) 333 [1..10]?
scanl (-) 333 [1..10]
(b) Welche Beziehung besteht allgemein zwischen dem Ergebnis von
und
scanr (+) a x?
scanl (-) a x
Welche Beziehung besteht zwischen aufeinanderfolgenden
Elementen in jeder dieser Listen? Beweisen Sie Ihre Aussagen.
f und g gelten, damit eine analoge Beziehung zwischen scanl f a x und scanr g a x besteht? (Untersuchen Sie genau,
welche Eigenschaften von + und - Sie in Ihrem Beweis zu Aufgabe (b) benötigt
(c) Welches Gesetz muss für die Operationen
haben.)
6
29. Sortieren durch Auswählen (10 Punkte)
Bei diesem Sortierverfahren wird das kleinste Element einer Liste ausgewählt und an
den Anfang gestellt; die restlichen Elemente werden rekursiv sortiert. Programmieren
Sie dieses Sortierverfahren in Haskell.
30. Verbinden von Listen, Faltung (5 Punkte)
(a) Denieren Sie die Funktion
++
durch eine geeignete Faltung.
(b) Bei der Lösung von Aufgabe 9 war eine Funktion hilfreich, die eine Liste von
Zeichenketten zu einer einzigen Zeichenkette zusammenfügt (In der Musterlösung
heiÿt diese Funktion
aneinander:: [String] -> String, in Haskell gibt es daconcat:: [[a]] -> [a].) Denieren Sie diese Funktion
für die Standardfunktion
durch Faltung.
31. Verbinden und Trennen von Listen (20 Punkte)
(a) Denieren Sie eine Funktion, die eine Liste von Listen mit einem Verbindungsglied
zusammenfügt. Das Verbindungsglied soll zwischen den Elementen erscheinen, aber
nicht am Ende nach dem letzten Element. Hier sind Beispiele:
verbinden
verbinden
verbinden
verbinden
::
",
",
",
[a] -> [[a]] -> [a]
" [] = ""
" ["eins"] = "eins"
" ["erstens","2.","drittens"] = "erstens, 2., drittens"
trennen :: [a] -> [a] -> [[a]] soll die Liste an den Stellen trennen, wo das Verbindungsglied vorkommt, sodass für alle x die Gleichung
verbinden x . trennen x = id gilt. Überlegen Sie, ob die Lösung immer ein-
(b) Die Umkehrfunktion
deutig ist. Beschreiben Sie klar und eindeutig (d.h., spezizieren Sie), was Ihre
Umkehrfunktion in jedem Fall machen soll.
(c) Denieren Sie die Umkehrfunktion nach Ihrer Spezikation.
(d) Warum ist es unmöglich, durch eine Funktion
trennen x . verbinden x = id
trennen
für alle
x die Gleichung
x, für die man
zu erfüllen? Gibt es Werte von
die Beziehung erfüllen kann?
32. Funktionen höherer Ordnung (10 Punkte)
Welche der folgenden Funktionen ersetzt jedes Vorkommen eines bestimmten Wortes in
einer Liste von Wörtern durch eine Folge von Sternen? Bestimmen Sie für jede Funktion,
ob Sie überhaupt nach den Haskell-Regeln gültig ist, und stellen Sie gegebenenfalls ihren
Typ fest.
wiederhole n x = [
ersetzeWort unwort
| unwort == w =
| otherwise
=
zensiere1 unwort =
zensiere2 unwort =
zensiere3 unwort =
zensiere4 unwort =
zensiere5
=
zensiere6 unwort =
zensiere7 unwort =
zensiere8
=
x | k <- [1 .. n]] -- = die Standardfunktion replicate
w
wiederhole (length unwort) '*'
w
map (ersetzeWort unwort)
map ersetzeWort unwort
map unwort . ersetzeWort
map . ersetzeWort unwort
map . ersetzeWort
(map . ersetzeWort) unwort
ersetzeWort unwort . map
map ersetzeWort
7
Funktionale Programmierung (ALP 1), WS 2011/12
Probeklausur vom 21. November 2011
1. Fläche eines Polygons (10 Punkte)
Die Fläche eines n-Ecks mit den Ecken (x1 , y1 ), . . . , (xn , yn ) ist durch die Formel
n
X
(x
−
x
)(y
+
y
)
i+1
i
i+1
i F =
2
i=1
gegeben, wobei xn+1 für x1 und yn+1 für y1 steht. Schreiben Sie eine Funktion für diese
Formel. (Die Funktion für den Absolutbetrag heiÿt abs.) Bei allen Funktionen ist wie
immer eine Typdeklaration anzugeben.
2. Sichtbarkeitsbereich (10 Punkte)
(a) (7 Punkte) Geben Sie für jeden im folgenden Programmstück eingeführten Namen
den Sichtbarkeitsbereich an.
f x y
| r > 0
| otherwise
where r = g
g z x
=
=
x
=
x+r
-x+y
(-y)
x*y*z - 1
(b) (3 Punkte) Bestimmen Sie [f (-1) (-1), f (-1) 2, f (-2) 1].
3. (a) (10 Punkte) Welche der folgenden Denitionen bewirkt, dass die Funktion g =
entf? ' ' alle Leerzeichen aus einer Zeichenkette entfernt?
entf1
entf2
entf3
entf4
entf4
entf4
entf5
z
z
z
z
z
z
z
= concat . map (\ x -> if x==z then "" else x)
l = [if x==z then "" else [x] | x <- l]
= foldr (\ x r -> if x==z then r else x:r) [ ]
[] = []
(z:zs) = entf4 z zs
(x:xs) = x: entf4 z xs
l = [x | x <- l, x/=z]
Bestimmen Sie für jede Funktion entfn, ob sie überhaupt nach den Haskell-Regeln
gültig ist, und stellen Sie gegebenenfalls ihren Typ fest. Begründen Sie Ihre Antworten.
(b) (5 Punkte) Was macht die Funktion
entf '.' . entf ',' . entf '.' . entf ';' . entf '.',
wobei entf die richtige Lösung zu Aufgabe (a) ist?
4. Strukturelle Induktion (15 Punkte)
Wie kann man foldl g a (u ++ v) durch foldl auf den Listen u und v ausdrücken?
Beweisen Sie Ihre Formel unter Verwendung der folgenden Denitionen.
(F0 )
(F1 )
(++0 )
(++1 )
foldl:: (b -> a -> b) -> b -> [a] -> b
foldl g a [] = a
foldl g a (x:xs) = foldl g (g a x) xs
(++):: [a] -> [a] -> [a]
[] ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)
8
Funktionale Programmierung (ALP 1), WS 2011/12 6. Übungsblatt
Test ab 28. November 2011 und ab 5. Dezember 2011
Bei allen Funktionen ist wie immer eine Typdeklaration anzugeben.
33. (8 Punkte) Die Funktion
filter p l wählt aus einer Liste l alle Elemente aus, die das
p erfüllen. Denieren Sie eine solche Funktion
Prädikat (die Boolesche Funktion)
filter:: (a->Bool) -> [a] -> [a]
(a) rekursiv,
(b) durch Listendurchlauf (Zermelo-Fränkel-Notation).
(c) Schreiben Sie mit Hilfe von
filter
eine Funktion, die alle Leerzeichen aus einer
Zeichenkette entfernt.
34. Auswertungsstrategien (10 Punkte)
Die Funktion
foldr::
foldl::
foldr f
foldr f
foldl f
foldl f
foldr
und
(a -> b ->
(b -> a ->
z []
=
z (x:xs) =
a []
=
a (x:xs) =
foldl
sind folgendermaÿen deniert:
b) -> b ->
b) -> b ->
z
f x (foldr
a
foldl f (f
[a] -> b
[a] -> b
f z xs)
a x) xs
Vollziehen Sie nach, wie die Ausdrücke
mit der Funktion
g x y = x+2*y
foldr g 0 [1,2,3]
und
foldl g 0 [1,2,3]
Schritt für Schritt ausgewertet werden, und zwar bei
(a) strenger Auswertung von innen nach auÿen, und (b) träger Auswertung (Bedarfsauswertung) wie in Haskell.
35. (10 Punkte) Lösen Sie die vorige Aufgabe mit der Funktion
foldl':
foldl':: (b -> a -> b) -> b -> [a] -> b
foldl' f a [] = a
foldl' f a x = f (foldl' f a (init x)) (last x)
last :: [a] -> a
last [x]
= x
last (_:xs)
= last xs
init :: [a] -> [a]
init [_]
= []
init (x:xs)
= x : init xs
36. Darstellung von Ausdrücken (10 Punkte)
(a) Schreiben Sie eine Funktion, die für eine Darstellung vom Typ
Ausdruck
(Vorle-
sung vom 16. 11. 2011), die keine Variablen enthält, den durch den arithmetischen
Ausdruck gegebenen Wert berechnet.
(b) Schreiben Sie eine Funktion, die als zusätzliche Eingabe eine Werteliste vom Typ
[(String,Integer)]
akzeptiert, wobei ein Element
ten soll, dass die Variable mit Namen
"x"
("x",3)
zum Beispiel bedeu-
den Wert 3 hat. Falls der Ausdruck
eine Variable enthält, die nicht in der Liste vorkommt, soll die Funktion mit einer
informativen Fehlermeldung abbrechen.
9
37. Strenge Funktionen (7 Punkte)
Eine Funktion
f
in Haskell ist
ausgewertet wird, wenn
f
streng
x,
in einem Parameter
wenn
x
auf jeden Fall
ausgewertet wird. In welchen Parametern sind die folgenden
Funktionen streng?
doppel n a = a+a
f1 n a = if n=0 then a+1 else a-n
f2 n a = if n=0 then a+1 else n
38. Träge Multiplikation (5 Punkte)
Schreiben Sie eine Funktion
mult
zur Multiplikation zweier Zahlen, die das zweite Ar-
gument nicht auswertet, wenn das erste Argument 0 ist.
39. Spiegeln von zweidimensionalen Mustern (10 Punkte)
Man kann rudimentäre Graken als Zeichenketten erzeugen, die aus
durch
\
+-->
\
|
+---+
'\n' abgeschlossenen Zeilen bestehen und mit putStr ausgegeben
putStr "\\
+-->\n \\
|\n +---+\n" das obige
werden. Zum Beispiel liefert
Bild. (Verkehrte Schrägstriche müssen in einer Zeichenkette doppelt eingegeben werden,
\n unterscheiden kann.)
flipV, die eine solches Bild an
damit man sie von Sonderkodierungen wie
Schreiben Sie Funktionen
flipH
und
einer horizontalen
beziehungsweise an einer vertikalen Achse spiegeln. Das Ergebnis soll bei diesem Beispiel
so aussehen:
flipH:
>--+
\
|
\
+---+
flipV:
+---+
\
|
\
+-->
40. Die Fibonacci-Zahlen (10 Punkte)
(a) Die Folge
F1 , F2 , . . .
der Fibonacci-Zahlen ist durch die Anfangswerte
F1 = F2 = 1
und die Rekursion
Fn = Fn−1 + Fn−2
für
(∗)
n ≥ 3 gegeben. Schreiben Sie ein Programm zur Berechnung der n-ten Fibonacci-
Zahl. Berechnen Sie die ersten 20 Fibonacci-Zahlen.
(b) Welche Werte ergeben sich für
Fn mit n ≤ 0, wenn man die Gültigkeit der Gleichung
(∗) auf alle ganzen Zahlen n ausdehnt? Erweitern Sie Ihr Programm, sodass es auch
eine negative Eingabe akzeptiert.
27
41. Kodierung von Bäumen (10 Punkte)
Nach einer alternativen Denition von Bäumen ist ein
Blatt (ein einzelner Knoten ohne Kinder) oder ein innerer Knoten mit genau
5
nichtleerer Baum entweder ein
zwei Kindern.
data Baum' a = Blatt a
| Knoten a (Baum' a) (Baum' a)
−2
44
7
8
5
7
9
Man kann einen solchen Baum kodieren, indem man augehend von der Wurzel einmal
auÿen um den Baum herumgeht und dabei jede Abwärtsbewegung (Down), jede Aufwärtsbewegung (Up) und jeden Knoten notiert, wenn er zum erstenmal besucht wird.
Das nebenstehende Beispiel liefert etwa den Kode
27D5D-2UD7UUD44D8UD5D7UD9UUU.
Schreiben Sie ein Programm, das diesen Kode für einen Baum vom Typ
berechnet.
10
Baum' Int
Funktionale Programmierung (ALP 1), WS 2011/12 7. Übungsblatt
Test ab 12. Dezember 2011
42. Zeichnen von Weihnachtsbäumen (10 Punkte)
Schreiben Sie ein Programm, das eine Baum mit ganzzahligen
Knotenwerten mit Buchstabengrak ausgibt, zum Beispiel wie
im nebenstehenden Bild. (Sie dürfen eine Annahme über den
Wertebereich machen, wenn Sie sie dokumentieren.)
43. Der Teilabschnitt mit der gröÿten Summe (10 Punkte)
Schreiben Sie eine Funktion, die für einer Liste
gröÿte Summe
ai + ai+1 + · · · + aj
zusammenhängenden
[a1 , . . . , an ]
die
einer in ihr enthaltenen
Teilfolge bestimmt. (Die Summe der
leeren Folge ist 0.)
44. Typklassen und Typinferenz (5 Punkte)
12
|
+---+---+
|
|
777
16
|
|
+-+-+
+-+-+
| |
| |
12 22 426 -12
|
|
|
+-+ +++ +-+
|
| |
|
16
13 6
1
concat . map show,
map length . sum. Verwenden Sie den
Bestimmen Sie den Typ der Funktionen
sum . map length,
und
Computer höchstens
zum Überprüfen Ihrer Antworten.
45. Typinferenz (15 Punkte)
Bestimmen Sie die Typen der Funktionen
= f x y,
und
id x = x.
curry f x y = f (x,y), uncurry f (x,y)
Stellen Sie fest, welche der folgenden acht Funktionen gültig
sind, und bestimmen Sie gegebenfalls ihren Typ:
curry id
uncurry id
curry (curry id)
uncurry (uncurry id)
uncurry curry
curry uncurry
uncurry uncurry
curry curry
46. Wahrheitstafel für Boolesche Funktion (15 Punkte)
Schreiben Sie eine Funktion zum Erstellen einer Wahrheitstafel für Boo-
Bool -> Bool -> · · · -> Bool. Beim Anwenden auf
k
eine k -stellige Funktion soll für jede der 2 Belegungen der Parameter
mit True oder False der Funktionswert tabelliert werden. Zum Beispiel
könnte für die Funktion (\x y z -> x && y || z) das nebenstehende
Ergebnis herauskommen. Die Stellenzahl k soll nicht als Parameter der
lesche Funktionen
Funktion verlangt werden.
T
T
T
T
F
F
F
F
T
T
F
F
T
T
F
F
T
F
T
F
T
F
T
F
|
|
|
|
|
|
|
|
T
T
T
F
T
F
T
F
47. Uhrzeiten (15 Punkte)
(a) (5 Punkte) Schreiben Sie eine eigene
show-Funktion für den Datentyp Uhrzeit aus
Show.
der Vorlesung vom 16. 11. und deklarieren Sie ihn als Beispiel der Typklasse
Sie können dabei das angelsächsische Format wie in Aufgabe 8 nehmen oder das
bei uns gebräuchliche 24-Stunden-Format.
Uhrzeit als Beispiel der Typklasse Enum. Sie müssen
fromEnum und toEnum denieren. Drücken Sie dann mit Hilfe
der folgenden Funktion, die in der Typklasse Enum bereits vordeniert ist, die Liste
(b) (10 Punkte) Deklarieren Sie
dazu die Funktionen
der Uhrzeiten alle 15 Minuten von 10:28 bis 16:13 Uhr aus.
enumFromThenTo x y z = map toEnum
[ fromEnum x, fromEnum y .. fromEnum z ]
11
Funktionale Programmierung (ALP 1), WS 2011/12 8. Übungsblatt
Test ab 24. Dezember 2011
48. Ein- und Ausgabe (10 Punkte)
Schreiben Sie ein Programm für folgende Aufgabe: Der Benutzer wird nach dem Namen
eine Eingabedatei und einer Ausgabedatei gefragt; dann wird die Eingabedatei auf die
Ausgabedatei kopiert, wobei Folgen von Leerzeichen am Zeilenende weggelassen werden.
49. Bäume dekodieren (10 Punkte)
Schreiben Sie ein Programm für die Umkehrfunktion zu Aufgabe 41.
50. Intervallhalbierung, binäre Suche (10 Punkte)
nullStelle:: (Floating a, Ord a) => (a -> a) -> a
-> a -> a -> a zum Finden einer Näherungslösung x der Gleichung f (x) = 0 für eine
stetige reelle Funktion f : [a, b] → R, die auf einem Intervall [a, b] deniert ist. Die
Funktion nullStelle f a b epsilon setzt voraus, dass f (a) und f (b) verschiedenes
Vorzeichen haben. Wegen der Stetigkeit von f folgt daraus, dass f im Intervall [a, b]
Schreiben Sie ein Programm
mindestens eine Nullstelle hat. Das Verfahren der Intervallhalbierung bestimmt zunächst
das Vorzeichen von
f ((a + b)/2)
und grenzt dadurch das Intervall auf die linke oder
die rechte Hälfte ein. Dieser Vorgang wird iteriert, bis die Länge des Lösungsintervalls
unter
ε
reduziert ist.
Finden Sie mit Ihrem Programm die Lösung von
xx = 2,
und von
ex = sin x, x > −4,
x
jeweils auf 6 Nachkommastellen genau. Die Exponentialfunktion e wird in Haskell als
exp x
geschrieben.
51. Die Fibonacci-Folge (13 Punkte)
Man kann die Fibonacci-Folge auch bei
fibo::
fibo 0
fibo 1
fibo n
F0 = 0
beginnen lassen:
Integer -> Integer
= 0
= 1
| n>1 = fibo (n-1) + fibo (n-2)
Wie oft wird beim Aufruf von
fibo n die letzte Zeile der Denition ausgeführt? Wie oft
wird die erste Zeile ausgeführt? Wie oft die zweite Zeile? Beweisen Sie Ihre Aussagen
durch Induktion nach
n.
52. Suchen und Einfügen in einem Suchbaum (10 Punkte)
data Ord a => Suchbaum a b = Leer | Knoten a b (Suchbaum a b) (Suchbaum a b)
(a) Schreiben Sie eine Funktion
finde:: Ord a => a -> Suchbaum a b -> Maybe b
zum Suchen eines Elements in einem Suchbaum (Vorlesung vom 28. 11.)
einf:: Ord a => a -> b -> Suchbaum a b ->
Suchbaum a b zum Einfügen eines Elements in einen Suchbaum. Das Ergebnis von
einf s t b ist ein neuer Suchbaum, in dem ein zusätzliches Element mit Schlüssel
s vom Typ a und Wert t vom Typ b enthalten ist. Sie dürfen annehmen, dass der
Schlüssel s vorher nicht im Baum vorkommt.
(b) Programmieren Sie eine Funktion
12
53. Bedingte Ausdrücke in primitiv-rekursiven Funktionen (10 Punkte)
Beweisen Sie: Wenn
f, g, h : Nk → N
dann ist auch die folgende Funktion
k -stellige
drei
a
primitiv-rekursive Funktionen sind,
eine primitiv-rekursive Funktion:
a(x1 , . . . , xk ) := if f (x1 , . . . , xk ) = 0 then g(x1 , . . . , xk ) else h(x1 , . . . , xk )
f1 (x1 , . . . , xk ) <
f1 (x1 , . . . , xk ) = f2 (x1 , . . . , xk ), falls
Beweisen Sie dieselbe Schlussfolgerung auch für Bedingungen der Form
f2 (x1 , . . . , xk ), f1 (x1 , . . . , xk ) ≤ f2 (x1 , . . . , xk )
f1 und f2 primitiv-rekursiv sind.
und
54. Gröÿe enthaltene Zweierpotenz (10 Punkte)
Zeigen Sie, dass die Funktion
p2 : N → N
p2 (n) := max{ i ≥ 0 | 2i
mit
ist ein Teiler von
n}
für
n > 0, p2 (0) := 0
primitiv-rekursiv ist. Tipp: Konstruieren Sie zuerst eine Hilfsfunktion
h(m, n) := max{ i ≥ 0 | 2i ≤ m + 1
und
2i
ist ein Teiler von
n}
Sie dürfen unter anderem voraussetzen, dass die modulo-Funktion und die Potenzfunktion primitiv-rekursiv ist.
55. Einsetzung (12 Punkte)
Klassischerweise wird die Einsetzungsregel bei der Denition der primitiv-rekursiven
Funktionen strenger formuliert:
Wenn eine
k -stellige
primitiv-rekursive Funktion
primitiv-rekursive Funktionen
die
n-stellige
g1 , . . . , gk :
Nk
Funktion
f : Nk → N
und
k n-stellige
→ N gegeben sind, dann ist auch
h(x1 , . . . , xn ) := f g1 (x1 , . . . , xn ), g2 (x1 , . . . , xn ), . . . gk (x1 , . . . , xn )
primitiv-rekursiv.
Zusätzlich wird dabei deniert, dass alle Projektionsfunktionen
Pik (x1 , . . . , xk ) := xi
für
1≤i≤k
primitiv-rekursiv sind.
Zeigen Sie mit dieser Einsetzungsregel und mit Hilfe geeigneter Projektionsfunktionen,
dass die Funktionen
p(x, y, z) := h(x, h(y, z))
q(x, y, z) := g(h(x, y), y, g(z, z, y))
primitiv-rekursiv sind, falls die Funktionen
g
und
h
als primitiv-rekursiv vorausgesetzt
werden.
56. Suchbäume (10 Punkte) Schreiben Sie eine Funktion, die überprüft, ob ein Suchbaum
richtig sortiert ist. (Das heiÿt, ob die Suchbaumeigenschaft erfüllt ist: Für jeden Knoten
mit Schlüssel
s
müssen die Knoten im linken Teilbaum kleinere Schlüssel als
s
haben
und die Knoten im rechten Teilbaum gröÿere Schlüssel.)
57. Verschmelzen (5 Punkte)
Scheiben Sie eine Funktion
verschmelze:: (Ord a) => [a] -> [a] -> [a],
die zwei
aufsteigend sortierte Listen zu einer sortierten Gesamtliste vereinigt. Zum Beispiel:
verschmelze [1,3,4,7] [2,3,7,8,10] = [1,2,3,3,4,7,7,8,10]
13
Weihnachtsaufgaben
Julian Fleischer
5. März 2012
Dies sind freiwillige Zusatzaufgaben, mit denen Sie im Rahmen einer etwas größeren Programmieraufgaben den Umgang mit einem svn-Repository üben können.
Für die Bearbeitung der Aufgaben ist ein SVN-Repository unter http://dev.spline.de
anzulegen. Hierfür ist lediglich eine E-Mail-Adresse @...fu-berlin.de nötig, also z.B. die
FU-Adresse, die man über das Zedat-Portal benutzen kann (zumeist [email protected] oder [email protected]).
Als Abgabe schicken Sie dann bitte einfach Name, Matrikelnummer, und den Link zu
Ihrem Repository (also z.B. https://dev.spline.de/svn/huffman_alp1/ bis zum 1.1.2012
an Ihren Tutor/Ihre Tutorin. Falls Ihr Repository nicht öffentlich ist, vergessen Sie nicht, Ihren
Tutor oder Ihre Tutoring in das Projekt einzuladen. Die Abgabe kann in Projektgruppen zu 2
oder 3 Leuten erfolgen. Hilfe erhalten Sie im Forum.1
Aufgabe W1, 20 Punkte: RSA-Verschlüsselung
Das RSA-Verfahren2 ist ein wichtiges Verfahren der Nachrichtenverschlüsselung mit öffentlichen
Schlüsseln, zum Beispiel bei Datenübertragung im Internet. Entwickeln Sie eine Programm, das
eine einfache RSA-Verschlüsselung erlaubt. Im öffentlichen Repository https://dev.spline.
de/svn/rsa_alp1_aufgabe2/ gibt es ein Grundgerüst für Ihre Anwendung.
a) Vervollständigen Sie die Funktion rsaEncode (5 Punkte).
b) Vervollständigen Sie die Funktion rsaDecode (5 Punkte).
c) Enschlüsseln Sie dien verschlüsselte Nachricht[7321434, 3598567, 1716197, 4119550, 1716197,
1348875, 8435094, 8273804, 543720, 4505902, 4941202, 6726051, 8083299, 4896702, 3790340,
8176577, 3956251, 3855025, 9779898, 9626936, 7581573, 530038, 5596561, 1789054, 3956251,
3855025, 9779898, 1631514, 8435094, 9779898, 60307, 7379435].
d) Schreiben Sie eine interaktive Ein/Ausgabe-Routine main, die es erlaubt, Ihr Programm
zu bedienen.
Aufgabe W2, 20 Punkte: Symbolischer Gleischungslöser
Entwickeln Sie ein Programm, das Gleichungen lösen kann. Checken Sie hierfür das öffentliche
Repository https://dev.spline.de/svn/symbolic_equation_solver_alp1 aus, in dem es ein
Grundgerüst für Ihre Anwendung gibt.
a) Erweitern Sie die Datenstruktur Term, so dass auch Produkte und Brüche dargestellt
werden können.
b) Implementieren Sie die fehlenden Funktionen der Instanz von Term für die Klasse Num.
Beachten Sie, dass sie Terme zwischendurch vereinfachen oder ordnen müssen (a + b ist der
gleiche Term wie b + a, und a + a ist der gleiche Term wie 2 ∗ a) — wahrscheinlich werden sie
eine kanonische Darstellung definieren müssen.
c) Vervollständigen Sie die Ein/Ausgabe-Routine main zur Bedienung Ihres Programms.
1
2
https://foren.spline.inf.fu-berlin.de/viewforum.php?f=474
http://de.wikipedia.org/wiki/RSA-Kryptosystem
14
Funktionale Programmierung (ALP 1), WS 2011/12 9. Übungsblatt
Test ab 10. Januar 2012
58. Die Ackermannfunktion (10 Punkte)
Eine Variante der Ackermannfunktion beginnt mit der Nachfolgerfunktion:
B0 (n) = n + 1, für n ≥ 0
Bi (0) = 2, für i ≥ 1
Bi (n) = Bi−1 (Bi (n − 1)), für i ≥ 1, n ≥ 1
(Die Funktion Ai (n) aus der Vorlesung beginnt mit der Verdoppelungsfunktion A0 (n) =
2n und hat Anfangswerte Ai (0) = 1 für i ≥ 1. Die allgemeine Rekursion ist wie bei B .)
(a) Finden Sie durch Probieren Formeln für B1 (n), B2 (n), B3 (n).
(b) (Zusatzaufgabe, 0 Punkte). Beweisen Sie die Formeln durch vollständige Induktion.
(c) Zeigen Sie, dass B2 (n) ≥ A0 (n) ist, dass B3 (n) ≥ A1 (n) ist, und dass generell
Bi+2 (n) ≥ Ai (n) ist. (Das Wachstum von B hinkt dem Wachstum von A also
höchstens zwei Schritte hinterher.)
59. (1 Punkt) Was passiert, wenn man in der obigen Aufgabe Bi (0) = 1 für i ≥ 1 schreibt?
60. (10 Punkte) Wörterbuchoperationen
Wir möchten die Operationen für ein Wörterbuch um die Operation
anzahl:: WBUCH a b -> Int
erweitern, die die Anzahl der gespeicherten Schlüssel ausgibt. Wie gut sind die in der
Vorlesung angegebenen Implementierungen eines Wörterbuchs dafür geeignet?
Wählen Sie eine Implementierung aus und erweitern Sie sie entsprechend.
61. (10 Punkte) Datenstruktur für ein Wörterbuch
Modizieren Sie die in der Vorlesung angegebene Implementierung eines Wörterbuchs
als algebraischer Datentyp (Modul SpeicherAlg), sodass beim Löschen wirklich gelöscht
wird und man mit folgender Typdeklaration auskommt:
data WBUCH a b = Leer | Einf a b (WBUCH a b)
62. (10 Punkte) Vereinigung von Wörterbüchern.
Ergänzen Sie die algebraische Spezikation von Wörterbüchern um eine Operation
vereinige:: WBUCH a b -> WBUCH a b -> WBUCH a b, die den Inhalt zweier Wörterbücher vereinigt.
Können Sie ihre Spezikation so gestalten, dass das Ergebnis nicht von der Reihenfolge
der Argument abhängt, dass also vereinige w1 w2 äquivalent zu vereinige w2 w1 ist?
63. Bäume (5 Punkte) Schreiben Sie eine Funktion, die die Höhe eines Suchbaums bestimmt. (Vorlesung vom 28. 11.: data (Ord a) => Suchbaum a b = Leer | Knoten
a b (Suchbaum a b) (Suchbaum a b) mit Schlüsseln vom Typ a.) Dabei hat ein leerer
Suchbaum die Höhe −1 und ein Baum mit einem einzigen Knoten die Höhe 0.
64. Bäume (10 Punkte) Schreiben Sie eine Funktion, die einen Suchbaum in einen Baum
vom Type Baum Int umwandelt, wo in jedem Knoten seine Tiefe gespeichert ist. Sie
müssen die Typkonstruktoren aus der Vorlesung vom 16. 11. umbenennen, um Sie von
Suchbäumen zu unterscheiden:
data Baum a = BLeer | BKnoten a (Baum a) (Baum a)
15
Funktionale Programmierung (ALP 1), WS 2011/12 10. Übungsblatt
Test ab 17. Januar 2012
65. Orientierungstest (10 Punkte)
Bei der Flächenformel eines Polygons,
Pn
i=1 (xi+1
− xi )(yi+1 + yi )/2,
(Aufgabe 1 der
Probeklausur) hat das Vorzeichen eine Bedeutung: es ist positiv, wenn der Rand des
Polygons im Gegenuhrzeigersinn (im mathematisch positiven Sinn) durchlaufen wird
und negativ, wenn er im Uhrzeigersinn (im mathematisch negativen Sinn) durchlaufen
wird. Betrachten Sie die Formel im Fall eines Dreiecks (n
Funktion
orient,
= 3)
und schreiben Sie eine
die berechnet, ob ein Dreieck positiv oder negativ orientiert ist. Ver-
einfachen Sie dazu die Formel unter Ausnützung der Tatsache, dass sich die Fläche nicht
ändert, wenn man das Dreieck verschiebt, und man daher eine Ecke auf den Nullpounkt
legen kann. Wann ergibt die Formel den Wert 0?
66. Backus-Naur-Form (10 Punkte)
Dies ist eine rudimentäre Syntax für arithmetische Ausdrücke mit Addition und Multiplikation, aber ohne Klammern:
hZieri ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
hZahli ::= hZieri{hZieri}
hAusdrucki ::= hZahli | hAusdrucki*hAusdrucki | hAusdrucki+hAusdrucki
Zeigen Sie, wie man in dieser Grammatik die Zeichenkette
hAusdrucki
30+4*5
aus der Variablen
Schritt für Schritt erzeugen kann. Ist dies auf eindeutige Art möglich?
67. Freie und gebundene Variablen (10 Punkte)
Bestimmen Sie die freien und gebundenen Variablen in den folgenden Ausdrücken. Benennen Sie die gebundenen Variablen so um, dass in jedem Ausdruck alle
λ-Abstraktionen
verschiende Variablen binden.
λa.(aλb.bca)
λf.bλb.(λf.f b)
(c) λf g.(λb.h)(λa.b)f g
(d) λxy.(λx.y)(λy.x)
(e) λpq.(λr.(p(λq.(λp.rq)))(qp))
(a)
(b)
68. Auswertung (10 Punkte)
Werten Sie die folgenden Ausdrücke Schritt für Schritt aus; und geben Sie auch alle
Zwischenergebnisse an.
(λxy.yx)(λp.λq.p)(λk.k)
(b) (λx.λyz.(xy)z)(λf a.f a)(λk.k)(λj.j)
(c) (λf a.f a)(λf a.f a)(λx.x)
(d) (λpq.pq)((λx.x)(λab.a))(λk.k)
(e) (λf.f f )((λf.f f )(λf a.a))g
(a)
69. Nachfolger, Addition und Multiplikation (10 Punkte)
Werten Sie die folgenden Ausdrücke aus.
(λwnz.n(wnz))(λnz.n(nz))
(b) (λnz.n(n(nz)))(λwnz.n(wnz))(λnz.n(nz))
(c) (λuab.u(ab))(λnz.n(n(n(z))))(λnz.n(n(z)))
(d) (λxy.xyλab.b)(λab.a)(λab.b)
(e) (λxy.xyλab.b)(λab.b)(λab.a)
(a)
16
Funktionale Programmierung (ALP 1), WS 2011/12 11. Übungsblatt
Test ab 23. Januar 2012
70. Zwei verschiedene Funktionen für die Addition (10 Punkte)
• Im Ausdruck 3Sx wird die Nachfolgerfunktion S = λanz.n(anz) dreimal auf das
Argument x angewendet, und das Ergebnis ist S(S(S(x))). 3S2 ist also 5, und
generell können wir auf diese Art zwei Church-Zahlen im Lambdakalkül addieren:
λab.aSb = λab.a(λanz.n(anz))b
• In der Vorlesung wurde die folgende Additionsfunktion eingeführt
λab.λnz.an(bnz) = λabnz.an(bnz)
Stellen die beiden in (a) und (b) gegebenen Ausdrücke die gleiche Funktion dar, in dem
Sinn, dass sie für alle Argumente dasselbe Ergebnis liefern?
71. Negative Zahlen als Paare von natürlichen Zahlen (10 Punkte)
Jede Darstellung von natürlichen Zahlen kann zu einer Darstellung aller ganzen Zahlen
als Paare natürlicher Zahlen erweitert werden: Das Paar (a, b) ∈ N × N stellt dann die
ganze Zahl a − b ∈ Z dar. Auf diese Art kann man negative Zahlen auch im LambdaKalkül einführen.
Schreiben Sie eine Haskell-Funktionen, die zu zwei Paaren natürlicher Zahlen (a, b) und
(a0 , b0 )
(a) bestimmt, ob sie dieselbe ganze Zahl darstellen;
(b) eine Darstellung für die Summe berechnet;
(c) eine Darstellung für das Produkt berechnet.
72. Normalisierung (10 Punkte)
Die Zahldarstellung der vorigen Aufgabe ist nicht eindeutig. Jede ganze Zahl hat aber
eine eindeutige normalisierte Darstellung (a, b) ∈ N × N, wo die Bedingung ab = 0
gilt. Schreiben Sie eine Funktion zum Berechnen einer normalisierten Darstellung für
eine gegebene Darstellung einer ganzen Zahl, und zwar sowohl in Haskell als auch im
Lambdakalkül.
73. (0 Punkte, freiwillig) Denieren Sie die Potenzfunktion im Lambda-Kalkül.
74. Rekursion (10 Punkte)
Denieren Sie die Fakultätsfunktion n 7→ n! im Lambda-Kalkül.
75. Durchlaufen von Bäumen (0 Punkte, freiwillig)
Schreiben Sie eine Funktion, die für eine Darstellung eines arithmetischen Ausdrucks
vom Typ Ausdruck (Vorlesung vom 16. 11. 2011) die Anzahl der verschiedenen Variablen
berechnet.
76. Teilwortsuche (10 Punkte)
Schreiben Sie ein Programm, das feststellt ob eine Zeichenkette (z. B. "ab c") in einem
längeren Text (z. B. "xyz rstab cde uvw") als Teilkette enthalten ist. Analysieren Sie
die Laufzeit Ihres Programmes in Abhängigkeit von der Länge n1 und n2 der beiden
Eingaben. Gesucht ist eine obere Schranke in O-Notation.
77. (5 Punkte) Analysieren Sie die Laufzeit Ihrer (oder einer anderen) Lösung zu Aufgabe 43
vom 7. Übungsblatt. (Teilabschnitt mit der gröÿten Summe). Gesucht ist eine Schranke
der Form O(f (n)) für eine geeignete Funktion f .
17
Funktionale Programmierung (ALP 1), WS 2011/12 12. Übungsblatt
Test ab 30. Januar 2012
78. Zwei verschiedene Funktionen für das logische Und (5 Punkte)
In der Vorlesung wurden zwei verschiedene Möglichkeiten λxy.xyx und λxy.xyF =
λxy.xyλuv.v für die Konjunktion im Lambda-Kalkül vorgestellt. Stellen diese beiden
Ausdrücke die gleiche Funktion dar, in dem Sinn, dass sie für alle Argumente dasselbe
Ergebnis liefern?
79. Die Ausgabemonade (10 Punkte)
Rechnen Sie nach, dass die Ausgabe-Monade (Vorlesung vom 23. Januar) die Monadengesetze erfüllt: p >>= return = p, return x >>= f = f x, und
(p >>= \x -> q) >>= r =
p >>= (\x -> (q >>= r),
falls x nicht in r vorkommt.
80. do-Notation (4 Punkte)
Schreiben Sie p >>= q in do-Notation (ohne den Bindeoperator >>=).
81. Kaufmännisches Runden (5 Punkte)
Schreiben Sie eine Funktion, die einen Gleitkommawert auf den nächstgelegenen Euround-Cent-Wert mit zwei Nachkommastellen rundet. Wenn die Eingabe genau in der
Mitte zwischen zwei Cent-Beträgen liegt, dann soll das Ergebnis gewählt werden, dessen
letzte Zier gerade ist. Beispiele: runde 0.325 = 0.32, runde 0.32501 = 0.33, runde
0.335 = 0.34, runde 0.31499 = 0.31, runde 0.315 = 0.32, runde 0.305 = 0.30.
82. Umnummerieren eines Baumes (10 Punkte)
Schreiben Sie mit Hilfe der Zustandsmonade ein Programm nummeriere:: (Eq a) =>
Baum a -> Baum Int, das alle Daten in einem Baum durch die Zahlen 0,1,. . . ersetzt,
wobei gleiche Daten durch die gleiche Zahl ersetzt werden sollen. Sie können ein Wörterbuch (Vorlesungen vom 2. und 4. 1. 2011) zu Hilfe nehmen.
data Baum a = Leer | Knoten a (Baum a) (Baum a) (Vorlesung vom 16. 11. 2011)
83. Tilgungsplan (10 Punkte)
(a) Sie haben am 1. 1. 2012 einen Kredit in Höhe k zu einem jährlichen Zinssatz p aufgenommen, den Sie durch unregelmäÿige Raten z1 , z2 , z3 , . . . zu Beginn eines jeden
Jahres zurückzahlen. Schreiben Sie ein Programm zur Erstellung eines Tilgungsplanes. Die Ausgabe für [z1 , z2 ] = [100, 110] könnte zum Beispiel so aussehen:
Datum
Restschuld Zahlung Zinsen Tilgung
1.1.2012 1000.00
1.1.2013 950.00
100.00 50.00
50.00
1.1.2014 887.50
110.00 47.50
62.50
Dabei sollen alle Zwischenergebnisse kaufmännisch gerundet werden (siehe Aufgabe 81).
(b) Erstellen Sie einen Tilgungsplan für regelmäÿige Raten in Höhe von z , bis der
Kredit getilgt ist. Die letzte Rate müssen Sie unter Umständen reduzieren.
84. Zusatzaufgabe, 0 Punkte
Bestimmen Sie die Rückzahlungsrate, die notwendig ist, um einen Kredit in a Jahren
zu tilgen.
18
Funktionale Programmierung (ALP 1), WS 2011/12 13. Übungsblatt
Test ab 6. Februar 2012
85. Aufzählen aller Möglichkeiten (10 Punkte)
Schreiben Sie eine Funktion
alleZerl:: [a]->[([a],[a])],
die alle Zerlegungen ei-
ner Liste in zwei Teillisten konstruiert; dabei sollen die Elemente in den Teillisten in
derselben Reihenfolge vorkommen wie in der Eingabeliste. Zum Beispiel ist
"cad") eine solche Zerlegung von "acbaadf". Bei einer Liste
2n Zerlegungen (die nicht alle verschieden sein müssen).
n
von
("abaf",
Elementen gibt es
86. Zusatzaufgabe, 0 Punkte
Unter welcher Bedingung an die Eingabeliste enthält die Ausgabe der vorigen Aufgabe
2n verschiedene
Paare?
87. Permutationen (10 Punkte)
Schreiben Sie ein Programm
tionen der Zahlen
1, 2, . . . , n
permutationen:: Int -> [[Int]],
das alle
n!
Permuta-
ausgibt. (Tipp: Es gibt zwei einfache Ansätze: Entweder
man probiert alle Möglichkeiten für das erste Element durch, oder man versucht das
Element
n auf alle möglichen Arten in eine Permutation von 1, 2, . . . , n − 1 einzufügen.)
88. Syntaxanalyse von Ausdrücken (8 Punkte)
Erweitern Sie das Programm aus der Vorlesung zum Parsen von Ausdrücken, sodass
auch negative Konstanten erlaubt sind.
89. Zufallszahlen (15 Punkte)
(a) Schreiben Sie ein Programm, das einen zufälligen Suchbaum mit
indem es
n
zufällige
Float-Zahlen
n Knoten erzeugt,
der Reihen nach in einen leeren Suchbaum ein-
fügt. (Aufgabe 52 vom 8. Übungsblatt)
(b) Erstellen Sie 1000 zufällige Suchbäume mit
Suchbäume der Höhe
h = 0, 1, 2, . . .
n = 10 Knoten, und zählen Sie, wie oft
herauskommen (Aufgabe 63 vom 9. Übungs-
blatt). Bestimmen Sie den Mittelwert der Höhe.
90. Längste monotone Teilfolge (0 Punkte, freiwillig)
Schreiben Sie ein Programm
lmT:: Ord a => [a]->Int,
das die Länge einer längsten
[1,3,5]
[2,1,3,4,3,6,5] (aber nicht die längste).
streng monoton wachsende Teilfolge in einer Liste bestimmt. Zum Beispiel ist
eine streng monoton wachsende Teilfolge vom
91. Der diskrete Fréchet-Abstand zur Ähnlichkeitsmessung zwischen zwei Polygonzügen
(freiwillig, 0 Punkte)
Schreiben Sie ein Programm für folgende Aufgabe. Wir stellen uns vor, dass ein Hund auf
a1 , a2 , . . . , am von Punkten der Ebene wandert und sein Herrchen
Folge b1 , b2 , . . . , bn . Dabei gelten folgende Regeln:
einer gegebenen Folge
auf einer gegebenen
(a) Sie beginnen in den Punkten
beziehungsweise
bn
a1
und
b1 ,
und am Ende sind sie in den Punkten
am
angelangt.
(b) Wenn der Hund im Punkt
ai
und das Herrchen im Punkt
bj
ist, dann haben sie
folgende Möglichkeiten für den nächsten Schritt:
ai+1 und das Herrchen bleibt auf bj .
Der Hund bleibt auf ai und das Herrchen geht zu bj+1 .
Sie bewegen sich beide gleichzeitig nach ai+1 beziehungsweise bj+1 .
i. Der Hund geht nach
ii.
iii.
Wie lang muss die Hundeleine mindestens sein, damit so ein Spaziergang möglich ist?
19
Funktionale Programmierung (ALP 1), WS 2011/12 14. Übungsblatt
92. Bäume kodieren und dekodieren (10 Punkte)
(a) Geben Sie eine Beschreibung der Zeichenketten, die bei der Kodierung von Bäumen vom Typ Baum' Int gemäÿ Aufgabe 41 vom 6. Übungsblatt entstehen, in
erweiterter Backus-Naur-Form (einschlieÿlich der Darstellung der Zahlen).
data Baum' a = Blatt a | Knoten a (Baum' a) (Baum' a)
(Sie können in Gedanken 'D' und 'U' mit '(' und ')' identizieren.)
(b) (Aufgabe 49 vom 8. Übungsblatt, 0 Punkte, freiwillig) Schreiben Sie ein Programm,
das die Umkehrfunktion zu Aufgabe 41 als Parse-Problem berechnet.
93. Aufzählen und Abzählen aller Möglichkeiten (15 Punkte)
(a) Schreiben Sie ein Programm zur Erzeugung aller Suchbäume mit den Schlüsseln
1, . . . , n. (Die Werte sollen einfach auf 0 gesetzt werden.)
(b) Zählen Sie, wie viele der Suchbäume mit den Schlüsseln 1, . . . , 10 die Höhe h =
0, 1, 2, . . . haben (vergleiche Aufgabe 63 vom 9. Übungsblatt und Aufgabe 89b vom
13. Übungsblatt). Bestimmen Sie den Mittelwert der Höhe.
(Hinweis: Das Ergebnis muss nicht mit Aufgabe 89b übereinstimmen.)
(c) (0 Punkte, freiwillig) Schreiben Sie ein möglichst ezientes Programm, das die
Anzahl der Suchbäume mit den Schlüsseln 1, . . . , n berechnet. Wie groÿ muss n
sein, damit die Anzahl gröÿer als 10100 wird?
94. Skalieren von Pixelgraken (Buchstabenbildern) (10 Punkte)
Man kann rudimentäre Graken (vom Typ [String]) als Listen von Zeichenketten
darstellen. (Die Graken von Aufgabe 38 vom 6. Übungsblatt kann man dann daraus
durch die Standardfunktion unlines erzeugen.)
(a) Schreiben Sie zwei Funktionen skaliereH, skaliereV:: Int -> [String] ->
[String], die eine solche Grak in horizontaler beziehungsweise vertikaler Richtung um einen ganzzahligen Faktor k > 0 strecken (skalieren), indem die Zeichen
k -mal wiederholt werden. Beispiel:
skaliereH 3
["D
+-->",
" D | ",
" +--+
"]
!
=
["DDD
+++------>>>",
" DDD
|||
",
"
+++------+++
"]
!
(b) Schreiben Sie eine Funktion skaliere:: Int -> [String] -> [String], die eine
Grak in beiden Richtungen skaliert.
95. Strukturelle Induktion (10 Punkte)
Die Standardfunktionen takeWhile, dropWhile:: (a -> Bool) -> [a] -> [a] können so deniert werden:
takeWhile p [ ]
takeWhile p (x:xs) |
|
dropWhile p [ ]
dropWhile p (x:xs) |
|
= [ ]
p x
= x : takeWhile p xs
otherwise = [ ]
= [ ]
p x
= dropWhile p xs
otherwise = (x:xs)
Leiten Sie daraus die Beziehung takeWhile p x ++ dropWhile p x = x her.
20
Algorithmen und Programmierung 1
(Funktionale Programmierung), WS 2011/2012 — Klausur
Aufgabe
1
2
3
4
5
6
Punkte
20
15
20
20
5
10
gesamt: 90
90 Minuten. Abgabe bis Montag, 20. Februar 2012, 15:30 Uhr
1. (20 Punkte) Schreiben Sie ein Modul Stapel zur Implementierung des abstrakten
Datentyps ST a, der einen Stapel (Keller, stack, pushdown storage) von Werten
vom Typ a darstellt. Der Stapel soll folgenden Operationen erlauben:
leer:: ST a -- erzeugt einen leeren Stapel
push:: a -> ST a -> ST a -- fügt ein Element als oberstes ein
top:: ST a -> a -- greift auf das oberste Element zu
pop:: ST a -> ST a -- löscht das oberste Element vom Stapel
istLeer:: ST a -> Bool -- testet, ob der Stapel leer ist
Die Bedeutung der Operationen ist durch folgende Gleichungen gegeben.
istLeer (leer) = True
istLeer (push x s) = False
top (push x s) = x
pop (push x s) = s
push (top s) (pop s) = s, falls not (istLeer s)
Bei einem leeren Stapel (istLeer liefert True) soll top und pop eine Fehlermeldung ausgeben.
Sie können frei entscheiden, welche Datenstruktur Sie zur Darstellung des Stapels verwenden und wie Sie die Operationen implementieren. Das Modul soll eine
explizite Exportliste haben. Ist es erforderlich, a auf bestimmte Typklassen einzuschränken? (Diese müssen Sie eventuell bei den Signaturen der obigen Funktionen
als Voraussetzungen ergänzen.) Begründen Sie Ihre Antwort.
Bei allen Funktionen ist wie immer eine Typdeklaration anzugeben.
2. (15 Punkte) Welche Variablen kommen im Ausdruck
λx. λx.λa.(ax(xx)yx) (λa.xa)
gebunden vor? Welche Variablen kommen frei vor (bezogen auf den gesamten
Ausdruck)?
Reduzieren Sie den Ausdruck so weit wie möglich.
21
3. (20 Punkte) Summen
Schreiben Sie ein Haskell-Programm, das in einer Liste vom Typ [Integer] ein
Tripel (a, b, c) mit a+b = c findet, falls es eines gibt. Dabei müssen a, b und c von
verschiedenen Stellen der Eingabeliste kommen. (Sie dürfen gleich sein, falls in
der Eingabeliste gleiche Zahlen mehrfach vorkommen.) Sie dürfen die Funktion
sort aus dem Modul Data.List verwenden, die eine Folge der Länge n mit
Laufzeit O(n log n) sortiert. Verwenden Sie Kommentare zur Erläuterung Ihres
Programms. Bei allen Funktionen ist wie immer eine Typdeklaration anzugeben.
Analysieren Sie sie asymptotische Laufzeit Ihres Programms (in O-Notation in
Abhängigkeit von der Länge n der Eingabeliste).
(Falls Ihr Programm korrekt ist und eine bessere Laufzeit als O(n3 ) hat, gibt es
bis zu 10 Zusatzpunkte.)
4. (20 Punkte) Welche Formel muss man für x einsetzen, damit die Gleichung
drop m . take n = take (x) . drop m
für alle m ≥ 0 und alle n ≥ 0 gilt?
Beweisen Sie die Gleichung dann durch strukturelle Induktion (oder durch eine
andere Methode Ihrer Wahl) unter Verwendung der folgenden Definitionen:
(t1)
(t2)
(t3)
(d1)
(d2)
(d3)
take, drop:: Int -> [a] -> [a]
take n _ | n <= 0 = []
take _ []
= []
take n (x:xs)
= x : take (n-1) xs
drop n xs | n <= 0 = xs
drop _ []
= []
drop n (_:xs)
= drop (n-1) xs
5. (5 Punkte) Funktionen höherer Ordnung
Welcher der folgenden Ausdrücke ist äquivalent zur Formel [g x y | y <- ys]?
a) (map . g x) ys, b) (map g x) ys, c) map(g x y) ys, d) map (g x)ys.
(Es können auch mehrere Antworten richtig sein. Eine Begründung ist nicht erforderlich.)
6. (10 Punkte) Typinferenz
Bestimmen Sie den allgemeinsten Typ, den die Funktion f haben kann.
f a b c
| b c
= [c+2]
| otherwise = a c
Begründen Sie Schritt für Schritt, wie Sie zu Ihren Schlussfolgerungen kommen.
22
Herunterladen