diff --git a/20210107/InstallationUndVerwendungGTKWin10.pdf b/20210107/InstallationUndVerwendungGTKWin10.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..3757e05839ad8463e7da520b343a93af1f30d951
Binary files /dev/null and b/20210107/InstallationUndVerwendungGTKWin10.pdf differ
diff --git a/20210107/Tower_of_Hanoi.jpeg b/20210107/Tower_of_Hanoi.jpeg
new file mode 120000
index 0000000000000000000000000000000000000000..a1a794afda08596ffa2f46f278db53455de25b6c
--- /dev/null
+++ b/20210107/Tower_of_Hanoi.jpeg
@@ -0,0 +1 @@
+../common/Tower_of_Hanoi.jpeg
\ No newline at end of file
diff --git a/20210107/aufgabe-1.c b/20210107/aufgabe-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..abbf364a3db17611e41d086591826e98a8a3672b
--- /dev/null
+++ b/20210107/aufgabe-1.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+int fak (int n)
+{
+  if (n <= 0)
+    return 1;
+  else
+    return n * fak (n - 1);
+}
+
+int main (void)
+{
+  for (int n = 0; n <= 5; n++)
+    printf ("%d\n", fak (n));
+  return 0;
+}
diff --git a/20210107/aufgabe-2.c b/20210107/aufgabe-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..d0b065941fbc0082bf867d872527299dca97b98f
--- /dev/null
+++ b/20210107/aufgabe-2.c
@@ -0,0 +1,18 @@
+#include <string.h>
+
+int fun_1 (char *s)
+{
+  int x = 0;
+  for (int i = 0; i < strlen (s); i++)
+    x += s[i];
+  return x;
+}
+
+int fun_2 (char *s)
+{
+  int i = 0, x = 0;
+  int len = strlen (s);
+  while (i < len)
+    x += s[i++];
+  return x;
+}
diff --git a/20210107/aufgabe-3.c b/20210107/aufgabe-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..2bcd5e63a71f212b7243d1f7d9c92406d1e41e77
--- /dev/null
+++ b/20210107/aufgabe-3.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+int main (void)
+{
+  char buffer[100];
+  fgets (buffer, 100, stdin);
+  for (char *p = buffer; *p; p++)
+    printf ("%02x", *p);
+  printf ("\n");
+}
diff --git a/20210107/hp-20210107.pdf b/20210107/hp-20210107.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..0503488856a9624499caa49b82e1a83ce6e35f04
Binary files /dev/null and b/20210107/hp-20210107.pdf differ
diff --git a/20210107/hp-20210107.tex b/20210107/hp-20210107.tex
new file mode 100644
index 0000000000000000000000000000000000000000..0e48bfed60b59e2731f579314252ee949a00019c
--- /dev/null
+++ b/20210107/hp-20210107.tex
@@ -0,0 +1,852 @@
+% hp-20210107.pdf - Lecture Slides on Low-Level Programming
+% Copyright (C) 2012, 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021  Peter Gerwinski
+%
+% This document is free software: you can redistribute it and/or
+% modify it either under the terms of the Creative Commons
+% Attribution-ShareAlike 3.0 License, or under the terms of the
+% GNU General Public License as published by the Free Software
+% Foundation, either version 3 of the License, or (at your option)
+% any later version.
+%
+% This document is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this document.  If not, see <http://www.gnu.org/licenses/>.
+%
+% You should have received a copy of the Creative Commons
+% Attribution-ShareAlike 3.0 Unported License along with this
+% document.  If not, see <http://creativecommons.org/licenses/>.
+
+% README: Rekursion, Aufwandsabschätzungen
+
+\documentclass[10pt,t]{beamer}
+
+\usepackage{pgslides}
+\usepackage{pdftricks}
+\usepackage{tikz}
+
+\begin{psinputs}
+  \usepackage[utf8]{inputenc}
+  \usepackage[german]{babel}
+  \usepackage[T1]{fontenc}
+  \usepackage{helvet}
+  \renewcommand*\familydefault{\sfdefault}
+  \usepackage{pstricks,pst-grad}
+\end{psinputs}
+
+\title{Hardwarenahe Programmierung}
+\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski}
+\date{7.\ Januar 2021}
+
+\begin{document}
+
+\maketitleframe
+
+\nosectionnonumber{\inserttitle}
+
+\begin{frame}
+
+  \shownosectionnonumber
+
+  \begin{itemize}
+    \item[\textbf{1}] \textbf{Einführung}
+      \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}}
+    \item[\textbf{2}] \textbf{Einführung in C}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+      \begin{itemize}
+        \item[3.1] Der Präprozessor
+        \item[3.2] Bibliotheken einbinden
+        \item[3.3] Bibliotheken verwenden
+        \color{medgreen}
+        \item[3.4] Projekt organisieren: make
+      \end{itemize}
+    \item[\textbf{4}] \textbf{Algorithmen}
+      \begin{itemize}
+        \color{medgreen}
+        \item[5.1] Differentialgleichungen
+        \color{red}
+        \item[5.2] Rekursion
+        \item[5.3] Aufwandsabschätzungen
+      \end{itemize}
+    \item[\textbf{5}] \textbf{Hardwarenahe Programmierung}
+    \vspace*{-\smallskipamount}
+    \item[\textbf{\dots}]
+  \end{itemize}
+
+\end{frame}
+
+\setcounter{section}{2}
+\section{Bibliotheken}
+\subsection{Der Präprozessor}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \lstinline{#include}: %\pause:
+  Text einbinden
+  \begin{itemize}
+%    \pause
+    \item
+      \lstinline{#include <stdio.h>}: Standard-Verzeichnisse -- Standard-Header
+%    \pause
+    \item
+      \lstinline{#include "answer.h"}: auch aktuelles Verzeichnis -- eigene Header
+  \end{itemize}
+
+%  \pause
+  \bigskip
+
+  \lstinline{#define VIER 4}: Text ersetzen lassen -- Konstante definieren
+  \begin{itemize}
+%    \pause
+    \item
+      Kein Semikolon!
+%    \pause
+    \item
+      Berechnungen in Klammern setzen:\\
+      \lstinline{#define VIER (2 + 2)}
+%    \pause
+    \item
+      Konvention: Großbuchstaben
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Bibliotheken einbinden}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  Inhalt der Header-Datei: externe Deklarationen
+
+%  \pause
+  \smallskip
+  \lstinline{extern int answer (void);}
+
+%  \pause
+  \smallskip
+  \lstinline{extern int printf (__const char *__restrict __format, ...);}
+
+%  \pause
+  \bigskip
+  Funktion wird "`anderswo"' definiert
+  \begin{itemize}
+%    \pause
+    \item
+      separater C-Quelltext: mit an \lstinline[style=terminal]{gcc} übergeben
+%    \pause
+    \item
+      Zusammenfügen zu ausführbarem Programm durch den \newterm{Linker}
+%    \pause
+    \item
+      vorcompilierte Bibliothek: \lstinline[style=terminal]{-lfoo}\\
+%      \pause
+      = Datei \file{libfoo.a} in Standard-Verzeichnis
+  \end{itemize}
+
+\end{frame}
+
+\subsection{Bibliothek verwenden (Beispiel: GTK+)}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  \begin{itemize}
+    \item
+      \lstinline{#include <gtk/gtk.h>}
+%    \pause
+    \smallskip
+    \item
+      Mit \lstinline[style=cmd]{pkg-config --cflags --libs} erfährt man,\\
+      welche Optionen und Bibliotheken man an \lstinline[style=cmd]{gcc}
+      übergeben muß\alt<1->{.}{:}
+%      \pause
+      \begin{onlyenv}<1>
+        \begin{lstlisting}[style=terminal,gobble=10]
+          $ ¡pkg-config --cflags --libs gtk+-3.0¿
+          -pthread -I/usr/include/gtk-3.0 -I/usr/include/at-spi2-
+          atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1
+          .0 -I/usr/lib/x86_64-linux-gnu/dbus-1.0/include -I/usr/
+          include/gtk-3.0 -I/usr/include/gio-unix-2.0/ -I/usr/inc
+          lude/cairo -I/usr/include/pango-1.0 -I/usr/include/harf
+          buzz -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 -I
+          /usr/include/cairo -I/usr/include/pixman-1 -I/usr/inclu
+          de/freetype2 -I/usr/include/libpng16 -I/usr/include/gdk
+          -pixbuf-2.0 -I/usr/include/libpng16 -I/usr/include/glib
+          -2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lgtk
+          -3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcai
+          ro-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject
+          -2.0 -lglib-2.0
+        \end{lstlisting}
+        \vspace*{-3cm}
+      \end{onlyenv}
+    \pause
+    \arrowitem
+      Compiler-Aufruf:
+      \begin{onlyenv}<2>
+        \begin{lstlisting}[style=terminal,gobble=10]
+          $ ¡gcc -Wall -O hello-gtk.c -pthread -I/usr/include/gtk-
+          3.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-sp
+          i-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/x86_64-linux-g
+          nu/dbus-1.0/include -I/usr/include/gtk-3.0 -I/usr/inclu
+          de/gio-unix-2.0/ -I/usr/include/cairo -I/usr/include/pa
+          ngo-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.
+          0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/in
+          clude/pixman-1 -I/usr/include/freetype2 -I/usr/include/
+          libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/l
+          ibpng16 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux
+          -gnu/glib-2.0/include -lgtk-3 -lgdk-3 -lpangocairo-1.0
+          -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pix
+          buf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -o hello-gtk¿
+        \end{lstlisting}
+        \vspace*{-2cm}
+      \end{onlyenv}
+      \begin{onlyenv}<3->
+        \begin{lstlisting}[style=terminal,gobble=10]
+          $ ¡gcc -Wall -O hello-gtk.c $(pkg-config --cflags --libs
+                 gtk+-3.0) -o hello-gtk¿
+        \end{lstlisting}
+      \end{onlyenv}
+      \begin{onlyenv}<3>
+        \begin{picture}(0,0)(0.3,0.3)
+          \color{red}
+          \put(6.6,-0.6){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(3,1.5);}}}
+          \put(6.3,-0.7){\makebox(0,0)[t]{\shortstack{\strut Optionen:\\
+                           \strut u.\,a.\ viele Include-Verzeichnisse:\\
+                           \lstinline[style=cmd]{-I/usr/include/gtk-3.0}}}}
+          \put(10.0,-2.1){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(1.5,3);}}}
+          \put(10.3,-2.2){\makebox(0,0)[t]{\shortstack{\strut Bibliotheken:\\
+                            \strut u.\,a.\ \lstinline[style=cmd]{-lgtk-3 -lcairo}\qquad\strut}}}
+        \end{picture}
+      \end{onlyenv}
+    \pause
+    \pause
+    \item
+      Auf manchen Plattformen kommt es auf die Reihenfolge an:
+      \begin{lstlisting}[style=terminal,gobble=8]
+        $ ¡gcc -Wall -O $(pkg-config --cflags gtk+-3.0) \
+               hello-gtk.c $(pkg-config --libs gtk+-3.0) \
+               -o hello-gtk¿
+      \end{lstlisting}
+      (Backslash = "`Es geht in der nächsten Zeile weiter."')
+  \end{itemize}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Selbst geschriebene Funktion übergeben: \newterm{Callback}
+
+  \bigskip
+
+  \begin{lstlisting}[xleftmargin=1em]
+    gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
+    {
+      /* Zeichenbefehle */
+      ...
+
+      return FALSE;
+    }
+  
+    ...
+
+    g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
+  \end{lstlisting}
+
+  \medskip
+
+  \begin{itemize}
+    \arrowitem 
+      GTK+ ruft immer dann, wenn es etwas zu zeichnen gibt,\\
+      die Funktion \lstinline{draw} auf.
+  \end{itemize}
+
+%  \pause
+  \begin{picture}(0,0)(-0.07,0.2)
+    \color{red}
+    \put(5.3,4.8){\makebox(0,0)[bl]{\tikz{\draw[-latex](0,0)--(1.90,1.15);}}}
+    \put(5.0,4.7){\makebox(0,0)[t]{\shortstack{\strut repräsentiert den\\
+                    \strut Bildschirm, auf den\\
+                    \strut gezeichnet werden soll}}}
+%    \pause
+    \put(9.7,5.1){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.2,0.85);}}}
+    \put(9.7,5.0){\makebox(0,0)[t]{\shortstack{\strut optionale Zusatzinformationen\\
+                    \strut für draw(), typischerweise\\
+                    \strut ein Zeiger auf ein struct}}}
+    \put(10.0,3.5){\makebox(0,0)[tl]{\tikz{\draw[-latex](0,0)--(0.6,-1.25);}}}
+  \end{picture}
+
+\end{frame}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Selbst geschriebene Funktion übergeben: \newterm{Callback}
+
+  \bigskip
+
+  \begin{lstlisting}[xleftmargin=1em]
+    gboolean timer (GtkWidget *widget)
+    {
+      /* Rechenbefehle */
+      ...
+
+      gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
+      g_timeout_add (50, (GSourceFunc) timer, widget);
+      return FALSE;
+    }
+  
+    ...
+
+    g_timeout_add (50, (GSourceFunc) timer, drawing_area);
+  \end{lstlisting}
+
+  \medskip
+
+  \begin{itemize}
+    \arrowitem 
+      GTK+ ruft nach 50 Millisekunden
+      die Funktion \lstinline{timer} auf.
+  \end{itemize}
+
+%  \pause
+  \begin{picture}(0,0)(-0.07,0.2)
+    \color{red}
+    \put(9.7,6.7){\makebox(0,0)[t]{\shortstack{\strut Dieser Bereich soll\\
+                    \strut neu gezeichnet werden.}}}
+    \put(9.7,5.7){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.6,-0.8);}}}
+%    \pause
+    \put(4.3,3.2){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-0.7,0.6);}}}
+    \put(4.3,3.1){\makebox(0,0)[t]{\shortstack{\strut In weiteren 50 Millisekunden soll\\
+                    \strut die Funktion erneut aufgerufen werden.}}}
+%    \pause
+    \put(9.3,2.9){\makebox(0,0)[br]{\tikz{\draw[-latex](0,0)--(-3.3,0.9);}}}
+    \put(9.8,2.8){\makebox(0,0)[t]{\shortstack{\strut Explizite Typumwandlung\\
+                    \strut eines Zeigers (später)}}}
+  \end{picture}
+
+  \vspace*{-1cm}
+
+\end{frame}
+
+\subsection{Projekt organisieren: make}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+  \begin{itemize}
+    \item
+      \only<4->{explizite und implizite} Regeln
+      \begin{onlyenv}<2>
+        \smallskip
+        \begin{lstlisting}[language=make,gobble=10]
+          philosophy: philosophy.o answer.o
+                  gcc philosophy.o answer.o -o philosophy
+
+          answer.o: answer.c answer.h
+                  gcc -Wall -O answer.c -c
+
+          philosophy.o: philosophy.c answer.h
+                  gcc -Wall -O philosophy.c -c
+        \end{lstlisting}
+      \end{onlyenv}
+      \begin{onlyenv}<4>
+        \smallskip
+        \begin{lstlisting}[language=make,gobble=10]
+          TARGET = philosophy
+          OBJECTS = philosophy.o answer.o
+          HEADERS = answer.h
+          CFLAGS = -Wall -O
+
+          $(TARGET): $(OBJECTS)
+                  gcc $(OBJECTS) -o $(TARGET)
+
+          %.o: %.c $(HEADERS)
+                  gcc $(CFLAGS) $< -c
+
+          clean:
+                  rm -f $(OBJECTS) $(TARGET)
+        \end{lstlisting}
+      \end{onlyenv}
+    \item
+      Makros
+      \begin{onlyenv}<3>
+        \smallskip
+        \begin{lstlisting}[language=make,gobble=10]
+          TARGET = philosophy
+          OBJECTS = philosophy.o answer.o
+          HEADERS = answer.h
+          CFLAGS = -Wall -O
+
+          $(TARGET): $(OBJECTS)
+                  gcc $(OBJECTS) -o $(TARGET)
+
+          answer.o: answer.c $(HEADERS)
+                  gcc $(CFLAGS) answer.c -c
+
+          philosophy.o: philosophy.c $(HEADERS)
+                  gcc $(CFLAGS) philosophy.c -c
+
+          clean:
+                  rm -f $(OBJECTS) $(TARGET)
+        \end{lstlisting}
+        \vspace*{-1cm}
+      \end{onlyenv}
+    \begin{onlyenv}<5->
+      \smallskip
+      \arrowitem
+        3 Sprachen: C, Präprozessor, make
+    \end{onlyenv}
+  \end{itemize}
+
+\end{frame}
+
+\section{Algorithmen}
+\subsection{Differentialgleichungen}
+
+\begin{frame}[fragile]
+
+  \showsection
+  \showsubsection
+
+  \textbf{Beispiel 1: Gleichmäßig beschleunigte Bewegung}
+
+  \strut\hfill
+  \begin{minipage}{2.5cm}
+    \vspace*{0.6cm}
+    \begin{align*}
+      x'(t) &= v_x(t) \\[0.65cm]
+      y'(t) &= v_y(t) \\[0.75cm]
+      v_x'(t) &= 0 \\[0.65cm]
+      v_y'(t) &= -g
+    \end{align*}
+    \vspace*{0.0cm}
+  \end{minipage}%
+  \only<1>{\hspace*{9.49cm}}\strut
+  \only<2->{\hfill$\Rightarrow$\hfill}%
+  \begin{onlyenv}<2-8>
+    \begin{minipage}{8.3cm}
+      \begin{align*}
+        x(t) &= \int v_x(t)\,dt
+          \visible<4->{= \int v_{0x}\,dt}
+          \visible<5->{= x_0 + v_{0x}\cdot t}\\[\medskipamount]
+        y(t) &= \int v_y(t)\,dt
+          \visible<7->{= \int v_{0y} - g\cdot t\,dt}
+          \visible<8->{= y_0 + v_{0y}\cdot t
+                         - {\textstyle\frac12}gt^2}\\[\bigskipamount]
+        v_x(t) &= \int 0\,dt
+          \visible<3->{= v_{0x}} \\[\medskipamount]
+        v_y(t) &= \int -g\,dt
+          \visible<6->{= v_{0y} - g\cdot t}
+      \end{align*}
+    \end{minipage}%
+  \end{onlyenv}%
+  \begin{onlyenv}<9->
+    \begin{minipage}{3.5cm}
+      \vspace*{0.5cm}
+      \begin{lstlisting}[gobble=8,xleftmargin=0.5em]
+        ¡x += vx * dt;¿
+      \end{lstlisting}
+      \vspace{0.75cm}
+      \begin{lstlisting}[gobble=8,xleftmargin=0.5em]
+        ¡y += vy * dt;¿
+      \end{lstlisting}
+      \vspace{0.90cm}
+      \begin{lstlisting}[gobble=8,xleftmargin=0.5em]
+        ¡vx += 0 * dt;¿
+      \end{lstlisting}
+      \vspace{0.75cm}
+      \begin{lstlisting}[gobble=8,xleftmargin=0.5em]
+        ¡vy += -g * dt;¿
+      \end{lstlisting}
+    \end{minipage}%
+    \begin{minipage}{5.13cm}
+      Siehe: \file{gtk-13.c}
+    \end{minipage}
+  \end{onlyenv}%
+  \hfill\strut
+
+\end{frame}
+
+\begin{frame}[fragile]
+  \showsection
+  \showsubsection
+
+  \textbf{Beispiel 1: Gleichmäßig beschleunigte Bewegung}
+
+  \medskip
+
+  \textbf{Beispiel 2: Mathematisches Pendel}
+
+  \vspace*{-2\bigskipamount}
+
+  \begin{picture}(0,0)
+    \put(8,-6.5){\includegraphics{pendulum.pdf}}
+  \end{picture}
+
+  \begin{eqnarray*}
+    \varphi'(t) &=& \omega(t) \\[\smallskipamount]
+    \omega'(t) &=& -\frac{g}{l}\cdot\sin\varphi(t)\hspace*{7.1cm}
+  \end{eqnarray*}
+  \vspace*{-1.5\medskipamount}
+  \begin{itemize}
+    \item
+      Von Hand (analytisch):\\
+      Lösung raten (Ansatz), Parameter berechnen
+    \item
+      Mit Computer (numerisch):\\
+      Eulersches Polygonzugverfahren
+  \end{itemize}
+  \smallskip
+  \begin{lstlisting}[gobble=0]
+    phi += dt * omega;
+    omega += - dt * g / l * sin (phi);
+  \end{lstlisting}
+
+  \pause
+  \bigskip
+
+  \textbf{Beispiel 3: Weltraum-Simulation}
+
+  Praktikumsaufgabe
+  \vspace*{-1cm}
+
+\end{frame}
+
+\nosectionnonumber{\inserttitle}
+
+\begin{frame}
+
+  \shownosectionnonumber
+
+  \begin{itemize}
+    \item[\textbf{1}] \textbf{Einführung}
+      \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}}
+    \item[\textbf{2}] \textbf{Einführung in C}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+      \begin{itemize}
+        \item[3.1] Der Präprozessor
+        \item[3.2] Bibliotheken einbinden
+        \item[3.3] Bibliotheken verwenden
+        \color{medgreen}
+        \item[3.4] Projekt organisieren: make
+      \end{itemize}
+    \item[\textbf{4}] \textbf{Algorithmen}
+      \begin{itemize}
+        \color{medgreen}
+        \item[5.1] Differentialgleichungen
+        \color{red}
+        \item[5.2] Rekursion
+        \item[5.3] Aufwandsabschätzungen
+      \end{itemize}
+    \item[\textbf{5}] \textbf{Hardwarenahe Programmierung}
+    \vspace*{-\smallskipamount}
+    \item[\textbf{\dots}]
+  \end{itemize}
+  \vspace*{-1cm}
+
+\end{frame}
+
+\subsection{Rekursion}
+
+\begin{frame}[fragile]
+
+  \showsubsection
+
+  Vollständige Induktion:
+  \vspace*{-0.725cm}
+  \begin{displaymath}
+    \hspace*{4cm}
+    \left.
+      \begin{array}{r}
+        \mbox{Aussage gilt für $n = 1$}\\[2pt]
+        \mbox{Schluß von $n - 1$ auf $n$}
+      \end{array}
+    \right\}
+    \mbox{Aussage gilt für alle $n\in\mathbb{N}$}
+  \end{displaymath}
+  \vspace*{-0.5cm}
+
+  \pause
+
+  Türme von Hanoi
+
+  \begin{onlyenv}<2>
+    \begin{center}
+      \includegraphics[width=12.2cm]{Tower_of_Hanoi.jpeg}
+    \end{center}
+  \end{onlyenv}
+
+  \begin{onlyenv}<3->
+    \begin{itemize}
+      \item
+        64 Scheiben, 3 Plätze,
+        \only<3-4>{\hfill\makebox(0,0)[rt]{\includegraphics[width=6cm]{Tower_of_Hanoi.jpeg}}}\\
+        immer 1 Scheibe verschieben
+      \item
+        Ziel: Turm verschieben
+      \item
+        Es dürfen nur kleinere Scheiben\\
+        auf größeren liegen.
+      \bigskip
+      \pause
+      \pause
+      \item
+        $n = 1$ Scheibe: fertig
+      \item
+        Wenn $n - 1$ Scheiben verschiebbar:\\
+        schiebe $n - 1$ Scheiben auf Hilfsplatz,\\
+        verschiebe die darunterliegende,\\
+        hole $n - 1$ Scheiben von Hilfsplatz
+    \end{itemize}
+    \begin{onlyenv}<5>
+      \vspace{-4.3cm}
+      \begin{lstlisting}[gobble=8,xleftmargin=6.4cm]
+        void move (int from, int to, int disks)
+        {
+          if (disks == 1)
+            move_one_disk (from, to);
+          else
+            {
+              int help = 0 + 1 + 2 - from - to;
+              move (from, help, disks - 1);
+              move (from, to, 1);
+              move (help, to, disks - 1);
+            }
+        }
+      \end{lstlisting}
+    \end{onlyenv}
+    \begin{onlyenv}<6->
+      \vspace{-5.0cm}
+      \hspace*{7.4cm}\begin{minipage}[t]{5cm}
+        32 Scheiben:
+        \begin{lstlisting}[gobble=10,style=terminal]
+          $ ¡time ./hanoi-9a¿
+          ...
+          real    0m32,712s
+          user    0m32,708s
+          sys     0m0,000s
+        \end{lstlisting}
+        \pause[7]
+        \begin{itemize}
+          \arrowitem
+            etwas über 1 Minute\\
+            für 64 Scheiben
+        \end{itemize}
+        \pause
+        \vspace*{-0.5cm}
+        \begin{picture}(0,0)
+          \color{red}
+          \put(0,0){\makebox(0,0)[bl]{\tikz[line width=1pt]{\draw(0,0)--(4,0.8);}}}
+          \put(0,0.8){\makebox(0,0)[tl]{\tikz[line width=1pt]{\draw(0,0)--(4,-0.8);}}}
+        \end{picture}
+
+        Für jede zusätzliche Scheibe\\verdoppelt sich die Rechenzeit!
+        % 32.712 * 2^32 / 3600 / 24 / 365.25 = 4452.08032888280477602859
+        \begin{itemize}
+          \arrowitem
+            $\frac{32,712\,\text{s}\,\cdot\,2^{32}}{3600\,\cdot\,24\,\cdot\,365,25} \approx 4452$
+            Jahre\\[\smallskipamount]
+            für 64 Scheiben
+        \end{itemize}
+      \end{minipage}
+    \end{onlyenv}
+  \end{onlyenv}
+
+\end{frame}
+
+\subsection{Aufwandsabschätzungen \protect\color{gray}-- Komplexitätsanalyse}
+
+\begin{frame}[fragile]
+
+%  \newcommand{\w}{\hspace*{0.75pt}}
+
+  \showsubsection
+
+  \begin{picture}(0,0)
+    \put(7.6,-0.5){%
+      \begin{minipage}[t]{5.3cm}
+%        \vspace*{-1.0cm}\includegraphics{landau-symbols.pdf}
+        \vspace*{-1.0cm}\alt<16->{\includegraphics{landau-symbols-3.pdf}}%
+                       {\alt<15->{\includegraphics{landau-symbols-2.pdf}}%
+                                 {\includegraphics{landau-symbols.pdf}}}
+        \small
+        \begin{description}\itemsep0pt\leftskip-0.5cm
+          \item[$n$:] Eingabedaten
+          \item[$g(n)$:] Rechenzeit
+        \end{description}
+      \end{minipage}}
+  \end{picture}
+
+  \vspace*{-\bigskipamount}
+
+  Wann ist ein Programm "`schnell"'?
+
+  \medskip
+
+  \begin{onlyenv}<1-2>
+      Türme von Hanoi: $\mathcal{O}(2^n)$
+      \par\medskip
+      Für jede zusätzliche Scheibe\\verdoppelt sich die Rechenzeit!
+      % 32.712 * 2^32 / 3600 / 24 / 365.25 = 4452.08032888280477602859
+      \begin{itemize}
+        \arrowitem
+          $\frac{32,712\,\text{s}\,\cdot\,2^{32}}{3600\,\cdot\,24\,\cdot\,365,25} \approx 4452$
+          Jahre\\[\smallskipamount]
+          für 64 Scheiben
+      \end{itemize}
+
+      \bigskip
+  \end{onlyenv}
+
+  \begin{onlyenv}<2->
+    Faustregel:\\Schachtelung der Schleifen zählen\\
+    $k$ Schleifen ineinander \textarrow\ $\mathcal{O}(n^k)$
+
+    \bigskip
+  \end{onlyenv}
+
+  \begin{onlyenv}<3-13>
+    \textbf{Beispiel: Sortieralgorithmen}
+
+    \smallskip
+
+    Anzahl der Vergleiche bei $n$ Strings
+    \begin{itemize}
+      \item
+        Maximum suchen \pause[4]mit Schummeln\pause: $\mathcal{O}(1)$
+      \pause
+      \item
+        Maximum suchen\pause: $\mathcal{O}(n)$
+      \pause
+      \item
+        Selection-Sort\pause: $\mathcal{O}(n^2)$
+      \pause
+      \item
+        Bubble-Sort\pause: $\mathcal{O}(n)$ bis $\mathcal{O}(n^2)$
+      \pause
+      \item
+        Quicksort\pause: $\mathcal{O}(n\log n)$ bis $\mathcal{O}(n^2)$
+    \end{itemize}
+
+  \end{onlyenv}
+
+  \begin{onlyenv}<14>
+    \textbf{Wie schnell ist RSA-Verschlüsselung?}
+
+    \smallskip
+
+    \begin{math}
+      c = m^e\,\%\,N
+    \end{math}
+    \quad
+    ("`$\%$"' = "`modulo"')
+
+    \medskip
+
+    \begin{lstlisting}[gobble=6,xleftmargin=2em]
+      int c = 1;
+      for (int i = 0; i < e; i++)
+        c = (c * m) % N;
+    \end{lstlisting}
+
+    \smallskip
+
+    \begin{itemize}
+      \item
+        $\mathcal{O}(e)$ Iterationen
+%      \item
+%        wenn $n$ die Anzahl der Binärziffern (Bits) von $e$ ist:
+%        $\mathcal{O}(2^n)$ Iterationen
+      \item
+        mit Trick:
+        $\mathcal{O}(\log e)$ Iterationen ($\log e$ = Anzahl der Ziffern von $e$)
+    \end{itemize}
+
+    \smallskip
+
+    Jede Iteration enthält eine Multiplikation und eine Division.\\
+    Aufwand dafür: $\mathcal{O}(\log e)$\\
+    \textarrow\ Gesamtaufwand: $\mathcal{O}\bigl((\log e)^2\bigr)$
+
+  \end{onlyenv}
+
+  \begin{onlyenv}<15->
+
+    \textbf{Wie schnell ist RSA?}\\
+
+    \smallskip
+
+    ($n$ = typische beteiligte Zahl, z.\,B. $e,p,q$)
+
+    \begin{itemize}
+      \item
+        Ver- und Entschlüsselung (Exponentiation):\\
+        \strut\hbox to 3.5cm{\color{red}$\mathcal{O}\!\left((\log n)^2\right)$\hss}
+        \only<16->{{\color{magenta}$\mathcal{O}(n^2)$}}
+      \item
+        Schlüsselerzeugung (Berechnung von $d$):\\
+        \strut\hbox to 3.5cm{\color{red}$\mathcal{O}\!\left((\log n)^2\right)$\hss}
+        \only<16->{{\color{magenta}$\mathcal{O}(n^2)$}}
+      \item
+        Verschlüsselung brechen (Primfaktorzerlegung):\\
+        \strut\hbox to 3.5cm{\color{red}$\mathcal{O}\bigl(2^{\sqrt{\log n\,\cdot\,\log\log n}}\bigr)$\hss}
+        \only<16->{{\color{magenta}$\mathcal{O}\bigl(2^{\sqrt{n\log n}}\bigr)$}}
+    \end{itemize}
+
+    \vspace{0cm plus 1filll}
+
+    \textbf{Die Sicherheit von RSA beruht darauf,
+    daß das Brechen der Verschlüsselung aufwendiger ist als
+    \boldmath$\mathcal{O}\bigl((\log n)^k\bigr)$ (für beliebiges $k$).}
+
+    \vspace*{0.65cm}
+
+  \end{onlyenv}
+
+\end{frame}
+
+\nosectionnonumber{\inserttitle}
+
+\begin{frame}
+
+  \shownosectionnonumber
+
+  \begin{itemize}
+    \item[\textbf{1}] \textbf{Einführung}
+      \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/hp}}}
+    \item[\textbf{2}] \textbf{Einführung in C}
+    \item[\textbf{3}] \textbf{Bibliotheken}
+      \begin{itemize}
+        \item[3.1] Der Präprozessor
+        \item[3.2] Bibliotheken einbinden
+        \item[3.3] Bibliotheken verwenden
+        \item[3.4] Projekt organisieren: make
+      \end{itemize}
+    \item[\textbf{4}] \textbf{Algorithmen}
+      \begin{itemize}
+        \item[5.1] Differentialgleichungen
+        \color{medgreen}
+        \item[5.2] Rekursion
+        \item[5.3] Aufwandsabschätzungen
+      \end{itemize}
+    \item[\textbf{5}] \textbf{Hardwarenahe Programmierung}
+    \vspace*{-\smallskipamount}
+    \item[\textbf{\dots}]
+  \end{itemize}
+  \vspace*{-1cm}
+
+\end{frame}
+
+\end{document}
diff --git a/20210107/hp-musterloesung-20210107.pdf b/20210107/hp-musterloesung-20210107.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..c154a59ec11e00019d6653f8a309f770ce37a0e6
Binary files /dev/null and b/20210107/hp-musterloesung-20210107.pdf differ
diff --git a/20210107/hp-musterloesung-20210107.tex b/20210107/hp-musterloesung-20210107.tex
new file mode 100644
index 0000000000000000000000000000000000000000..2027ef6d209d940a82a925f8d8fee50f54ab0048
--- /dev/null
+++ b/20210107/hp-musterloesung-20210107.tex
@@ -0,0 +1,357 @@
+% hp-musterloesung-20210107.pdf - Solutions to the Exercises on Low-Level Programming
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021  Peter Gerwinski
+%
+% This document is free software: you can redistribute it and/or
+% modify it either under the terms of the Creative Commons
+% Attribution-ShareAlike 3.0 License, or under the terms of the
+% GNU General Public License as published by the Free Software
+% Foundation, either version 3 of the License, or (at your option)
+% any later version.
+%
+% This document is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this document.  If not, see <http://www.gnu.org/licenses/>.
+%
+% You should have received a copy of the Creative Commons
+% Attribution-ShareAlike 3.0 Unported License along with this
+% document.  If not, see <http://creativecommons.org/licenses/>.
+
+% README: Fakultät, Länge von Strings (Neuauflage), Hexdumps
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+\usepackage{gnuplot-lua-tikz}
+
+\begin{document}
+
+  \section*{Hardwarenahe Programmierung\\
+            Musterlösung zu den Übungsaufgaben -- 7.\ Januar 2021}
+
+  \exercise{Fakultät}
+
+  Die Fakultät $n!$ einer ganzen Zahl $n \ge 0$ ist definiert als:
+  \begin{eqnarray*}
+    1 & \mbox{für} & n = 0, \\
+    n \cdot (n-1)! & \mbox{für} & n > 0.
+  \end{eqnarray*}
+
+  Mit anderen Worten: $n! = 1\cdot2\cdot3\cdot\dots\cdot n$.
+
+  Die folgende Funktion \lstinline{fak()} berechnet die Fakultät \emph{rekursiv}
+  (Datei: \gitfile{hp}{2020ws/20210107}{aufgabe-1.c}):
+
+  \begin{lstlisting}
+    int fak (int n)
+    {
+      if (n <= 0)
+        return 1;
+      else
+        return n * fak (n - 1);
+    }
+  \end{lstlisting}
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\
+      d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion.
+      \points{3}
+    \item
+      Wie viele Multiplikationen (Landau-Symbol)
+      erfordern beide Versionen der Fakultätsfunktion\\
+      in Abhängigkeit von \lstinline$n$?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+    \item
+      Wieviel Speicherplatz (Landau-Symbol)
+      erfordern beide Versionen der Fakultätsfunktion\\
+      in Abhängigkeit von \lstinline$n$?
+      Begründen Sie Ihre Antwort.
+      \points{3}
+  \end{enumerate}
+
+  \solution
+
+  \begin{itemize}
+    \item[(a)]
+      \textbf{Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\
+      d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion.}
+
+      Datei: \gitfile{hp}{2020ws/20210107}{loesung-1.c}
+      \begin{lstlisting}[gobble=8]
+        int fak (int n)
+        {
+          int f = 1;
+          for (int i = 2; i <= n; i++)
+            f *= i;
+          return f;
+        }
+      \end{lstlisting}
+
+    \item[(b)]
+      \textbf{Wie viele Multiplikationen (Landau-Symbol)
+      erfordern beide Versionen der Fakultätsfunktion\\
+      in Abhängigkeit von \lstinline$n$?
+      Begründen Sie Ihre Antwort.}
+
+      In beiden Fällen werden $n$ Zahlen miteinander multipliziert --
+      oder $n - 1$, wenn man Multiplikationen mit 1 ausspart.
+      In jedem Fall hängt die Anzahl der Multiplikationen
+      linear von $n$ ab; es sind $\mathcal{O}(n)$ Multiplikationen.
+      Insbesondere arbeiten also beide Versionen gleich schnell.
+
+    \item[(c)]
+      \textbf{Wieviel Speicherplatz (Landau-Symbol)
+      erfordern beide Versionen der Fakultätsfunktion\\
+      in Abhängigkeit von \lstinline$n$?
+      Begründen Sie Ihre Antwort.}
+
+      Die iterative Version der Funktion benötigt 2 Variable vom Typ \lstinline{int},
+      nämlich \lstinline{n} und \lstinline{f}.
+      Dies ist eine konstante Zahl;
+      der Speicherplatzverbrauch ist daher $\mathcal{O}(1)$.
+
+      Die rekursive Version der Funktion erzeugt
+      jedesmal, wenn sie sich selbst aufruft,
+      eine zusätzliche Variable \lstinline{n}.
+      Es sind $n + 1$ Aufrufe; die Anzahl der Variablen \lstinline{n}
+      hängt linear von $n$ ab; der Speicherplatzverbrauch ist also $\mathcal{O}(n)$.
+  \end{itemize}
+
+  \exercise{Länge von Strings}
+
+  Diese Aufgabe ist eine Neuauflage von Aufgabe 3 der
+  Übung vom 14.\ November 2019,\\
+  ergänzt um die Teilaufgaben (f) und (g).
+
+  \medskip
+
+  Strings werden in der Programmiersprache C durch Zeiger auf \lstinline{char}-Variable realisiert.
+
+  Beispiel: \lstinline{char *hello_world = "Hello, world!\n"}
+
+  Die Systembibliothek stellt eine Funktion \lstinline{strlen()} zur Ermittlung der Länge von Strings\\
+  zur Verfügung (\lstinline{#include <string.h>}).
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Auf welche Weise ist die Länge eines Strings gekennzeichnet?
+      \points{1}
+    \item
+      Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
+      und wieviel Speicherplatz belegt sie?\\
+      \points{2}
+    \item
+      Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
+      die die Länge eines Strings zurückgibt.\\
+      \points{3}
+  \end{enumerate}
+
+  \goodbreak
+
+  Wir betrachten nun die folgenden Funktionen (Datei: \gitfile{hp}{2020ws/20210107}{aufgabe-2.c}):
+  \begin{center}
+    \begin{minipage}{8cm}
+      \begin{lstlisting}[gobble=8]
+        int fun_1 (char *s)
+        {
+          int x = 0;
+          for (int i = 0; i < strlen (s); i++)
+            x += s[i];
+          return x;
+        }
+      \end{lstlisting}
+    \end{minipage}%
+    \begin{minipage}{6cm}
+      \vspace*{-1cm}
+      \begin{lstlisting}[gobble=8]
+        int fun_2 (char *s)
+        {
+          int i = 0, x = 0;
+          int len = strlen (s);
+          while (i < len)
+            x += s[i++];
+          return x;
+        }
+      \end{lstlisting}
+      \vspace*{-1cm}
+    \end{minipage}
+  \end{center}
+  \begin{enumerate}[\quad(a)]\setcounter{enumi}{3}
+    \item
+      Was bewirken die beiden Funktionen?
+      \points{2}
+    \item
+      Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},\\
+      nur effizienter.
+      \points{4}
+    \item
+      Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
+      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String?
+      Begründen Sie Ihre Antwort.
+      Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.
+       \points{3}
+    \item
+      Von welcher Ordnung (Landau-Symbol) ist Ihre effizientere Funktion?\\
+      Begründen Sie Ihre Antwort.
+      \points{1}
+  \end{enumerate}
+
+  \solution
+
+  \begin{itemize}
+    \item[(a)]
+      \textbf{Auf welche Weise ist die Länge eines Strings gekennzeichnet?}
+
+      Ein String ist ein Array von \lstinline{char}s.
+      Nach den eigentlichen Zeichen des Strings enthält das Array
+      \textbf{ein Null-Symbol} (Zeichen mit Zahlenwert 0,
+      nicht zu verwechseln mit der Ziffer \lstinline{'0'}) als Ende-Markierung.
+      Die Länge eines Strings ist die Anzahl der Zeichen
+      \emph{vor\/} diesem Symbol.
+
+    \item[(b)]
+      {\bf Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
+      und wieviel Speicherplatz belegt sie?}
+
+      Sie ist 14 Zeichen lang (\lstinline{'\n'} ist nur 1 Zeichen;
+      das Null-Symbol, das das Ende markiert, zählt hier nicht mit)
+      und belegt Speicherplatz für 15 Zeichen
+      (15 Bytes -- einschließlich Null-Symbol / Ende-Markierung).
+
+    \item[(c)]
+      \textbf{Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
+      die die Länge eines Strings zurückgibt.}
+
+      Siehe die Dateien \gitfile{hp}{2020ws/20210107}{loesung-2c-1.c} (mit Array-Index)
+      und \gitfile{hp}{2020ws/20210107}{loesung-2c-2.c} (mit Zeiger-Arithmetik).
+      Beide Lösungen sind korrekt und arbeiten gleich schnell.
+
+      Die Warnung \lstinline[style=terminal]{conflicting types for built-in function "strlen"}
+      kann normalerweise ignoriert werden;
+      auf manchen Systemen (z.\,B.\ MinGW) hat jedoch die eingebaute Funktion \lstinline{strlen()}
+      beim Linken Vorrang vor der selbstgeschriebenen,
+      so daß die selbstgeschriebene Funktion nie aufgerufen wird.
+      In solchen Fällen ist es zulässig, die selbstgeschriebene Funktion
+      anders zu nennen (z.\,B.\ \lstinline{my_strlen()}).
+
+    \item[(d)]
+      \textbf{Was bewirken die beiden Funktionen?}
+
+      Beide addieren die Zahlenwerte der im String enthaltenen Zeichen
+      und geben die Summe als Funktionsergebnis zurück.
+
+      Im Falle des Test-Strings \lstinline{"Hello, world!\n"}
+      lautet der Rückgabewert 1171 (siehe \gitfile{hp}{2020ws/20210107}{loesung-2d-1.c} und \gitfile{hp}{2020ws/20210107}{loesung-2d-2.c}).
+
+    \item[(e)]
+      \textbf{Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},
+      nur effizienter.}
+
+      Die Funktion wird effizienter,
+      wenn man auf den Aufruf von \lstinline{strlen()} verzichtet
+      und stattdessen die Ende-Prüfung in derselben Schleife vornimmt,
+      in der man auch die Zahlenwerte der Zeichen des Strings aufsummiert.
+
+      Die Funktion \lstinline{fun_3()} in der Datei \gitfile{hp}{2020ws/20210107}{loesung-2e-1.c}
+      realisiert dies mit einem Array-Index,
+      Die Funktion \lstinline{fun_4()} in der Datei \gitfile{hp}{2020ws/20210107}{loesung-2e-2.c}
+      mit Zeiger-Arithmetik.
+      Beide Lösungen sind korrekt und arbeiten gleich schnell.
+
+      \textbf{Bemerkung:} Die effizientere Version der Funktion
+      arbeitet doppelt so schnell wie die ursprüngliche,
+      hat aber ebenfalls die Ordnung $\mathcal{O}(n)$ -- siehe unten.
+
+    \item[(f)]
+      \textbf{Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
+      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String?
+      Begründen Sie Ihre Antwort.
+      Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.}
+
+      Vorüberlegung: \lstinline{strlen()} greift in einer Schleife
+      auf alle Zeichen des Strings der Länge $n$ zu,
+      hat also $\mathcal{O}(n)$.
+
+      \lstinline{fun_1()} ruft in jedem Schleifendurchlauf
+      (zum Prüfen der \lstinline{while}-Bedingung) einmal \lstinline{strlen()} auf
+      und greift anschließend auf ein Zeichen des Strings zu,
+      hat also $\mathcal{O}\bigl(n\cdot(n+1)\bigr) = \mathcal{O}(n^2)$.
+
+      \lstinline{fun_2()} ruft einmalig \lstinline{strlen()} auf
+      und greift anschließend in einer Schleife auf alle Zeichen des Strings zu,
+      hat also $\mathcal{O}(n+n) = \mathcal{O}(n)$.
+
+    \item[(g)]
+      \textbf{Von welcher Ordnung (Landau-Symbol) ist Ihre effizientere Funktion?\\
+      Begründen Sie Ihre Antwort.}
+
+      In beiden o.\,a.\ Lösungsvarianten
+      -- \gitfile{hp}{2020ws/20210107}{loesung-2e-1.c}
+      und \gitfile{hp}{2020ws/20210107}{loesung-2e-2.c} --
+      arbeitet die Funktion mit einer einzigen Schleife,
+      die gleichzeitig die Zahlenwerte addiert und das Ende des Strings sucht.
+
+      Mit jeweils einer einzigen Schleife
+      haben beide Funktionen die Ordnung $\mathcal{O}(n)$.
+
+  \end{itemize}
+
+  \exercise{Hexdumps}
+
+  Das folgende Programm (\gitfile{hp}{2020ws/20210107}{aufgabe-2.c}) liest
+  einen String ein und gibt die ASCII-Werte der Buchstaben hexadezimal aus.
+  (Anders als z.\,B.\ \lstinline{scanf()}
+  akzeptiert die Funktion \lstinline{fgets()} zum Lesen von Strings auch Leerzeichen,
+  und sie vermeidet Pufferüberläufe.)
+  \begin{lstlisting}[style=numbered]
+    #include <stdio.h>
+
+    int main (void)
+    {
+      char buffer[100];
+      fgets (buffer, 100, stdin);
+      for (char *p = buffer; *p; p++)
+        printf ("%02x", *p);
+      printf ("\n");
+    }
+  \end{lstlisting}
+  Beispiel: Bei der Eingabe von \lstinline[style=cmd]{Dies ist ein Test.}
+  erscheint die Ausgabe\\
+  \lstinline[style=terminal]{44696573206973742065696e20546573742e0a}.
+
+  Schreiben Sie ein Programm, das diese Umwandlung in umgekehrter Richtung vornimmt,
+  also z.\,B.\ bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a}
+  wieder \lstinline[style=terminal]{Dies ist ein Test.} ausgibt.
+
+  \points{6}
+
+  Hinweis für die Klausur:
+  Abgabe in digitaler Form ist erwünscht, aber nicht zwingend.
+
+  \solution
+
+  Siehe \gitfile{hp}{2020ws/20210107}{loesung-2.c}.
+
+  Das Programm macht mehrfach davon Gebrauch,
+  daß in C Zeichen und Zahlen äquivalent sind.
+  Wenn z.\,B.\ die \lstinline{char}-Variable \lstinline{c}
+  den Wert \lstinline{'3'} (Ziffer 3) enthält,
+  dann hat der Ausdruck \lstinline{c - '0'} den Wert \lstinline{3} (Zahlenwert 3).
+  Hierfür ist es insbesondere nicht nötig, vorauszusetzen,
+  daß wir den ASCII-Zeichensatz verwenden und \lstinline{'0'}
+  den Wert \lstinline{48} hat.
+
+  Bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a}
+  gibt das Programm zusätzlich eine Leerzeile aus.
+  Die liegt daran, daß das \lstinline[style=cmd]{0a} am Ende
+  bereits eine Zeilenschaltung enthält und das Programm mit
+  \lstinline{printf ("\n")} eine zusätzliche Zeilenschaltung ausgibt.
+
+\end{document}
diff --git a/20210107/hp-uebung-20210107.pdf b/20210107/hp-uebung-20210107.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..068a5c491dd2622ecc9223c9fc0cf9ffed8fd762
Binary files /dev/null and b/20210107/hp-uebung-20210107.pdf differ
diff --git a/20210107/hp-uebung-20210107.tex b/20210107/hp-uebung-20210107.tex
new file mode 100644
index 0000000000000000000000000000000000000000..3e06f4d7420fa1182fce1741aa6bf718df3c7ce5
--- /dev/null
+++ b/20210107/hp-uebung-20210107.tex
@@ -0,0 +1,203 @@
+% hp-uebung-20210107.pdf - Exercises on Low-Level Programming
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019, 2020, 2021  Peter Gerwinski
+%
+% This document is free software: you can redistribute it and/or
+% modify it either under the terms of the Creative Commons
+% Attribution-ShareAlike 3.0 License, or under the terms of the
+% GNU General Public License as published by the Free Software
+% Foundation, either version 3 of the License, or (at your option)
+% any later version.
+%
+% This document is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this document.  If not, see <http://www.gnu.org/licenses/>.
+%
+% You should have received a copy of the Creative Commons
+% Attribution-ShareAlike 3.0 Unported License along with this
+% document.  If not, see <http://creativecommons.org/licenses/>.
+
+% README: Fakultät, Länge von Strings (Neuauflage), Hexdumps
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+
+\begin{document}
+
+%  \thispagestyle{empty}
+
+  \section*{Hardwarenahe Programmierung\\
+            Übungsaufgaben -- 7.\ Januar 2021}
+
+  Diese Übung enthält Punkteangaben wie in einer Klausur.
+  Um zu "`bestehen"', müssen Sie innerhalb von 85 Minuten
+  unter Verwendung ausschließlich zugelassener Hilfsmittel
+  15 Punkte (von insgesamt \totalpoints) erreichen.
+
+  \exercise{Fakultät}
+
+  Die Fakultät $n!$ einer ganzen Zahl $n \ge 0$ ist definiert als:
+  \begin{eqnarray*}
+    1 & \mbox{für} & n = 0, \\
+    n \cdot (n-1)! & \mbox{für} & n > 0.
+  \end{eqnarray*}
+
+  Mit anderen Worten: $n! = 1\cdot2\cdot3\cdot\dots\cdot n$.
+
+  Die folgende Funktion \lstinline{fak()} berechnet die Fakultät \emph{rekursiv}
+  (Datei: \gitfile{hp}{2020ws/20210107}{aufgabe-1.c}):
+
+  \begin{lstlisting}
+    int fak (int n)
+    {
+      if (n <= 0)
+        return 1;
+      else
+        return n * fak (n - 1);
+    }
+  \end{lstlisting}
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Schreiben Sie eine Funktion, die die Fakultät \emph{iterativ} berechnet,\\
+      d.\,h.\ mit Hilfe einer Schleife anstelle von Rekursion.
+      \points{3}
+    \item
+      Wie viele Multiplikationen (Landau-Symbol)
+      erfordern beide Versionen der Fakultätsfunktion\\
+      in Abhängigkeit von \lstinline$n$?
+      Begründen Sie Ihre Antwort.
+      \points{2}
+    \item
+      Wieviel Speicherplatz (Landau-Symbol)
+      erfordern beide Versionen der Fakultätsfunktion\\
+      in Abhängigkeit von \lstinline$n$?
+      Begründen Sie Ihre Antwort.
+      \points{3}
+  \end{enumerate}
+
+  \exercise{Länge von Strings}
+
+  Diese Aufgabe ist eine Neuauflage von Aufgabe 3 der
+  Übung vom 10.\ Dezember 2020,\\
+  ergänzt um die Teilaufgaben (f) und (g).
+
+  \medskip
+
+  Strings werden in der Programmiersprache C durch Zeiger auf \lstinline{char}-Variable realisiert.
+
+  Beispiel: \lstinline{char *hello_world = "Hello, world!\n"}
+
+  Die Systembibliothek stellt eine Funktion \lstinline{strlen()} zur Ermittlung der Länge von Strings\\
+  zur Verfügung (\lstinline{#include <string.h>}).
+
+  \begin{enumerate}[\quad(a)]
+    \item
+      Auf welche Weise ist die Länge eines Strings gekennzeichnet?
+      \points{1}
+    \item
+      Wie lang ist die Beispiel-String-Konstante \lstinline{"Hello, world!\n"},
+      und wieviel Speicherplatz belegt sie?\\
+      \points{2}
+    \item
+      Schreiben Sie eine eigene Funktion \lstinline{int strlen (char *s)},
+      die die Länge eines Strings zurückgibt.\\
+      \points{3}
+  \end{enumerate}
+
+  \goodbreak
+
+  Wir betrachten nun die folgenden Funktionen (Datei: \gitfile{hp}{2020ws/20210107}{aufgabe-2.c}):
+  \begin{center}
+    \begin{minipage}{8cm}
+      \begin{lstlisting}[gobble=8]
+        int fun_1 (char *s)
+        {
+          int x = 0;
+          for (int i = 0; i < strlen (s); i++)
+            x += s[i];
+          return x;
+        }
+      \end{lstlisting}
+    \end{minipage}%
+    \begin{minipage}{6cm}
+      \vspace*{-1cm}
+      \begin{lstlisting}[gobble=8]
+        int fun_2 (char *s)
+        {
+          int i = 0, x = 0;
+          int len = strlen (s);
+          while (i < len)
+            x += s[i++];
+          return x;
+        }
+      \end{lstlisting}
+      \vspace*{-1cm}
+    \end{minipage}
+  \end{center}
+  \begin{enumerate}[\quad(a)]\setcounter{enumi}{3}
+    \item
+      Was bewirken die beiden Funktionen?
+      \points{2}
+    \item
+      Schreiben Sie eine eigene Funktion,
+      die dieselbe Aufgabe erledigt wie \lstinline{fun_2()},\\
+      nur effizienter.
+      \points{4}
+    \item
+      Von welcher Ordnung (Landau-Symbol) sind die beiden Funktionen
+      hinsichtlich der Anzahl ihrer Zugriffe auf die Zeichen im String?
+      Begründen Sie Ihre Antwort.
+      Sie dürfen für \lstinline{strlen()} Ihre eigene Version der Funktion voraussetzen.
+       \points{3}
+    \item
+      Von welcher Ordnung (Landau-Symbol) ist Ihre effizientere Funktion?\\
+      Begründen Sie Ihre Antwort.
+      \points{1}
+  \end{enumerate}
+
+  \exercise{Hexdumps}
+
+  Das folgende Programm (\gitfile{hp}{2020ws/20210107}{aufgabe-3.c}) liest
+  einen String ein und gibt die ASCII-Werte der Buchstaben hexadezimal aus.
+  (Anders als z.\,B.\ \lstinline{scanf()}
+  akzeptiert die Funktion \lstinline{fgets()} zum Lesen von Strings auch Leerzeichen,
+  und sie vermeidet Pufferüberläufe.)
+  \begin{lstlisting}[style=numbered]
+    #include <stdio.h>
+
+    int main (void)
+    {
+      char buffer[100];
+      fgets (buffer, 100, stdin);
+      for (char *p = buffer; *p; p++)
+        printf ("%02x", *p);
+      printf ("\n");
+    }
+  \end{lstlisting}
+  Beispiel: Bei der Eingabe von \lstinline[style=cmd]{Dies ist ein Test.}
+  erscheint die Ausgabe\\
+  \lstinline[style=terminal]{44696573206973742065696e20546573742e0a}.
+
+  Schreiben Sie ein Programm, das diese Umwandlung in umgekehrter Richtung vornimmt,
+  also z.\,B.\ bei Eingabe von \lstinline[style=cmd]{44696573206973742065696e20546573742e0a}
+  wieder \lstinline[style=terminal]{Dies ist ein Test.} ausgibt.
+
+  \points{6}
+
+  Hinweis für die Klausur:
+  Abgabe in digitaler Form ist erwünscht, aber nicht zwingend.
+
+  \begin{flushright}
+    \textit{Viel Erfolg!}
+  \end{flushright}
+
+  \makeatletter
+    \immediate\write\@mainaux{\string\gdef\string\totalpoints{\arabic{points}}}
+  \makeatother
+
+\end{document}
diff --git a/20210107/landau-symbols-2.pdf b/20210107/landau-symbols-2.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..6b458b6efd8e274824a6dfcaabc4b9c27d196dc4
--- /dev/null
+++ b/20210107/landau-symbols-2.pdf
@@ -0,0 +1 @@
+../common/landau-symbols-2.pdf
\ No newline at end of file
diff --git a/20210107/landau-symbols-3.pdf b/20210107/landau-symbols-3.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..46efa409b35ff5df763c744a423599cba515d886
--- /dev/null
+++ b/20210107/landau-symbols-3.pdf
@@ -0,0 +1 @@
+../common/landau-symbols-3.pdf
\ No newline at end of file
diff --git a/20210107/landau-symbols.pdf b/20210107/landau-symbols.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..ca145425bf07439c680632aa0663f84be601a565
--- /dev/null
+++ b/20210107/landau-symbols.pdf
@@ -0,0 +1 @@
+../common/landau-symbols.pdf
\ No newline at end of file
diff --git a/20210107/loesung-1.c b/20210107/loesung-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..c2d6f6003924627ae97831407c191eaac42a09c1
--- /dev/null
+++ b/20210107/loesung-1.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+int fak (int n)
+{
+  int f = 1;
+  for (int i = 2; i <= n; i++)
+    f *= i;
+  return f;
+}
+
+int main (void)
+{
+  for (int n = 0; n <= 5; n++)
+    printf ("%d\n", fak (n));
+  return 0;
+}
diff --git a/20210107/loesung-2c-1.c b/20210107/loesung-2c-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..69ddd0e4e749f6ca31bfa3d4f929c333648ef6ea
--- /dev/null
+++ b/20210107/loesung-2c-1.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int strlen (char *s)
+{
+  int l = 0;
+  while (s[l])
+    l++;
+  return l;
+}
+
+int main (void)
+{
+  printf ("%d\n", strlen ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20210107/loesung-2c-2.c b/20210107/loesung-2c-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..e783c474e485e80d08a6e86f8ae6e179f5a294f4
--- /dev/null
+++ b/20210107/loesung-2c-2.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int strlen (char *s)
+{
+  char *s0 = s;
+  while (*s)
+    s++;
+  return s - s0;
+}
+
+int main (void)
+{
+  printf ("%d\n", strlen ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20210107/loesung-2d-1.c b/20210107/loesung-2d-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..57521382c21fb743c6f5f5c65320bc4ac9360b1a
--- /dev/null
+++ b/20210107/loesung-2d-1.c
@@ -0,0 +1,34 @@
+
+#include <stdio.h>
+
+int strlen (char *s)
+{
+  int l = 0;
+  while (s[l])
+    l++;
+  return l;
+}
+
+int fun_1 (char *s)
+{
+  int x = 0;
+  for (int i = 0; i < strlen (s); i++)
+    x += s[i];
+  return x;
+}
+
+int fun_2 (char *s)
+{
+  int i = 0, x = 0;
+  int len = strlen (s);
+  while (i < len)
+    x += s[i++];
+  return x;
+}
+
+int main (void)
+{
+  printf ("%d\n", fun_1 ("Hello, world!\n"));
+  printf ("%d\n", fun_2 ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20210107/loesung-2d-2.c b/20210107/loesung-2d-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..5f3f0961129aa16fc9c4510ae21bb77b69913b12
--- /dev/null
+++ b/20210107/loesung-2d-2.c
@@ -0,0 +1,34 @@
+
+#include <stdio.h>
+
+int strlen (char *s)
+{
+  char *s0 = s;
+  while (*s)
+    s++;
+  return s - s0;
+}
+
+int fun_1 (char *s)
+{
+  int x = 0;
+  for (int i = 0; i < strlen (s); i++)
+    x += s[i];
+  return x;
+}
+
+int fun_2 (char *s)
+{
+  int i = 0, x = 0;
+  int len = strlen (s);
+  while (i < len)
+    x += s[i++];
+  return x;
+}
+
+int main (void)
+{
+  printf ("%d\n", fun_1 ("Hello, world!\n"));
+  printf ("%d\n", fun_2 ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20210107/loesung-2e-1.c b/20210107/loesung-2e-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..74f5add0c5f62cccb8f817d40f860893f496db11
--- /dev/null
+++ b/20210107/loesung-2e-1.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int fun_3 (char *s)
+{
+  int i = 0, x = 0;
+  while (s[i])
+    x += s[i++];
+  return x;
+}
+
+int main (void)
+{
+  printf ("%d\n", fun_3 ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20210107/loesung-2e-2.c b/20210107/loesung-2e-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..b223d2d17c261d7cf1373a8379def8911a45ccb7
--- /dev/null
+++ b/20210107/loesung-2e-2.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int fun_4 (char *s)
+{
+  int x = 0;
+  while (*s)
+    x += *s++;
+  return x;
+}
+
+int main (void)
+{
+  printf ("%d\n", fun_4 ("Hello, world!\n"));
+  return 0;
+}
diff --git a/20210107/loesung-3.c b/20210107/loesung-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..872058ac9fecdcb59ac1104ca67841cb3dc974a9
--- /dev/null
+++ b/20210107/loesung-3.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+
+int read_hex (char c)
+{
+  if (c >= '0' && c <= '9')
+    return c - '0';
+  else if (c >= 'A' && c <= 'F')
+    return c - 'A' + 10;
+  else if (c >= 'a' && c <= 'f')
+    return c - 'a' + 10;
+  else
+    {
+      fprintf (stderr, "invalid hex digit '%c'\n", c);
+      return 0;
+    }
+}
+
+int main (void)
+{
+  char buffer[100];
+  fgets (buffer, 100, stdin);
+  for (char *p = buffer; p[0] && p[1]; p += 2)
+    {
+      char c = 16 * read_hex (p[0]) + read_hex (p[1]);
+      printf ("%c", c);
+    }
+  printf ("\n");
+}
diff --git a/20210107/loesung-3d-0f.c b/20210107/loesung-3d-0f.c
new file mode 100644
index 0000000000000000000000000000000000000000..04b2d3e8956f4790b3f2ffdf3a314994c640513e
--- /dev/null
+++ b/20210107/loesung-3d-0f.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+typedef struct animal
+{
+  int type;
+  char *name;
+} animal;
+
+typedef struct with_wings
+{
+  int type;
+  char *name;
+  int wings;
+} with_wings;
+
+typedef struct with_legs
+{
+  int type;
+  char *name;
+  int legs;
+} with_legs;
+
+int main (void)
+{
+  animal *a[2];
+
+  animal duck;
+  a[0] = &duck;
+  a[0]->type = WITH_WINGS;
+  a[0]->name = "duck";
+  ((with_wings *) a[0])->wings = 2;
+
+  animal cow;
+  a[1] = &cow;
+  a[1]->type = WITH_LEGS;
+  a[1]->name = "cow";
+  ((with_legs *) a[1])->legs = 4;
+
+  for (int i = 0; i < 2; i++)
+    if (a[i]->type == WITH_LEGS)
+      printf ("A %s has %d legs.\n", a[i]->name,
+              ((with_legs *) a[i])-> legs);
+    else if (a[i]->type == WITH_WINGS)
+      printf ("A %s has %d wings.\n", a[i]->name,
+              ((with_wings *) a[i])-> wings);
+    else
+      printf ("Error in animal: %s\n", a[i]->name);
+
+  return 0;
+}
diff --git a/20210107/loesung-3d-1.c b/20210107/loesung-3d-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..349523a7d99e33ba81094ffbc8907773b5a3a251
--- /dev/null
+++ b/20210107/loesung-3d-1.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+typedef struct animal
+{
+  int type;
+  char *name;
+} animal;
+
+typedef struct with_wings
+{
+  int type;
+  char *name;
+  int wings;
+} with_wings;
+
+typedef struct with_legs
+{
+  int type;
+  char *name;
+  int legs;
+} with_legs;
+
+int main (void)
+{
+  animal *a[2];
+
+  with_wings duck;
+  a[0] = (animal *) &duck;
+  a[0]->type = WITH_WINGS;
+  a[0]->name = "duck";
+  ((with_wings *) a[0])->wings = 2;
+
+  with_legs cow;
+  a[1] = (animal *) &cow;
+  a[1]->type = WITH_LEGS;
+  a[1]->name = "cow";
+  ((with_legs *) a[1])->legs = 4;
+
+  for (int i = 0; i < 2; i++)
+    if (a[i]->type == WITH_LEGS)
+      printf ("A %s has %d legs.\n", a[i]->name,
+              ((with_legs *) a[i])-> legs);
+    else if (a[i]->type == WITH_WINGS)
+      printf ("A %s has %d wings.\n", a[i]->name,
+              ((with_wings *) a[i])-> wings);
+    else
+      printf ("Error in animal: %s\n", a[i]->name);
+
+  return 0;
+}
diff --git a/20210107/loesung-3d-2.c b/20210107/loesung-3d-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..f831a75eda1f3e784c8e6c1f24a83d9d6b55ee6c
--- /dev/null
+++ b/20210107/loesung-3d-2.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+typedef struct animal
+{
+  int type;
+  char *name;
+} animal;
+
+typedef struct with_wings
+{
+  int type;
+  char *name;
+  int wings;
+} with_wings;
+
+typedef struct with_legs
+{
+  int type;
+  char *name;
+  int legs;
+} with_legs;
+
+int main (void)
+{
+  animal *a[2];
+
+  with_wings duck;
+  a[0] = (animal *) &duck;
+  duck.type = WITH_WINGS;
+  duck.name = "duck";
+  duck.wings = 2;
+
+  with_legs cow;
+  a[1] = (animal *) &cow;
+  cow.type = WITH_LEGS;
+  cow.name = "cow";
+  cow.legs = 4;
+
+  for (int i = 0; i < 2; i++)
+    if (a[i]->type == WITH_LEGS)
+      printf ("A %s has %d legs.\n", a[i]->name,
+              ((with_legs *) a[i])-> legs);
+    else if (a[i]->type == WITH_WINGS)
+      printf ("A %s has %d wings.\n", a[i]->name,
+              ((with_wings *) a[i])-> wings);
+    else
+      printf ("Error in animal: %s\n", a[i]->name);
+
+  return 0;
+}
diff --git a/20210107/loesung-3e.c b/20210107/loesung-3e.c
new file mode 100644
index 0000000000000000000000000000000000000000..b984d9253b9c379a88f0fc0ca130c88c3103f8f3
--- /dev/null
+++ b/20210107/loesung-3e.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+typedef struct
+{
+  int type;
+  char *name;
+} base;
+
+typedef struct
+{
+  int type;
+  char *name;
+  int wings;
+} with_wings;
+
+typedef struct
+{
+  int type;
+  char *name;
+  int legs;
+} with_legs;
+
+typedef union
+{
+  base b;
+  with_wings w;
+  with_legs l;
+} animal;
+
+int main (void)
+{
+  animal *a[2];
+
+  animal duck;
+  a[0] = &duck;
+  duck.b.type = WITH_WINGS;
+  duck.b.name = "duck";
+  duck.w.wings = 2;
+
+  animal cow;
+  a[1] = &cow;
+  cow.b.type = WITH_LEGS;
+  cow.b.name = "cow";
+  cow.l.legs = 4;
+
+  for (int i = 0; i < 2; i++)
+    if (a[i]->b.type == WITH_LEGS)
+      printf ("A %s has %d legs.\n", a[i]->b.name,
+              a[i]->l.legs);
+    else if (a[i]->b.type == WITH_WINGS)
+      printf ("A %s has %d wings.\n", a[i]->b.name,
+              a[i]->w.wings);
+    else
+      printf ("Error in animal: %s\n", a[i]->b.name);
+
+  return 0;
+}
diff --git a/20210107/loesung-3f.c b/20210107/loesung-3f.c
new file mode 100644
index 0000000000000000000000000000000000000000..7b949e6365fc3839e6adc7661e0f8b4dd0c059df
--- /dev/null
+++ b/20210107/loesung-3f.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+typedef struct
+{
+  int type;
+  char *name;
+} base;
+
+typedef struct
+{
+  int type;
+  char *name;
+  int wings;
+} with_wings;
+
+typedef struct
+{
+  int type;
+  char *name;
+  int legs;
+} with_legs;
+
+typedef union
+{
+  base b;
+  with_wings w;
+  with_legs l;
+} animal;
+
+animal *new_with_wings (char *name, int wings)
+{
+  animal *a = malloc (sizeof (with_wings));
+  a->b.type = WITH_WINGS;
+  a->b.name = name;
+  a->w.wings = wings;
+  return a;
+}
+
+animal *new_with_legs (char *name, int legs)
+{
+  animal *a = malloc (sizeof (with_legs));
+  a->b.type = WITH_LEGS;
+  a->b.name = name;
+  a->l.legs = legs;
+  return a;
+}
+
+int main (void)
+{
+  animal *a[2] = { new_with_wings ("duck", 2),
+                   new_with_legs ("cow", 4) };
+
+  for (int i = 0; i < 2; i++)
+    if (a[i]->b.type == WITH_LEGS)
+      printf ("A %s has %d legs.\n", a[i]->b.name,
+              a[i]->l.legs);
+    else if (a[i]->b.type == WITH_WINGS)
+      printf ("A %s has %d wings.\n", a[i]->b.name,
+              a[i]->w.wings);
+    else
+      printf ("Error in animal: %s\n", a[i]->b.name);
+
+  return 0;
+}
diff --git a/20210107/loesung-3g.c b/20210107/loesung-3g.c
new file mode 100644
index 0000000000000000000000000000000000000000..b453a52dbe0ef27399255819808b3f6e562ba3ef
--- /dev/null
+++ b/20210107/loesung-3g.c
@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ANIMAL     0
+#define WITH_WINGS 1
+#define WITH_LEGS  2
+
+union animal;
+
+typedef struct
+{
+  int type;
+  char *name;
+  void (*print) (union animal *this);
+} base;
+
+typedef struct
+{
+  int type;
+  char *name;
+  void (*print) (union animal *this);
+  int wings;
+} with_wings;
+
+typedef struct
+{
+  int type;
+  char *name;
+  void (*print) (union animal *this);
+  int legs;
+} with_legs;
+
+typedef union animal
+{
+  base b;
+  with_wings w;
+  with_legs l;
+} animal;
+
+void print_with_wings (animal *this)
+{
+  printf ("A %s has %d wings.\n", this->b.name, this->w.wings);
+}
+
+void print_with_legs (animal *this)
+{
+  printf ("A %s has %d legs.\n", this->b.name, this->l.legs);
+}
+
+animal *new_with_wings (char *name, int wings)
+{
+  animal *a = malloc (sizeof (with_wings));
+  a->b.type = WITH_WINGS;
+  a->b.name = name;
+  a->b.print = print_with_wings;
+  a->w.wings = wings;
+  return a;
+}
+
+animal *new_with_legs (char *name, int legs)
+{
+  animal *a = malloc (sizeof (with_legs));
+  a->b.type = WITH_LEGS;
+  a->b.name = name;
+  a->b.print = print_with_legs;
+  a->l.legs = legs;
+  return a;
+}
+
+int main (void)
+{
+  animal *a[2] = { new_with_wings ("duck", 2),
+                   new_with_legs ("cow", 4) };
+  for (int i = 0; i < 2; i++)
+    a[i]->b.print (a[i]);
+  return 0;
+}
diff --git a/20210107/logo-hochschule-bochum-cvh-text-v2.pdf b/20210107/logo-hochschule-bochum-cvh-text-v2.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8
--- /dev/null
+++ b/20210107/logo-hochschule-bochum-cvh-text-v2.pdf
@@ -0,0 +1 @@
+../common/logo-hochschule-bochum-cvh-text-v2.pdf
\ No newline at end of file
diff --git a/20210107/logo-hochschule-bochum.pdf b/20210107/logo-hochschule-bochum.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1
--- /dev/null
+++ b/20210107/logo-hochschule-bochum.pdf
@@ -0,0 +1 @@
+../common/logo-hochschule-bochum.pdf
\ No newline at end of file
diff --git a/20210107/pendulum.pdf b/20210107/pendulum.pdf
new file mode 120000
index 0000000000000000000000000000000000000000..7d1d87305cdb8840a248ff2207538d758464f452
--- /dev/null
+++ b/20210107/pendulum.pdf
@@ -0,0 +1 @@
+../common/pendulum.pdf
\ No newline at end of file
diff --git a/20210107/pgscript.sty b/20210107/pgscript.sty
new file mode 120000
index 0000000000000000000000000000000000000000..95c888478c99ea7fda0fd11ccf669ae91be7178b
--- /dev/null
+++ b/20210107/pgscript.sty
@@ -0,0 +1 @@
+../common/pgscript.sty
\ No newline at end of file
diff --git a/20210107/pgslides.sty b/20210107/pgslides.sty
new file mode 120000
index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64
--- /dev/null
+++ b/20210107/pgslides.sty
@@ -0,0 +1 @@
+../common/pgslides.sty
\ No newline at end of file