Übungsblatt aus Übung 3 - Universität des Saarlandes

Werbung
Fachrichtung 6.2 — Informatik
Universität des Saarlandes
Tutorenteam der Vorlesung Programmierung 1
Programmierung 1 (Wintersemester 2015/16)
Aufgaben für die Übungsgruppen: 3
(Kapitel 3)
Hinweis: Dieses Übungsblatt enthält von den Tutoren für die Übungsgruppe erstellte Aufgaben.
Die Aufgaben und die damit abgedeckten Themenbereiche sind für die Klausur weder relevant noch irrelevant.
1
Höherstufigkeit
Höherstufigkeit verstehen
Hinweis: Bearbeiten Sie diesen Abschnitt nur, wenn Sie noch grundlegende Verständnisprobleme zu Höherstufigkeit,
insbesondere zu iter haben. Ansonsten empfehlen wir Ihnen, diese Aufgaben zu überspringen.
Aufgabe 3.1
Sei folgender Code gegeben:
fun f a b = iter a b ( fn x ⇒ x + 1)
Geben Sie ein verkürztes Ausführungsprotokoll für den Aufruf f 4 9 an.
Aufgabe 3.2
Sei folgender Code gegeben:
fun istprim ( n : int ) : bool = ...
fun f a = first a istprim
Dabei liefert istprim genau dann true, wenn die Eingabe n eine Primzahl ist. Geben Sie ein verkürztes
Ausführungsprotokoll für den Aufruf f 14 an.
Aufgabe 3.3
Sei folgender Code gegeben:
fun sum ( f : int → int ) ( n : int ) : int = if n < 1 then 0 else sum f ( n − 1) + f n
fun pluszwei x = x + 2
Geben Sie ein verkürztes Ausführungsprotokoll für den Aufruf sum pluszwei 4 an.
Aufgabe 3.4
Sei folgender Code gegeben:
fun f a b g = iter ( b − a + 1) (a , 0)
( fn (n , x ) ⇒ ( n + 1 , x + ( if g n then 1 else 0)))
(a) Welchen Typ hat f ?
(b) Geben Sie ein verkürztes Ausführungsprotokoll für den Aufruf f 2 5 (fn n ⇒ n mod 2 = 0) an.
Hinweis: Sie dürfen häufig auftretende Codeschnipsel (beispielsweise Abstraktionen, die unverändert als
Argument weitergegeben werden) abkürzen.
1
Höherstufigkeit anwenden
Aufgabe 3.5
(a) Schreiben Sie eine höherstufige Prozedur, die nicht kaskadiert ist.
(b) Schreiben Sie eine kaskadierte Prozedur, die nicht höherstufig ist.
Aufgabe 3.6
Schreiben Sie eine Prozedur quad : int → int, welche mit Hilfe von iter eine Zahl quadriert. Nutzen Sie
dafür keine Multiplikation.
Aufgabe 3.7
Schreiben Sie eine Prozedur double : int → int, welche mit Hilfe von iter eine Zahl verdoppelt. Nutzen Sie
dafür keine Multiplikation
Aufgabe 3.8
Schreiben Sie eine Prozedur gerade: int → bool, die für eine Zahl n prüft, ob sie gerade oder ungerade ist.
Verwenden Sie dazu ausschließlich iter und weder die Operation mod noch div.
Aufgabe 3.9
Deklarieren Sie eine Prozedur aufrundenBitte : int → int, die eine gegebene Zahl auf die nächstgrößere
durch 10 teilbare Zahl aufrundet. Benutzen Sie first, aber keine explizierte Rekursion!
Aufgabe 3.10
Schreiben Sie zwei Prozeduren
cas : ( int * int → int ) → int → int → int
car : ( int → int → int ) → int * int → int
so, dass cas zur kartesischen Darstellung einer zweistelligen Operation die kaskadierte Darstellung und car zur
kaskadierten Darstellung die kartesische Darstellung liefert. Erproben Sie cas und car mit einem Interpreter!
Aufgabe 3.11
Schreiben Sie eine Prozedur summe: int * int → int, die zu zwei gegebenen natürlichen Zahlen m und n
(wobei m < n) die Summe (m + 1) + (m + 2) + (m + 3) + ... + (n − 1) berechnet. Verwenden Sie hierzu:
(a) iterup
(b) iterdn
(c) iter
Aufgabe 3.12
Schreiben Sie eine Prozedur kubik: int → int, die die erste Kubikzahl bestimmt, die strikt größer ist als eine
Eingabe n.
Aufgabe 3.13
Schreiben Sie eine Prozedur count: (int → bool) → int → int → int, die zählt, wie oft eine übergebene
Prozedur predicate zwischen zwei Zahlen min und max (jeweils inklusive) true liefert.
Aufgabe 3.14
(a) Schreiben Sie eine Prozedur quer: int → int, die zu einer gegebenen ganzen Zahl n die Quersumme
berechnet. Verwenden Sie iter.
Hinweis: Sie benötigen eine Hilfsprozedur stell: int → int, die Ihnen die Stelligkeit einer Zahl berechnet.
(b) Implementieren Sie nun eine Prozedur equalquer: int → int, die zu einer gegebenen natürlichen Zahl
n die kleinste natürliche Zahl berechnet, deren Quersumme gleich der Quersumme von n ist.
2
Aufgabe 3.15 (Primzahlen I )
Geben Sie einen Ausdruck vom Typ int → int an, der zu einer Eingabe n > 2 die größte Primzahl liefert, die
echt kleiner ist als n. Nehmen Sie eine Prozedur istprim: int → bool, die genau dann true liefert, wenn ihre
Eingabe prim ist, als gegeben an.
Aufgabe 3.16 (k-Fibonacci)
(a) Schreiben Sie eine Prozedur fib3: int → int, die die n-te 3-Fibonacci-Zahl berechnet, d. h. die drei
Vorgänger werden addiert. Die definierenden Gleichungen lauten:
f ib3 n = 0
n<3
f ib3 n = 1
n=3
f ib3 n = f ib3 (n − 1) + f ib3 (n − 2) + f ib3 (n − 3)
n>3
Die Folge beginnt wie folgt: 0, 0, 0, 1, 1, 2, 4, 7, 13, 24, . . .
(b) Zeichnen Sie den Rekursionsbaum für n = 6.
(c) Geben Sie ein verkürztes Ausführungsprotokoll für fib3 5 an.
(d) Schreiben Sie eine Prozedur fibk: int → int → int, welche mithilfe von iterup die n-te k-FibonacciZahl berechnet.
Für die n-te k-Finbonacci-Zahl werden die k Vorgänger addiert, wenn n > k. Für alle n < k soll gelten:
fibk n = 0. Für n = k ist fibk n = 1.
Aufgabe 3.17 (Primzahlen II )
Schreiben Sie eine Prozedur istprim: int → bool, die entscheidet, ob eine Zahl n ≥ 2 eine Primzahl ist.
j nk
Hinweis: Wann gilt n =
· k? Wie können Sie diese Gleichung mit first ausnutzen?
k
2
Typinferenz
Aufgabe 3.18
Geben Sie Deklarationen an, welche die folgenden Bezeichner monomorph typen:
(a) a: (bool → real) * int * bool
(b) b: unit → unit
(c) c: (bool * int * bool → int) → bool * int * bool → int
(d) d: unit → real → bool
(e) e: (int * int → bool) → real
Verzichten Sie dabei auf explizite Typangaben und verwenden Sie keine Operator- und Prozeduranwendungen.
Aufgabe 3.19
Bestimmen Sie das Typschema folgender Prozeduren:
(a) fun f a b = a b b
(b) fun f a b c = a b c
(c) fun f a b c = a (b c)
(d) fun f a (b, c) = (a b, a c, a b c)
(e) fun f (a, b, c) d = if c then (a+4)=b else d (true)
(f) fun f (a,b,c,d) = if a<3 then b else if c=d then 5.3 else 3.8
(g) fun f a b (c,d) = let val e=(a b) in if c then d else d+2 end
3
(h) fun f a (b, c) d = a (b (c d) c a)
(i) fun f a (b,c) d (e,f) = a (f e) ((a b) (c d))
Aufgabe 3.20
Gegeben sei folgendes Programm:
fun f x y = x = y
fun g x h = fn y ⇒ let val a = f x val b = h in b a y end
(a) Geben Sie jeweils das Typschema von f und g an.
(b) Überprüfen Sie Ihre Lösung mit dem Interpreter.
Aufgabe 3.21
Geben Sie jeweils eine Prozedur mit dem gegebenen Typschema an, ohne dabei explizite Typangaben zu machen.
(a) bool → int → int
(b) int → α → β → bool
(c) (α → β → γ) → (β → α) →β → γ
(d) ’α → ’α → β → (β → β) → β
(e) α → (β → γ) → (α → β) → γ
(f) α → β → (α → β) → (bool → γ) → γ
(g) α → (α → α) → α
(h) ((α → β) → γ) → β → γ
(i) ((α → β → α) → γ) → (δ → α) → δ → γ
(j) α → (β → α) → α
(k) α → (β → α → γ) → (β → γ) * (α → α)
(l) α → (α → β) → (int → α) * β
(m) (α → β) → (α → γ) → α → β * (α → γ) * γ * (bool → γ)
(n) (bool → α) → ’β → (α * ’β → ’β * γ) → γ → ’β
(o) (bool → bool) → α → β → γ → (β * γ → (bool → bool) * γ) → bool
Aufgabe 3.22
Gibt es ein Typschema, für das sich keine Prozedur mit diesem Typschema finden lässt?
3
Bezeichnerbindung
Aufgabe 3.23
Gegeben sei die folgende Prozedurdeklaration:
fun g x y = (fn x ⇒ let val x = f x val y = g x y in x + y end) x
Bereinigen Sie die Prozedurdeklaration: Überstreichen Sie die definierenden Bezeichnerauftreten, stellen Sie die
lexikalischen Bindungen mit Pfeilen dar und benennen Sie konsistent die gebundenen Bezeichner um.
4
Herunterladen