diff --git a/documents/Programmierparadigmen/Haskell.tex b/documents/Programmierparadigmen/Haskell.tex index 33d9c44..0ea4527 100644 --- a/documents/Programmierparadigmen/Haskell.tex +++ b/documents/Programmierparadigmen/Haskell.tex @@ -173,7 +173,7 @@ erzeugt werden: \inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/data-example.hs} -\section{Lazy Evaluation}\xindex{Lazy Evaluation} +\section{Lazy Evaluation}\xindex{Lazy Evaluation}% Haskell wertet Ausdrücke nur aus, wenn es nötig ist. \begin{beispiel}[Lazy Evaluation] @@ -182,9 +182,6 @@ Haskell wertet Ausdrücke nur aus, wenn es nötig ist. \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=lazy-evaluation.hs]{haskell}{scripts/haskell/lazy-evaluation.hs} \end{beispiel} -Ein spezialfall der Lazy-Evaluation ist die sog. \textit{Kurzschlussauswertung}.\xindex{Kurzschlussauswertung}\xindex{Short-circuit evaluation} -Das bezeichnet die Lazy-Evaluation von booleschen Ausdrücken. - \section{Beispiele} \subsection{Quicksort} \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=qsort.hs]{haskell}{scripts/haskell/qsort.hs} @@ -205,6 +202,7 @@ sich das ganze sogar noch kürzer schreiben: \subsection{Fibonacci}\xindex{Fibonacci} \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci.hs]{haskell}{scripts/haskell/fibonacci.hs} \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-akk.hs]{haskell}{scripts/haskell/fibonacci-akk.hs} +\xindex{zipWith} \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-zip.hs]{haskell}{scripts/haskell/fibonacci-zip.hs} \inputminted[linenos, numbersep=5pt, tabsize=4, frame=lines, label=fibonacci-pattern-matching.hs]{haskell}{scripts/haskell/fibonacci-pattern-matching.hs} @@ -219,7 +217,7 @@ TODO \subsection{Standard Prelude} Hier sind die Definitionen eininger wichtiger Funktionen: - +\xindex{zipWith}\xindex{zip} \inputminted[numbersep=5pt, tabsize=4]{haskell}{scripts/haskell/standard-definitions.hs} \section{Weitere Informationen} diff --git a/documents/Programmierparadigmen/Lambda.tex b/documents/Programmierparadigmen/Lambda.tex index 9ea83d2..1ad6a5f 100644 --- a/documents/Programmierparadigmen/Lambda.tex +++ b/documents/Programmierparadigmen/Lambda.tex @@ -102,7 +102,9 @@ Die Funktionsapplikation sei linksassoziativ. Es gilt also: Die Call-By-Name Auswertung wird in Funktionen verwendet. -Haskell verwendet die Call-By-Name Auswertungsreihenfolge zusammen mit \enquote{sharing}. Dies nennt man Lazy Evaluation. +Haskell verwendet die Call-By-Name Auswertungsreihenfolge zusammen mit \enquote{sharing}. Dies nennt man \textit{Lazy Evaluation}. Ein spezialfall der Lazy-Evaluation ist die sog. \textit{Kurzschlussauswertung}.\xindex{Kurzschlussauswertung}\xindex{Short-circuit evaluation} +Das bezeichnet die Lazy-Evaluation von booleschen Ausdrücken. + \todo[inline]{Was ist sharing?} \begin{definition}[Call-By-Value]\xindex{Call-By-Value}% diff --git a/documents/Programmierparadigmen/Logik.tex b/documents/Programmierparadigmen/Logik.tex index 321f6eb..18e3013 100644 --- a/documents/Programmierparadigmen/Logik.tex +++ b/documents/Programmierparadigmen/Logik.tex @@ -82,7 +82,7 @@ Damit sind alle Ausdrücke unserer Sprache festgelegt. Ist zum Beispiel $f$ ein ein Ausdruck, da er sich durch Anwendung obiger Regeln aufbauen lässt. Es sei noch einmal darauf hingewiesen, dass wir die Ausdrücke mittels der genannten Regeln rein mechanisch erstellen, ohne dass die Ausdrücke zwangsläufig irgendetwas bezeichnen müssten. \subsection{1. Stufe} -Unterschiedliche Sprachen erster Stufe unterscheiden sich lediglich in den Mengen $\mathcal C$, $\mathcal F$ und $\mathcal R$, die man üblicherweise zur Symbolmenge $S$ zusammenfasst und auch die \textit{Signatur} der Sprache nennt. Man spricht dann auch genauer von $S$-Termen bzw. $S$-Ausdrücken. Die Sprache, das heißt die Gesamtheit aller nach obigen Regeln gebildeten Ausdrücke, wird mit $L(S)$, $L^S$ oder $L_I^S$ bezeichnet. Bei letzterem steht die römische $I$ für die 1-te Stufe. Dies bezieht sich auf den Umstand, dass gemäß letzter Erzeugungsregel nur über Variable quantifiziert werden kann. $L_I^S$ sieht nicht vor, über alle Teilmengen einer Menge oder über alle Funktionen zu quantifizieren. So lassen sich die üblichen [[Peano-Axiome]] nicht in $L_I^S$ ausdrücken, da das Induktionsaxiom eine Aussage über alle Teilmengen der natürlichen Zahlen macht. Das kann als Schwäche dieser Sprache angesehen werden, allerdings sind die Axiome der [[Zermelo-Fraenkel-Mengenlehre]] sämtlich in der ersten Stufe mit dem einzigen Symbol $\in$ formulierbar, so dass die erste Stufe prinzipiell für die Mathematik ausreicht. +Unterschiedliche Sprachen erster Stufe unterscheiden sich lediglich in den Mengen $\mathcal C$, $\mathcal F$ und $\mathcal R$, die man üblicherweise zur Symbolmenge $S$ zusammenfasst und auch die \textit{Signatur} der Sprache nennt. Man spricht dann auch genauer von $S$-Termen bzw. $S$-Ausdrücken. Die Sprache, das heißt die Gesamtheit aller nach obigen Regeln gebildeten Ausdrücke, wird mit $L(S)$, $L^S$ oder $L_I^S$ bezeichnet. Bei letzterem steht die römische $I$ für die 1-te Stufe. Dies bezieht sich auf den Umstand, dass gemäß letzter Erzeugungsregel nur über Variable quantifiziert werden kann. $L_I^S$ sieht nicht vor, über alle Teilmengen einer Menge oder über alle Funktionen zu quantifizieren. So lassen sich die üblichen [[Peano-Axiome]] nicht in $L_I^S$ ausdrücken, da das Induktionsaxiom eine Aussage über alle Teilmengen der natürlichen Zahlen macht. Das kann als Schwäche dieser Sprache angesehen werden, allerdings sind die Axiome der Zermelo-Fraenkel-Mengenlehre sämtlich in der ersten Stufe mit dem einzigen Symbol $\in$ formulierbar, so dass die erste Stufe prinzipiell für die Mathematik ausreicht. \subsection{Freie Variablen} Weitere Eigenschaften von Ausdrücken der Sprache $L_I^S$ lassen sich ebenfalls rein syntaktisch definieren. Gemäß dem oben beschriebenen Aufbau durch Bildungsregeln definieren wir die Menge $\mathrm{frei}(\varphi)$ der im Ausdruck $\varphi$ frei vorkommenden Variablen wie folgt: diff --git a/documents/Programmierparadigmen/Programmierparadigmen.pdf b/documents/Programmierparadigmen/Programmierparadigmen.pdf index 5946c77..77ccc3c 100644 Binary files a/documents/Programmierparadigmen/Programmierparadigmen.pdf and b/documents/Programmierparadigmen/Programmierparadigmen.pdf differ diff --git a/documents/Programmierparadigmen/Programmiertechniken.tex b/documents/Programmierparadigmen/Programmiertechniken.tex index b989231..6f1998e 100644 --- a/documents/Programmierparadigmen/Programmiertechniken.tex +++ b/documents/Programmierparadigmen/Programmiertechniken.tex @@ -113,7 +113,18 @@ Wenn eine rekursive Funktion nicht terminiert oder wenn \index{Rekursion|)} \section{Backtracking} \index{Backtracking|(} +Unter \textit{Backtracking} versteht man eine Programmiertechnik, die +(eventuell implizit) auf einem Suchbaum arbeitet und mittels Tiefensuche versucht +eine Lösung zu finden. +\begin{beispiel}[Backtracking] + Probleme, bei deren (vollständigen) Lösung Backtracking verwendet wird, sind: + \begin{bspenum} + \item Damenproblem + \item Springerproblem + \item Rucksackproblem + \end{bspenum} +\end{beispiel} \index{Backtracking|)} \section{Funktionen höherer Ordnung} diff --git a/documents/Programmierparadigmen/scripts/python/n-damen.py b/documents/Programmierparadigmen/scripts/python/n-damen.py new file mode 100644 index 0000000..21d203d --- /dev/null +++ b/documents/Programmierparadigmen/scripts/python/n-damen.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +def get_next(n, i, damen_pos): + for i in range(n): + candidates = set(list(range(n))) + candidates -= set(damen_pos) + candidates -= set(list(range(damen_pos[i]+1))) + candidates = list(candidates) + if len(candidates) > 0: + damen_pos[i] = candidates[0] + return i, damen_pos + else: + damen_pos = damen_pos[0:i] + [0]*(n-i) + i -= 1 + +def is_attacked(damen, x, y): + """ Wird das Feld (x,y) von einer der Damen angegriffen? """ + for dy, dx in enumerate(damen[:y]): + if dx == x or dy == y or abs(x-dx) == abs(y-dy): + return True + return False + +def finde_loesung(n): + """ Platziere n Damen so auf einem n×n Feld, + sodass sich keine Damen schlagen. + """ + # damen[i] ist die x-position von Dame i in Zeile i + damen = [0]*n + i = 1 + solutions = [] + while 0 <= i < n: + while not is_attacked(damen, damen[i], i): + if i == n-1: + yield damen + break + i += 1 + i, damen = get_next(n, i, damen) + +def alle_loesungen(n): + generator = finde_loesung(n) + return list(generator) + +print(len(alle_loesungen(11))) \ No newline at end of file