Informatik A

Werbung
Lösungen zum 4. Aufgabenblatt zur Vorlesung
Informatik A
(Autor: Sascha Meiers)
1. Einfaches Haskell
Die Lösung wurde freundlicherweise bereitgestellt von M. Can und L. Thomas.
threeDiff :: Int -> Int -> Int -> Bool
threeDiff a b c = a /= b && a /= c && b /= c
-- Die Funktion ist nur dann True, falls a /= b, a /= c und b /= c gilt.
threeEqual :: Int -> Int -> Int -> Bool
threeEqual a b c = a == b && b ==c
-- Die Funktion ist nur dann True, falls a = b = c gilt.
howManyDiff :: Int -> Int -> Int -> Int
howManyDiff a b c
| threeDiff a b c = 3
| threeEqual a b c = 1
| otherwise = 2
2. Klammerung testen
(a) Schreiben Sie eine Funktion klammerTest :: String -> Bool, die testet, ob die
in einem Eingabestring vorkommenden öffnenden und schließenden runden Klammern 0 (0 bzw. 0 )0 einen korrekten Klammerausdruck bilden. Korrekte Klammerausdrücke sind dadurch gekennzeichnet, dass in jedem Präfix (Anfangsstück) des
Strings mindestens so viele öffnende wie schließende Klammern auftreten und insgesamt es gleich viele öffnende und schließende Klammern gibt. Definieren Sie ggf.
geeignete Hilfsfunktionen.
Lösung:
Die Lösung wurde freundlicherweise bereitgestellt von B. Jeschke und M.
Möllenberg. Sie beruht auf einem Int, der mit dem String übergeben wird und
die Differenz der Zahl der öffnenden und der Zahl der schließenden Klammern speichert. Dieser muss am Ende 0 sein (# schließende Klammern = # öffnende Klammern) und darf zwischendurch nicht unter 0 sinken (mindestens soviele öffnende
wie schließende Klammern in jedem Präfix des Strings).
klammerTest :: String -> Bool
klammerTest a = test a 0
test :: String -> Int -> Bool
test [] n = n == 0
test (x:xs) n
|
|
|
|
n < 0 = False
x == ’(’ = test xs (n+1)
x == ’)’ = test xs (n-1)
otherwise = test xs n
-----
Falls n<0 soll er sofort abbrechen
n wird 1 hochgezählt
n wird 1 runtergezählt
arbeite mit dem Rest weiter
(b) Die Menge der korrekt geklammerten, nichtleeren Wörter über dem Alphabet
Σ = {x1 , ..., xn , (, )} ist die Menge derjenigen Wörter, die sich durch endlich oftes Anwenden der folgenden Regeln erzeugen lassen.
i. Jeder einzelne Buchstabe aus {x1 , ..., xn } sowie das Wort () sind korrekte
Klammerausdrücke.
ii. Falls t ein korrekter Klammerausdruck ist, dann ist auch (t) ein k. KA.
iii. Falls t1 und t2 korrekte KA.sind, dann ist auch die Konkatenation t1 ◦ t2 ein
korrekter KA.
3. Rechtecke testen Ein achsenparalleles Rechteck in der Ebenen kann repräsentiert
werden durch die Angabe von 4 Gleitkommazahlen. Die ersten beiden werden interpretiert als die x–y–Koordinaten der linken unteren Ecke, die beiden anderen als Koordinaten der rechten oberen Ecke. Schreiben Sie ein Haskell–Skript Rectangle.hs oder
Rectangle.lhs, das mindestens die Definitionen folgender Funktionen enthalten soll.
Geben Sie jeweils auch die Signatur der Funktionen an.
(a) Die Funktion isRectangle überprüft, ob die vier Zahlen tatsächlich ein Rechteck
mit nichtleerer Fläche definieren.
(b) Die Funktion areaBBox berechnet die Fläche der sogenannten bounding box der
zwei Rechtecke, also des kleinsten achsenparallelen Rechtecks, das beide enthält.
(c) Die Funktion isContained überprüft von zwei Rechtecken, ob eines davon im
anderen völlig enthalten ist. Eine Möglichkeit ist es, auf die Funktion areaBBox
zuzugreifen. Wie?
Lösung: Die Lösung wurde freundlicherweise bereitgestellt von H. Velkov. Bei der
isRectangle-Funktion galt zu beachten, dass das erste Argument die linke untere Ecke
des Rechtecks beschreiben soll.
type Point = (Float, Float)
type Rectangle = (Point, Point)
isRectangle :: Point -> Point -> Bool
isRectangle (a,b) (c,d)
| (c > a) && (d > b) = True
| otherwise
= False
areaBBox :: Rectangle -> Rectangle -> Float
areaBBox ((a,b),(c,d)) ((e,f),(g,h))
| (isRectangle (a,b) (c,d) == False ) ||
(isRectangle (e,f) (g,h) == False )
= error "Keine richtigen Rechtecken vorhanden"
| otherwise
= (maximum [c,g] - minimum [a,e]) * (maximum [d,h] - minimum [b,f])
{- Solange wir richtige Rechtecken haben, berechnen wir die Flaeche als
Produkt des maximalen horizontalen Abstandes zwischen den Ecken und
des maximalen vertikalen Abstandes. Diese Maxima werden jeweils von
einem Paar bestehend aus rechter oberer Ecke und linker unterer Ecke
realisiert-}
isContained :: Rectangle -> Rectangle -> Bool
isContained ((a,b),(c,d)) ((e,f),(g,h))
| (areaBBox ((a,b),(c,d)) ((e,f),(g,h)) == (c-a)*(d-b)) ||
(areaBBox ((a,b),(c,d)) ((e,f),(g,h)) == (g-e)*(h-f)) = True
| otherwise
= False
{- Wenn die Fläche der bounding box der zwei Rechtecke gleich der Flaeche
von einem der beiden ist, dann ist das eine in dem anderen enthalten-}
Herunterladen