Konzepte der Programmierung Programmierkurs 2 Sommer 2017 Universität Konstanz Informatik & Informationswissenschaft M. Grossniklaus, J. Fuchs, L. Wörteler 7. Übungsblatt (Ausgabe: 05. Juni 2017 — Abgabe bis: 12. Juni 2017, 15:00 Uhr) Aufgabe 1 (8 Punkte) Wir betrachten die folgende Funktion: ( x falls x gerade f x := 2 3 · x + 1 falls x ungerade Darauf basierend kann man diese Folge definieren: x0 := x xn+1 := f xn für n ≥ 0 Oder, wenn man f n x für die n-fache Anwendung von f auf x schreibt, xn := f n x. Als 3 · x + 1-Problem oder Collatz-Problem bekannt ist die folgende Fragestellung: Gibt es zu jedem x ∈ N+ ein n ∈ N, sodass xn = 1? Noch einmal in Worten: Wendet man auf eine beliebige positive natürliche Zahl x die Funktion f an, auf das Ergebnis noch einmal f , und immer so weiter, kommt man dann irgendwann beim Wert 1 an? Dieses Problem ist bislang ungelöst, allerdings ist schon für weite Bereiche der natürlichen Zahlen überprüft, dass die Vermutung stimmt1 . Die Aufgabe ist nun, mit den Mitteln von Haskell unter den natürlichen Zahlen zwischen 1 und einer gegebenen Obergrenze n die Zahl zu finden, für die die meisten Anwendungen von f benötigt werden, um auf 1 zu kommen. Diese Anzahl der Schritte soll zusammen mit der zugehörigen Zahl ausgegeben werden, und zwar durch eine Haskell-Funktion maxCollatz :: Integer -> (Integer, Integer) Es ist auf jeden Fall hilfreich, keine große monolithische Funktion zu schreiben, sondern maxCollatz aus einer Reihe von Hilfsfunktionen zusammenzusetzen. Aufgabe 2 (4 Punkte) Schreiben Sie eine Funktion splitWords :: String -> [String] welche eine Zeichenkette an den Whitespace-Zeichen (das seien hier ' ' (space), '\t' (tab), und '\n' (newline)) in einzelne Worte aufspaltet. Beispiel: Main> splitWords " Dies ist eine \t Zeichenkette mit vielen\nLeerzeichen." ["Dies","ist","eine","Zeichenkette","mit","vielen","Leerzeichen."] 1 bei Interesse: Richard K. Guy, Unsolved Problems in Number Theory, New York 1994, Problem E16 1 Aufgabe 3 (3+3(+1) Punkte) Schreiben Sie zwei Funktionen leftTextAlign, blockTextAlign :: Integer -> String -> String Beide bekommen eine Spaltenbreite und einen Eingabestring und sollen als Ausgabe eine Zeichenkette produzieren, die den Text in der vorgegebenen Breite linksbündig, beziehungsweise im Blocksatz formatiert. Je zwei Worte sollen dabei im Ergebnis durch mindestens ein, aber möglichst wenige Leerzeichen getrennt sein. Jede Zeile soll so viele Worte enthalten wie möglich. • In der leftTextAlign-Variante soll jede Zeile linksbündig sein. • In der blockTextAlign-Variante darf das jeweils erste und letzte Zeichen einer Zeile kein Leerzeichen sein, und die Leerzeichen sollen möglichst gleichmäßig zwischen den einzelnen Worten der Zeile verteilt sein. • Sie können (wenn Sie Lust dazu haben; 1 Bonuspunkt) noch geeignete ästhetische Ergänzungen vornehmen: Zum Beispiel ist es schöner, auch bei blockTextAlign die letzte Zeile linksbündig auszurichten. Ist die angegebene Spaltenbreite so klein, dass ein Wort des Textes nicht hineinpasst, oder im Blocksatz nur ein einzelnes Wort in eine Zeile passen würde, so muss die Funktion kein korrektes Ergebnis liefern. Hinweise: Verwenden Sie splitWords aus Aufgabe 2, außerdem können Sie das Aufteilen der Wörter in Zeilen als separates Problem lösen. Zur besseren Ansicht des Ergebnisses kann die Funktion putStr benutzt werden. Beispiel: Main> putStr $ blockTextAlign 30 sampleText Dies ist ein etwas längerer Beispieltext, der dazu dienen soll, die Wirkungsweise der Funktionen blockTextAlign und leftTextAlign zu demonstrieren. Dabei ist das Ergebnis durchaus stark von der vorgegebenen Spaltenbreite abhängig. Main> putStr $ leftTextAlign 60 sampleText Dies ist ein etwas längerer Beispieltext, der dazu dienen soll, die Wirkungsweise der Funktionen blockTextAlign und leftTextAlign zu demonstrieren. Dabei ist das Ergebnis durchaus stark von der vorgegebenen Spaltenbreite abhängig. Aufgabe 4 (2 Punkte) Schreiben Sie eine Funktion safeLast (analog zur Funktion safediv auf Folie 275 ) mit der das letzte Element einer Liste bestimmt werden kann, die aber auf einer leeren Liste keinen Fehler erzeugt.