3.¨Ubungsblatt - informatik.uni

Werbung
Praktische Informatik 3 WS 2009/10
3. Übungsblatt
Ausgabe: 12.11.2009
Abgabe: 26.11.2009
Berthold Hoffmann <hof>
Dominik Dietrich <dodi>
Christian Maeder <maeder>
Julia Seiter <jseiter>
Jasper van de Ven <jasper>
Spaß ist Spaß, und Ernst ist Ernst. Und Fußball ist todernst! Nur weil der Server, mit dem
die Spielpläne der Fußball-Bundesliga erstellt werden, abgeraucht ist und die Quellen der
Cobol-Programme, mit denen sie erstellt wurden, nicht mehr zu rekonstruieren sind, droht
die Bundesliga-Rückrunde ins Wasser zu fallen!
In Haskell lässt sich so ein Plan zum Glück schnell errechnen.
6 Spielpläne erstellen
5 Punkte
Entwickeln Sie ein Programm, mit dem ein Spielplan für eine Liga mit einer geraden Anzahl
n > 0 von Mannschaften erstellt wird. Repräsentieren Sie die Mannschaften durch Zahlen
von 0 bis n − 1.1
Ein Spieltag ist eine Liste von Paaren, in der jede Mannschaft genau einmal vorkommt. Dabei
steht ein in Paar (i, j) für ein Heimspiel der Mannschaft i gegen die Gastmannschaft j.
Ein Spielplan ist eine Liste von Spieltagen, in dem jede Mannschaft genau einmal gegen jede
andere antritt und jede Mannschaft nicht mehr als n ÷ 2 Heim- oder Auswärtsspiele hat.
Die Paarungen werden durch Rotation wie folgt bestimmt: Der erste Spieltag besteht aus
den Paarungen:
H
G
H
...
...
0
1
2
... n÷ 2 −1
n− 1 n− 2 n −3 ...
n÷2
Die Buchstaben H und G in der ersten Zeile geben an, ob die Teams in der zweiten Zeile
Heimrecht oder Gastrecht haben. Die oben genannten Mannschaften haben also abwechselnd
Heimrecht bzw. Gastrecht. Als Tupel wird also eine Spalte H i j als (i, j) und eine Spalte
G i j als (j, i) dargestellt. Der erste Spieltag soll berechnet werden mit einer Funktion
day :: Int → [(Int,Int)]
Rotiert wird ein Spieltag wie folgt:
1. Team n − 1 bleibt an der gleichen Stelle (links unten).
2. In allen anderen Stellen der Tabelle wird Team i durch Team i + 1‘mod‘(n − 1) ersetzt.
3. In der ersten Spalte ändert sich bei einer Rotation Heim- zu Gastrecht oder umgekehrt.
4. In allen anderen Spalten bleibt das Heim- bzw. Gastrecht unverändert.
Der zweite Spieltag sieht also wie folgt aus:
G
G
H
...
...
1
2
3
...
n÷2
n −1 0 n −2 ... n÷ 2+ 1
1
Dahinter steht die kaufmännische Hoffnung, dass auch die Server für die Spielplanberechnungen in den
Handball-, Basketball- und Eishockeyligen irgend wann einmal ihren Geist aufgeben werden und Sie dann
auch für n 6= 18 schnell eine Lösung anbieten können.
Die Rotation soll berechnet werden mit einer Funktion
nextDay :: [(Int,Int)] → [(Int,Int)]
Den Spielplan für eine Hin- oder Rückrunde mit n − 1 Spieltagen erhält man durch n − 2
Rotationen des ersten Spieltags:
plan :: Int → [[(Int,Int)]]
Dies ergibt eine abstrakte Funktion für das Erstellen von Spielplänen mit einer geraden
Anzahl n von Mannschaften.
7 Der Bundesliga-Spielplan
5 Punkte
Nun geht es darum, aus der abstrakten Planung einen schön gedruckten Spielplan für die
Bundesliga zu erstellen.2 Erstellen Sie eine Liste theTeams ::Teams, in der die Namen aller
Bundesligavereine enthalten sind, wobei Teams folgendes Typsynonym ist:
type Teams = [String]
Implementieren Sie nun eine Funktion theFinalPlan ::Teams →String, die für die Mannschaften einen Plan erstellt und formatiert ausgibt. Die Anzahl n der Mannschaften lässt
sich aus der Liste berechnen – ist sie ungerade, soll eine Mannschaft "-- spielfrei --"
hinzugefügt werden.
Definieren Sie für die Formatierung folgende Funktionen:
1. Die Funktionen theHomeTeam, theGuestTeam ::Int →String →String formatieren Heimmannschaften linksbündig und Gastmannschaften rechtsbündig in einer Zeichenkette der Länge b (dem ersten Argument).
2. Die Funktion theMatch ::Int →Teams →(Int,Int) →String formatiert eine Paarung; dabei steht die Heimmannschaft vorne.
3. Die Funktion theDay ::Int → Teams →[(Int,Int)] →String formatiert einen Spieltag (mit abschließender Leerzeile, ggf. auch mit Überschrift).
4. Die Funktion thePlan ::Int →Teams →[[(Int,Int)]] →String formatiert den Spielplan.
Tipps für die Implementierung:
1. Die Funktion (!!) :: [a] → Int → a selektiert das Elemente einer Liste ℓ mit den
Indices 0 . . . (length ℓ) − 1.
2. Benutzen die Bibliotheksfunktion unlines ::[String] →String, um eine Liste von
Zeichenketten in eine Zeichenkette mit Zeilenwechseln umzuwandeln.
3. Die Aktion putStrLn ::String →IO() gibt – als zuletzt aufgerufene Funktion eines
Ausdrucks – eine Zeichenkette mit Zeilenwechseln und ohne die Gänsefüßchen aus.
[Die Idee zu dieser Aufgabe ist von Christian Maeder.]
Dies ist Fassung 2 vom 10. November 2009.
2
Fans anderer Fußballligen oder anderer Mannschaftssportarten dürfen statt dessen auch andere Spielpläne errechnen.
Herunterladen