FB Informatik LS I – Funktionale Programmierung – Prof. Dr. P. Padawitz Christian Bockermann, Hubert Wagner Übungen zur Vorlesung Funktionale Programmierung Wintersemester 2007/08 Probeklausur Keine Abgabe Aufgabe 0.1 Wir betrachten endliche Bäume, deren Knoten mit Elementen vom Typ a markiert sind und deren Knoten auch beliebig viele Söhne haben können. 1. Geben Sie den Datentyp FinTree a für solche Bäume an. 2. Schreiben Sie eine Haskell-Funktion f , die zu einem Baum t vom Typ FinTree a einen Baum f t mit der gleichen Struktur, aber vom Typ FinTree Integer, berechnet, so dass jeder Knoten p in f t mit der Anzahl der Knoten des Unterbaumes mit Wurzel p markiert ist. Aufgabe 0.2 1. Geben Sie eine Haskell-Funktion sit :: Int -> String -> String an, die bei Eingabe der ganzen Zahl n > 0 und des Strings x den String x . . x} berechnet. | .{z n mal 2. Mit Hilfe welcher Funktion kann man aus der Liste [x1 , . . . , xn ] ∈ [String] die Liste [(1, x1 ) , . . . , (n, xn )] erzeugen? 3. Zeigen Sie nun, wie man unter Verwendung von foldl zu der Liste [x1 , . . . , xn ] den String x1 x2 x2 x3 x3 x3 . . . xn . . . xn | {z } n mal berechnet. Aufgabe 0.3 Schreiben Sie eine Haskell- Funktion, die angewandt auf eine Funktion f :: Integer -> Integer das folgende, in Pseudo-Code beschriebene Verhalten zeigt: x := 0 read n while x <= n do print (f x) read i x := x + i Aufgabe 0.4 Teilbarkeit Über den euklidischen Algorithmus läßt sich auf effiziente Weise der größte gemeinsame Teiler zweier natürlicher Zahlen finden. Nachfolgend finden sie den Algorithmus in iterativer Form in Pseudo-Code Notation. Implementieren Sie den Algorithmus in Haskell. EUCLID (a, b) SOLANGE b != 0 h := a mod b a := b b := h RETURN a Aufgabe 0.5 Arithmetischer Parser In der Vorlesung und den Übungen wurde ein arithmetischer Parser implementiert, der einen Ausdruck bestehend aus ganzen Zahlen und den Operationen “*” und “+” evaluiert. • Erweitern Sie den Parser um die Operationen “-” und “/”, wobei “/” die ganzzahlige Division darstellt. (15 Punkte) • Erweitern die den Parser um die Möglichkeit, auch Dezimalzahlen in der normalen Dezimalschreibweise zu evaluieren. (15 Punkte) Aufgabe 0.6 Newton-Verfahren (30 Punkte) Mit Hilfe des Newtonschen Approximationsverfahrens lassen sich Lösungen nicht-linearer Gleichungen numerisch bestimmen. Die Quadrat-Wurzel einer Zahl a ist dabei gerade die Nullstelle der Funktion f (x) = 1 − a x2 Die Newton-Iterationen erfolgen gemäß der Vorschrift xn+1 = xn x2 (3 − n ) 2 a Geben Sie eine Haskell-Funktion wurzel :: Float -> Int -> Float an, die für zwei Zahlen a ∈ R und n ∈ N das Ergebnis der n-ten Iteration berechnet. Aufgabe 0.7 Der Quicksort-Algorithmus läßt sich auf Listen anwenden, deren Elemente vom Typ Ord sind. Eine Verallgemeinerung des Algortihmus mit Hilfe einer Funktion compare :: a -> a -> Bool ist durch die folgende Implementierung gegeben: qsort:: ( a -> a -> Bool ) -> [ a ] -> [ a ] qsort cmp [] = [] qsort cmp (x:xs) = qsort cmp smaller ++ [ x ] ++ qsort cmp larger where smaller = [ a | a <- xs, cmp a x ] larger = [ b | b <- xs, not ( cmp b x ) ] Geben Sie eine Vergleichsfunktion compare :: String -> String -> Bool an die für zwei Strings die Anzahl der Kleinbuchstaben vergleicht. Der String mit weniger Kleinbuchstaben soll in der durch cmp implizierten Ordnung vor dem String mit mehr Kleinbuchstaben stehen. Bei gleicher Anzahl der Kleinbuchstaben soll die lexikographische Ordnung angewendet werden. Aufgabe 0.8 Die Eulersche ϕ-Funktion liefert für eine natürliche Zahl n die Anzahl aller Zahlen i = 1, . . . , (n− 1), die zu n teilerfremd sind. 1. Geben Sie eine Haskell-Funktion teilerFremd :: Int -> [Int] an, die für eine natürliche Zahl n die Liste aller natürlicher Zahlen < n liefert, die teilerfremd zu n sind. 2. Geben Sie eine Haskell-Funktion ephi :: Int -> Int an, die die Eulersche ϕ-Funktion berechnet. Aufgabe 0.9 Eine Multimenge M ist eine Menge, in der Elemente mehrfach vorkommen können. Diese Eigenschaft bieten in Haskell auch Listen. Für eine kompatke Darstellung von Multimengen soll eine Multimenge im Folgenden als Liste von Tupeln [(a,Int)] dargestellt werden, wobei die zweite Komponente die Anzahl der Vorkommnisse eines Objektes repräsentiert. Implementieren Sie eine Haskell-Funktion compress :: [a] -> [(a,Int)], die für eine Liste die kompakte Darstellung der Liste als Multimenge zurückliefert.