Grundlagen der Programmierung 2 Aufgabenblatt Nr. 7 Aufgabe 1

Werbung
Prof. Dr. Manfred Schmidt-Schauß
Künstliche Intelligenz/Softwaretechnologie
Fachbereich Informatik und Mathematik/ Institut für Informatik
Johann Wolfgang Goethe-Universität Frankfurt am Main
Grundlagen der Programmierung 2
Sommersemester 2008
Aufgabenblatt Nr. 7
Abgabe: Mittwoch 28. Mai 2008 vor! der Vorlesung
Bitte beachten Sie, dass zu Ihrer Lösung zugehöriger Quellcode sowohl gedruckt abgegeben als auch
per Email an den entsprechenden Tutor gesendet werden muss!.
Für zu implementierende Programme/Funktionen sind stets auch Testaufrufe mit
geeigneten Werten der Lösung beizufügen!
Aufgabe 1 (15 Punkte)
a) Üben Sie die Benutzung des Haskell-Interpreters GHCi, indem Sie den Interpreter starten
(bzw. eventuell vorher installieren) und sich mit der zugehörigen Dokumentation vertraut
machen. Machen Sie sich insbesondere mit den Kommandos des Interpreters vertraut und
erklären Sie die Funktionalitäten der Kommandos1 :load, :reload, :cd, :quit und :?
und geben Sie Beispiele für deren Verwendung an.
(5 Punkte)
b) Implementieren Sie eine Funktion in Haskell, die vier Parameter als Eingaben erwartet:
– eine Gesamtzahl an Übungspunkten aus der ersten Hälfte,
– eine Gesamtzahl an Übungspunkten aus der zweiten Hälfte,
– einen Wahrheitswert der genau dann wahr (True) ist, wenn mindestens einmal in der
ersten Hälfte der Übungen vorgerechnet wurde, und
– einen Wahrheitswert der genau dann wahr (True) ist, wenn mindestens einmal in der
zweiten Hälfte der Übungen vorgerechnet wurde.
Als Ausgabe soll die Funktion die Bonuspunkte für die Klausur berechnen. Speichern Sie
die Funktion in einer Datei2 und laden Sie sie in einen Haskell-Interpreter. Testen Sie die
Funktion anschließend mit sinnvollen Werten.
(10 Punkte)
Aufgabe 2 (20 Punkte)
Implementieren Sie in Haskell eine rekursive Funktion, die die Quersumme3 einer natürlichen
Zahl berechnet.
Hinweise:
• In Haskell sind die Operatoren div und mod zur ganzzahligen Division mit Rest bereits
definiert. Hierbei berechnet div den ganzzahligen Anteil und mod den Rest einer solchen
Division.
• Präfix-Operatoren wie z. B. div können in Haskell auch infix verwendet werden, indem
sie in Hochkommas eingeschlossen werden. Z. B. kann (div 9 3) auch als (9 ‘div‘ 3)
geschrieben werden.
Infix-Operatoren wie z. B. + können in Haskell auch präfix verwendet werden, indem sie
in Klammern gesetzt werden. Z.B. kann (3 + 5) auch als (+) 3 5 geschrieben werden.
1
Man kann die Kommandos auch verkürzt eingeben, d.h. z.B. :l statt :load
Haskell-Quelldateien haben die Endung .hs bzw. .lhs, wenn Sie den Literate Haskell-Stil verwenden
3
Die Quersumme einer Zahl ist die Summe ihrer Ziffern.
2
1
Aufgabe 3 (20 Punkte)
Bei der Multiplikation, Division, Addition oder Subtraktion zweier ganzer Zahlen kann das
Ergebnis mithilfe des Neunertests auf Richtigkeit hin überprüft werden. Hierbei berechnet man
jeweils die Quersummen der Ausgangszahlen und des Ergebnisses und wiederholt dieses solange
für jede der entstehenden Zahlen, bis die entstehenden Quersummen einstellige Zahlen sind. Anschließend rechnet man die Zahlen noch modulo 9, d.h. Neunen werden zu Nullen. Die Rechnung
war (wahrscheinlich) richtig, wenn die beiden Reste der Ausgangszahlen miteinander verknüpft
(modulo 9) denselben Rest ergeben wie die Quersumme des Ergebnisses.
Wir betrachten als Beispiel: 9999 + 8888 = 18887. Dann berechnet der Neunertest:
• für 9999: 9+9+9+9 = 36, 3+6 = 9 und 9 modulo 9 = 0
• für 8888: 8+8+8+8 = 32, 3+2 = 5 und 5 modulo 9 = 5
• für 18887: 1+8+8+8+7 = 32, 3+2 = 5 und 5 modulo 9 = 5
Da 0 + 5 = 5, war die Rechnung wahrscheinlich richtig.
Implementieren Sie in Haskell eine Funktion neunertest, die vier Parameter erwartet:
• eine binäre Rechenoperation auf Zahlen, wie (+), (-), (*) und (/),
• zwei Eingabezahlen der Rechenoperation und
• ein Ergebnis der Rechenoperation.
Die Funktion soll nun den Neunertest anhand der Eingaben durchführen und als Ergebnis True
liefern, wenn der Neunertest erfolgreich war; andernfalls sollte sie False liefern.
Aufgabe 4 (25 Punkte)
Es seien folgende Funktionsdefinitionen in Haskell gegeben:
f1
f2
f3
f4
a)
b)
c)
d)
e)
a
a
a
a
b
b
b
b
=
=
=
=
(f1 a (b+1)) ‘mod‘ (f3 a b)
if (f2 (a+3) (b-2)) > (f3 100 b) then f1 (a-1) (b+1) else f2 (a+1) (b-1)
if a+b > 1000 then 20 else f4 a (b*3)
(f3 (a+4) (b-10)) + (f1 (a-1) (b+2))
Für welche Funktionen f, g ∈ {f1, f2, f3, f4} gilt f referenziert g direkt?
Für welche Funktionen f , g ∈ {f1, f2, f3, f4} gilt f referenziert g?
Welche der Funktionen f1, f2, f3 und f4 sind direkt rekursiv?
Welche der Funktionen f1, f2, f3 und f4 sind rekursiv?
Welche Paare der Funktionen f1, f2, f3 und f4 sind verschränkt rekursiv?
(7
(6
(3
(4
(5
Punkte)
Punkte)
Punkte)
Punkte)
Punkte)
Aufgabe 5 (20 Punkte)
Seien f und g definiert als
f x y = 2 + (g x)
g z
= if z >= 20 then 1 else f (4*z) (2+z)
Werten Sie den Ausdruck f (1+(3*3)) (g (5*5)) per Hand in applikativer Reihenfolge aus.
Geben Sie sämtliche Reduktionsschritte sowie die jeweils verwendete Regel als Buchstabe d, i
oder a an, wobei
d: Definitionseinsetzung (δ-Reduktion)
i: Auswertung einer Fallunterscheidung (if-Reduktion)
a: Auswertung von arithmetischen Ausdrücken
2
Herunterladen