Tutoraufgabe 1 (Auswertungsstrategie): Aufgabe 2

Werbung
Programmierung WS12/13
Übungsblatt 10 (Abgabe 11.01.2013)
M. Brockschmidt, F. Emmes, C. Otto, T. Ströder
Prof.aa
Dr. J. Giesl
Allgemeine Hinweise:
• Die Hausaufgaben sollen in Gruppen von je 2 Studierenden aus der gleichen Kleingruppenübung
(Tutorium) bearbeitet werden. Namen und Matrikelnummern der Studierenden sind auf jedes Blatt
der Abgabe zu schreiben. Heften bzw. tackern Sie die Blätter!
• Die Nummer der Übungsgruppe muss links oben auf das erste Blatt der Abgabe geschrieben
werden. Notieren Sie die Gruppennummer gut sichtbar, damit wir besser sortieren können.
• Die Lösungen müssen bis Freitag, 11.01.2013 um 8:00 Uhr in den entsprechenden Übungskasten eingeworfen werden. Sie finden die Kästen am Eingang Halifaxstr. des Informatikzentrums (Ahornstr. 55).
Alternativ können Sie die Lösungen auch in Ihrem Tutorium vor der Abgabefrist direkt bei Ihrer Tutorin/Ihrem Tutor abgeben.
Tutoraufgabe 1 (Auswertungsstrategie):
Gegeben sei das folgende Haskell-Programm:
absteigend :: Int -> [ Int ]
absteigend 0 = []
absteigend n = n : absteigend (n -1)
produkt :: [ Int ] -> Int
produkt [] = 1
produkt ( x : xs ) = x * produkt xs
summe :: [ Int ] -> Int
summe xs = summe ’ xs 0
where summe ’ []
a = a
summe ’ ( x : xs ) a = summe ’ xs ( a + x )
Die Funktion absteigend berechnet die absteigende Liste der natürlichen Zahlen bis hinunter zu 1. Zum
Beispiel berechnet absteigend 5 die Liste [5,4,3,2,1]. Die Funktion produkt multipliziert die Elemente
einer Liste, beispielsweise ergibt produkt [3,5,2,1] die Zahl 30. Die Funktion summe addiert die Elemente
einer Liste. Zum Beispiel liefert summe [5,2,7] den Wert 14.
Geben Sie alle Zwischenschritte bei der Auswertung der folgenden Ausdrücke an:
1. produkt (absteigend 2)
2. summe (absteigend 2)
Beachten Sie, dass Haskell eine Leftmost-Outermost Auswertungsstrategie besitzt. Allerdings sind Operatoren
wie * und +, die auf eingebauten Zahlen arbeiten, strikt, d.h. hier müssen vor Anwendung des Operators seine
Argumente vollständig ausgewertet worden sein.
Aufgabe 2 (Auswertungsstrategie):
(7 Punkte)
Gegeben sei das folgende Haskell-Programm:
produkt :: [ Int ] -> Int
produkt [] = 1
produkt ( x : xs ) = x * produkt xs
jedesZweite :: [ Int ] -> [ Int ]
jedesZweite [] = []
1
Programmierung WS12/13
Übungsblatt 10 (Abgabe 11.01.2013)
jedesZweite [ x ] = [ x ]
jedesZweite ( x : _ : xs ) = x : jedesZweite xs
minus10 :: [ Int ] -> [ Int ]
minus10 [] = []
minus10 ( x : xs ) = x - 10 : minus10 xs
Die Funktion produkt multipliziert die Elemente einer Liste, beispielsweise ergibt produkt [3,5,2,1] die
Zahl 30. Die Funktion jedesZweite bekommt eine Liste als Eingabe und gibt die gleiche Liste zurück, wobei
jedes zweite Element gelöscht wurde. So ergibt jedesZweite [1,2,3] die Liste [1,3]. Die Funktion minus10
gibt seine Eingabeliste zurück, wobei bei von jedem Element 10 subtrahiert wurde.
Geben Sie alle Zwischenschritte des Ausdrucks produkt (jedesZweite (minus10 [3,2,1])) bei der Auswertung an. Schreiben Sie hierbei um Platz zu sparen p, j und m statt produkt, jedesZweite und minus10.
Hinweise:
• Beachten Sie, dass Haskell eine Leftmost-Outermost Auswertungsstrategie besitzt. Allerdings sind Operatoren wie * und +, die auf eingebauten Zahlen arbeiten, strikt, d.h. hier müssen vor Anwendung des
Operators seine Argumente vollständig ausgewertet worden sein (wobei zunächst das linke Argument
ausgewertet wird).
Tutoraufgabe 3 (Listen):
Seien x, y ganze Zahlen vom Typ Int und xs und ys Listen der Längen n und m vom Typ [Int].
Welche der folgenden Gleichungen zwischen Listen sind richtig und welche nicht? Begründen Sie Ihre Antwort.
Falls es sich um syntaktisch korrekte Ausdrücke handelt, geben Sie für jede linke und rechte Seite auch an, wie
viele Elemente in der jeweiligen Liste enthalten sind und welchen Typ sie hat.
Beispiel : Die Liste [[1,2,3],[4,5]] hat den Typ [[Int]] und enthält 2 Elemente.
Hinweise:
• Hierbei steht ++ für den Verkettungsoperator für Listen. Das Resultat von xs ++ ys ist die Liste, die
entsteht, wenn die Elemente aus ys — in der Reihenfolge wie sie in ys stehen — an das Ende von xs
angefügt werden.
Beispiel : [1,2] ++ [1,2,3] = [1,2,1,2,3]
• Falls linke und rechte Seite gleich sind, genügt eine Angabe des Typs und der Elementzahl
a) x:xs = [x] ++ xs
b) (x:y):xs = x:y:xs
c) [x,y,xs] = x:y:xs
d) x:y:((x:[x]) ++ xs) = [x,y,x] ++ (x:xs)
e) []:[[],[[1]]] = [[],[]]:[[[1]]]
Aufgabe 4 (Listen):
(9 Punkte)
Seien x, y, z ganze Zahlen vom Typ Int und xs und ys Listen der Längen n und m vom Typ [Int].
Welche der folgenden Gleichungen zwischen Listen sind richtig und welche nicht? Begründen Sie Ihre Antwort.
Falls es sich um syntaktisch korrekte Ausdrücke handelt, geben Sie für jede linke und rechte Seite auch an, wie
viele Elemente in der jeweiligen Liste enthalten sind und welchen Typ sie hat.
Beispiel : Die Liste [[1,2,3],[4,5]] hat den Typ [[Int]] und enthält 2 Elemente.
Hinweise:
• Falls linke und rechte Seite gleich sind, genügt wiederum eine Angabe des Typs und der Elementzahl
2
Programmierung WS12/13
Übungsblatt 10 (Abgabe 11.01.2013)
a) [] ++ [xs] = [] : [xs]
b) [[]] ++ [x] = [] : [x]
c) [x] ++ [y] = x : [y]
d) x:y:z:(xs ++ ys) = [x,y,z] ++ xs ++ ys
e) [(x:xs):[ys],[[]]] = (([]:[]):[]) ++ ([([x] ++ xs),ys]:[])
Tutoraufgabe 5 (Programmieren):
Implementieren Sie alle der im Folgenden beschriebenen Funktionen in Haskell. Geben Sie jeweils auch die
Typdeklarationen an. Verwenden Sie außer Listenkonstruktoren [] und : (und deren Kurzschreibweise) und
Vergleichsoperatoren wie <=, ==,. . . keine vordefinierten Funktionen (dies schließt auch arithmetische Operatoren ein), außer denen, die in den jeweiligen Teilaufgaben explizit erlaubt werden.
a) sekunden h m s
Gibt die Anzahl der Sekunden zurück, die in h Stunden, m Minuten und s Sekunden vergehen. So
berechnet zum Beispiel sekunden 5 4 3 den Wert 18243. Die Funktion darf sich auf negativen Eingaben
beliebig verhalten. Sie dürfen hier + und * verwenden.
b) turm x y
Berechnet den Potenzturm x ↑↑ y. Der Potenzturm ist die logische Weiterentwicklung von Multiplikation
und Potenzfunktion:
Multiplikation
a·n
:=
a + a + ··· + a
{z
}
|
an
:=
a
| · a ·{z. . . · a}
n
Potenz
n
a·
Potenzturm
a ↑↑ n
:=
a
|
(aa )
··
{z
n
!
}
Beispiele:
2 2(2 )
• 2 ↑↑ 4 = 2
4
= 2(2
)
= 216 = 65.536
• 3 ↑↑ 3 = 7.625.597.484.987
Die Funktion darf sich auf negativen Eingaben beliebig verhalten. Sie dürfen auf - und ^ (zur Berechnung
der Potenz) zurückgreifen.
Hinweise:
• Auch in Haskell gibt es unterschiedliche Integer-Datentypen mit verschiedenen Wertebereichen, weshalb in Ihrer Lösung vermutlich turm 3 3 nicht das erwartete Ergebnis 7625597484987 liefert.
Wenn Sie den Datentyp Integer statt Int für die Darstellung ganzer Zahlen verwenden, vermeiden
Sie das Problem.
c) wurzel x
Berechnet die abgerundete dritte (!) Wurzel aus x. Zum Beispiel liefert der Aufruf wurzel 124 den Wert
4. Die Funktion darf sich auf negativen Eingaben beliebig verhalten. Sie dürfen hier - und * verwenden.
d) getEnd xs
Berechnet das letzte Element der Int-Liste xs. Beispielsweise berechnet getEnd [12, 7, 23] den Wert
23. Die Funktion darf sich auf leeren Listen beliebig verhalten.
e) insertEnd x ys
Berechnet die Int-Liste, die entsteht, wenn man den Wert x an das Ende der Int-Liste ys einfügt.
Beispielsweise berechnet insertEnd [12, 7] 23 die Liste [12, 7, 23].
3
Programmierung WS12/13
Übungsblatt 10 (Abgabe 11.01.2013)
f ) anzahl x ys
Berechnet die Anzahl der Vorkommen von x in der Int-Liste ys. Zum Beispiel liefert der Aufruf anzahl
3 [1,2,3,4,5,4,3,2,1] den Wert 2. Sie dürfen hier + verwenden.
g) einfuegen x ys
Berechnet die Int-Liste, die entsteht, wenn man den Wert x so in die sortierte Int-Liste ys einfügt, dass
diese anschließend weiterhin sortiert ist. Zum Beispiel liefert der Aufruf einfuegen 5 [1,3,5,7] den
Wert [1,3,5,5,7].
h) insSort xs
Sortiert die Int-Liste xs. Verwenden Sie dabei die Funktion einfuegen. Der Aufruf insSort [5,3,1,8]
liefert dann beispielweise den Wert [1,3,5,8].
i) zipping xs ys
Berechnet die Kombination der beiden Int-Listen xs und ys im Reißverschlussprinzip. Das heißt, dass
das Ergebnis zuerst das erste Element von xs, dann das erste Element von ys, dann das zweite Element
von xs usw. enthält. Wenn eine der beiden Listen leer ist, sollen nur noch Elemente aus der anderen Liste
folgen. Beispielsweise berechnet zipping [1,2,5,8,7,6] [3,9,4] die Liste [1,3,2,9,5,4,8,7,6].
j) flach xs
Berechnet für eine Liste von Int-Listen eine “flache” Liste, die die Elemente der inneren Listen der
Eingabe xs in der ursprünglichen Reihenfolge enthält. Der Aufruf flach [[1,5,2],[],[2,3]] liefert
zum Beispiel den Wert [1,5,2,2,3].
Aufgabe 6 (Programmieren):
(1+1+2+1+1+1+2+2+2+2 = 15 Punkte)
Implementieren Sie alle der im Folgenden beschriebenen Funktionen in Haskell. Geben Sie jeweils auch die
Typdeklarationen an. Verwenden Sie außer Listenkonstruktoren [] und : (und deren Kurzschreibweise) und
Vergleichsoperatoren wie <=, ==,. . . keine vordefinierten Funktionen (dies schließt auch arithmetische Operatoren ein), außer denen, die in den jeweiligen Teilaufgaben explizit erlaubt werden.
a) millimeter f z
Gibt (halbwegs präzise) aus, wie viele Millimeter f Fuß und z Zoll sind. Gehen Sie hierbei davon aus,
dass ein Fuß 305mm entspricht und ein Zoll genau 25mm ist. So berechnet zum Beispiel millimeter 5
4 den Wert 1625. Die Funktion darf sich auf negativen Eingaben beliebig verhalten. Sie dürfen hier +
und * verwenden.
b) mult x y
Berechnet x · y. Sie dürfen dazu + und - verwenden. Die Funktion darf sich auf negativen Eingaben
beliebig verhalten.
c) bLog x
Berechnet den aufgerundeten Logarithmus zur Basis 2 von x. Somit liefert bLog 1 den Wert 0, bLog 5
den Wert 3 und bLog 32 den Wert 5. Sie dürfen hier + und * verwenden. Die Funktion darf sich auf
negativen Eingaben oder der Eingabe 0 beliebig verhalten.
d) getLastTwo xs
Berechnet die Teilliste der letzten zwei Elemente der Int-Liste xs. Beispielsweise berechnet getLastTwo
[12, 7, 23] den Wert [7, 23]. Die Funktion darf sich auf Listen der Länge 0 und 1 beliebig verhalten.
e) singletons x
Berechnet eine Liste mit x Elementen, wobei jedes Listenelement eine einelementige Liste ist. Die Elemente der einelementigen Listen sind die Zahlen x, x − 1, . . . , 1. Beispielsweise berechnet singletons 3
die Liste [[3],[2],[1]]. Die Funktion darf sich auf negativen Eingaben beliebig verhalten. Sie dürfen
hier - verwenden.
4
Programmierung WS12/13
Übungsblatt 10 (Abgabe 11.01.2013)
f ) cleanEmpty xs
Die Eingabe ist eine Liste von Listen von Zahlen (vom Typ [[Int]]). Die Funktion berechnet die Liste
von Listen von Zahlen, die aus der Eingabe entsteht, indem alle leeren Listen aus dieser entfernt werden.
Beispielsweise berechnet cleanEmpty [[5,6],[],[8],[]] die Liste [[5,6],[8]].
g) kleinstes xs
Berechnet das kleinste Element, das in der Int-Liste xs vorkommt. Zum Beispiel liefert der Aufruf
kleinstes [42, 7, 23] den Wert 7. Die Funktion darf sich auf leeren Listen beliebig verhalten.
h) nachHinten x xs
Verschiebt die x ersten Elemente der Liste xs an das Ende. Beispielsweise berechnet nachHinten 2
[1,2,3,4] die Liste [3,4,1,2]. Sie dürfen hier ++ und - verwenden. Die Funktion darf sich auf negativen
Eingaben für x oder bei einer leeren Eingabeliste beliebig verhalten.
i) einpacken xs ys
Das erste Argument xs ist eine Liste von Listen von Zahlen (vom Typ [[Int]]), das zweite Argument
ist eine einfache Liste von Zahlen (vom Typ [Int]). Die Funktion ersetzt leere Listen in der ersten
Eingabeliste durch einelementige Listen. Der Inhalt dieser einelementigen Listen ist die jeweils nächste
Zahl aus der zweiten Eingabeliste. Beispielsweise berechnet einpacken [[5,6],[],[8],[]] [1,2] die
Liste [[5,6],[1],[8],[2]]. Wenn im zweiten Argument nicht genug Zahlen zur Verfügung stehen,
werden zusätzliche leere Listen im ersten Argument leer gelassen. Wenn im zweiten Argument zu viele
Zahlen zur Verfügung stehen, werden diese ignoriert.
j) listAdd x xs
Addiert jeweils das n-te Listenelement auf das (n+1)-te Listenelement, wobei auf das erste Listenelement
x addiert wird. Beispielsweise berechnet listAdd 5 [1,9,3] die Liste [6,10,12]. Sie dürfen hier +
verwenden.
5
Herunterladen