Tobias Friedrich, Anton Krohmer Wintersemester 15/16 Übungsblatt 1 – Theoretische Informatik I Abgabe 19.10.2015 vor der Vorlesung, im Vorlesungsraum Es gibt wöchentlich ein Übungsblatt bestehend aus Vorbereitung, Übungsaufgaben und Knobelaufgaben. Vorbereitung: Die Vorbereitung wird in der kommenden Woche in der Vorlesung vorausgesetzt und darauf aufgebaut. Um der Vorlesung folgen zu können, ist es erforderlich, alle Vorbereitungen im Vorfeld zu bearbeiten. Zu Beginn jeder Vorlesung können Fragen zu der Vorbereitung gestellt werden. Übungsaufgaben: Die Übungsaufgaben stellen herkömmliche Aufgaben dar und festigen gelerntes Wissen. Zur Klausurzulassung sind 50% der erreichbaren Punkte der ersten Vorlesungshälfte und 50% der zweiten Vorlesungshälfte zu erreichen. Überschüssige Punkte können nicht in die zweite Vorlesungshälfte übertragen werden. Knobelaufgaben: Die Knobelaufgaben stellen besonders kniffelige Herausforderungen dar. Meistens muss man um mehrere Ecken denken und das ganze vorhandene Wissen anwenden. Korrekt gelöste Knobelaufgaben bringen Bonuspunkte für die jeweils kommende Klausur. Es gibt pro Woche einen Pool von höchstens 10 Punkte für alle Studierenden. Sollten mehr als 10 die Aufgaben lösen, werden die Punkte gleichmäßig unter ihnen aufgeteilt. (Lösen zB. 80 Leute die Aufgabe, bekommt jeder 1 Punkte.) 8 Generell gilt: Schreiben Sie auf Ihre Abgabe Ihren Namen, und zu welcher Übungsgruppe Sie gehen. Alle Antworten müssen nachvollziehbar sein. Begründen Sie daher Ihre Ergebnisse und schreiben Sie strukturierte Beweise. Vorbereitung. Machen Sie sich mit der While-Sprache vertraut. Arbeiten Sie dazu alle 3 Seiten der Unit unter https://hpi.de/friedrich/teaching/units/ while-language.html durch. 1 Theoretische Informatik I Tobias Friedrich, Anton Krohmer Aufgabe 1. (4 Punkte) Geben Sie While-Programme für die folgenden zwei Funktionen an. Sie dürfen (und sollen!) bekannten syntaktischen Zucker benutzen. (x, y) → 7 x DIV y; (x, y) → 7 x MOD y. (1) (2) Hierbei sind DIV und MOD die Division und der Modulo-Operator so dass für alle x, y gilt (x DIV y) · y + (x MOD y) = x. Zum Beispiel gilt 15 DIV 7 = 2 und 15 MOD 7 = 1. Aufgabe 2. (6 Punkte) In dieser Aufgabe wollen wir uns eine Paarbildungsfunktion herleiten. Effektiv kann man damit zwei beliebige Zahlen n1 , n2 ∈ N in nur einer While-Variable xi speichern. Wir wollen also While-berechenbare Funktionen pair, first und second schreiben, sodass für alle Zahlen n1 , n2 ∈ N gilt first(pair(n1 , n2 )) = n1 und second(pair(n1 , n2 )) = n2 . (a) (1 Punkt) Überlegen Sie sich zwei Prozeduren (in Pseudocode, nicht in While) cod und doc mit den folgenden Eigenschaften. Die Prozedor cod nimmt 2 Strings und gibt einen String zurück. Die Prozedur doc nimmt einen String und gibt zwei Strings zurück. Schreiben Sie die Prozeduren so, dass für alle Strings s1 , s2 gilt doc(cod(s1 , s2 )) = (s1 , s2 ). (b) (2 Punkte) Geben Sie eine injektive Funktion f : N2 → N an, und beweisen Sie die Injektivität. Argumentieren Sie, wieso Ihre Funktion While-berechenbar ist. Sie erhalten 1 Punkt für eine formale, mathematische Beschreibung von f . (c) (2 Punkte) Geben Sie die Umkehrfunktion f −1 : N → N2 an. Argumentieren Sie, wieso Ihre Funktion While-berechenbar ist. Sie erhalten 1 Punkt für eine formale, mathematische Beschreibung von f −1 . (2 Punkte) (d) (1 Punkt) Zeigen Sie, dass die Menge der rationalen Zahlen gleich mächtig ist zur Menge der natürlichen Zahlen, also dass |Q| = |N|. Zur Erinnerung: Für 2 Mengen A, B gilt |A| ≤ |B|, falls es eine injektive Funktion g : A → B gibt. (e) (1 Bonuspunkt) Geben Sie eine bijektive Funktion f : N2 → N und zeigen Sie deren Bijektivität. 2 Theoretische Informatik I Tobias Friedrich, Anton Krohmer Aufgabe 3. (6 Punkte) Ein Stack ist eine Datenstruktur, in welcher Objekte gespeichert werden können. In unserem Fall sind diese Objekte natürliche Zahlen n ∈ N. Auf einem Stack können drei Operationen ausgeführt werden: push(x, S) legt ein Element x “auf” den Stack S. pop(S) nimmt ein Element von dem Stack S herunter und gibt es zurück. isempty(S) prüft, ob der Stack S leer ist und gibt dementsprechend entweder 1 oder 0 zurück. In dieser Aufgabe wollen wir einen Stack in While implementieren. Sie dürfen (und sollen!) bekannten syntaktischen Zucker benutzen. (a) (1 Punkt) Beschreiben Sie, wie man einen Stack von natürlichen Zahlen n1 , . . . , ni ∈ N in einer einzigen natürlichen Zahl n speichern kann. Gehen Sie dabei darauf ein, wie ein leerer Stack dargestellt wird. (b) (2 Punkte) Implementieren Sie die push(x, S) Operation in While. (c) (2 Punkte) Implementieren Sie die pop(S) Operation in While. (d) (1 Punkt) Implementieren Sie die isempty(S) Operation in While. Knobelaufgabe. (1 Klausurpunkt) Sei S eine beliebige Menge. Wir definieren 2S := {T | T ⊆ S}. Zeigen Sie, dass |2S | |S|. 3