diff --git a/20181119/hp-musterloesung-20181119.tex b/20181119/hp-musterloesung-20181119.tex
index 4e44498e8dd279111dfb34bfeb949e9753e03eb3..dff2f028b51825a80b4b390f6c7a2dc227a9c907 100644
--- a/20181119/hp-musterloesung-20181119.tex
+++ b/20181119/hp-musterloesung-20181119.tex
@@ -1,5 +1,5 @@
-% hp-musterloesung-20181112.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
-% Copyright (C) 2013, 2015, 2016, 2017, 2018  Peter Gerwinski
+% hp-musterloesung-20181119.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019  Peter Gerwinski
 %
 % This document is free software: you can redistribute it and/or
 % modify it either under the terms of the Creative Commons
diff --git a/20181126/hp-musterloesung-20181126.tex b/20181126/hp-musterloesung-20181126.tex
index af48f54a7d95305af2327f19875ae154accce80e..5278288de1979f7b048bf672668fbcecd49a96ac 100644
--- a/20181126/hp-musterloesung-20181126.tex
+++ b/20181126/hp-musterloesung-20181126.tex
@@ -1,5 +1,5 @@
-% hp-musterloesung-20181112.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
-% Copyright (C) 2013, 2015, 2016, 2017, 2018  Peter Gerwinski
+% hp-musterloesung-20181126.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019  Peter Gerwinski
 %
 % This document is free software: you can redistribute it and/or
 % modify it either under the terms of the Creative Commons
diff --git a/20181203/hp-musterloesung-20181203.pdf b/20181203/hp-musterloesung-20181203.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..c04ed216c89605746bacccae02999f4d865577d0
Binary files /dev/null and b/20181203/hp-musterloesung-20181203.pdf differ
diff --git a/20181203/hp-musterloesung-20181203.tex b/20181203/hp-musterloesung-20181203.tex
new file mode 100644
index 0000000000000000000000000000000000000000..a17574ca126ab20a36cfe7394521affc53c61010
--- /dev/null
+++ b/20181203/hp-musterloesung-20181203.tex
@@ -0,0 +1,275 @@
+% hp-musterloesung-20181203.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019  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: XBM-Grafik, LED-Blinkmuster
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+\usepackage{sfmath}
+
+\begin{document}
+
+  \section*{Hardwarenahe Programmierung\\
+            Musterlösung zu den Übungsaufgaben -- 3.\ Dezember 2018}
+
+  \exercise{XBM-Grafik}
+
+  Bei einer XBM-Grafikdatei handelt es sich
+  um ein als C-Quelltext abgespeichertes Array,
+  das die Bildinformationen enthält:
+  \begin{itemize}\itemsep0pt
+    \item Jedes Bit entspricht einem Pixel.
+    \item Nullen stehen für Weiß, Einsen für Schwarz.
+    \item Das Bit mit Zahlenwert 1 steht für einen Bildpunkt ganz links im Byte,
+          das Bit mit Zahlenwert 128 für einen Bildpunkt ganz rechts.
+          (Diese Bit-Reihenfolge heißt \newterm{LSB first}.)
+    \item Jede Zeile des Bildes wird auf ganze Bytes aufgefüllt.
+    \item Breite und Höhe des Bildes sind als Konstantendefinitionen
+          (\lstinline{#define}) in der Datei enthalten.
+  \end{itemize}
+  Sie können eine XBM-Datei sowohl mit einem Texteditor
+  als auch mit vielen Grafikprogrammen öffnen und bearbeiten.
+
+  Beispiel (\gitfile{hp}{20181203}{aufgabe-1.xbm}):\hfill
+  \makebox(0,0)[tr]{\framebox{\includegraphics[scale=3]{aufgabe-1.png}}}
+  \begin{lstlisting}
+    #define aufgabe_1_width 14
+    #define aufgabe_1_height 14
+    static unsigned char aufgabe_1_bits[] = {
+       0x00, 0x00, 0xf0, 0x03, 0x08, 0x04, 0x04, 0x08, 0x02, 0x10, 0x32, 0x13,
+       0x22, 0x12, 0x02, 0x10, 0x0a, 0x14, 0x12, 0x12, 0xe4, 0x09, 0x08, 0x04,
+       0xf0, 0x03, 0x00, 0x00 };
+  \end{lstlisting} 
+  Ein C-Programm, das eine XBM-Grafik nutzen will,
+  kann die \file{.xbm}-Datei mit \lstinline{#include "..."} direkt einbinden.
+
+  Schreiben Sie ein Programm, das die XBM-Datei als ASCII-Grafik ausgibt, z.\,B.:
+  \begin{lstlisting}[style=terminal,lineskip=-4pt]
+                  
+        ******    
+       *      *   
+      *        *  
+     *          * 
+     *  **  **  * 
+     *   *   *  * 
+     *          * 
+     * *      * * 
+     *  *    *  * 
+      *  ****  *  
+       *      *   
+        ******    
+    ¡              ¿
+  \end{lstlisting}
+  \points{8}
+
+  (Hinweis für die Klausur: Abgabe auf Datenträger ist erlaubt und erwünscht,
+  aber nicht zwingend.)
+
+  \solution
+
+  Siehe die Datei \gitfile{hp}{20181203}{loesung-1.c}.
+
+  Der Ausdruck \lstinline{(aufgabe_3_width + 7) / 8}
+  ist die auf ganze Bytes aufgerundete Breits des Bildes in Bytes.
+  Ohne das "`\lstinline{+ 7}"' in der Klammer würde stets abgerundet;
+  die Breite von Bildern, deren Breite kein Vielfaches von 8 ist,
+  wäre dann immer um 1 zu klein.
+  Dadurch daß wir $n - 1$ addieren, bevor wir durch $n$ dividieren,
+  machen wir aus dem Abrunden ein Aufrunden.
+
+  In jedem Durchlauf der äußeren Schleife
+  wird der Zeiger \lstinline{p} auf den Anfang der Zeile \lstinline{i} des Bildes gesetzt.
+
+  Innerhalb der Zeile gehen wir mit einer Bit-Maske \lstinline{mask}
+  die Bits innerhalb des Bytes \lstinline{*p} von rechts nach links durch (LSB first).
+  Wenn das Bit aus der Maske links herausgeschoben wird,
+  setzen wir die Maske auf \lstinline{0x01} zurück
+  und setzen den Zeiger \lstinline{p} auf das nächste Byte.
+
+  (Der Datentyp \lstinline{unsigned char}
+  ist eine vorzeichenlose ganze Zahl von der Größe einer Speicherzelle
+  und normalerweise identisch mit \lstinline{uint8_t}.
+  Da das XBM-Dateiformat den Datentyp \lstinline{unsigned char} verwendet,
+  geschieht dies auch im Programm \gitfile{hp}{20181203}{loesung-1.c};
+  ansonsten wäre \lstinline{uint8_t} eine bessere Wahl.)
+
+  \exercise{LED-Blinkmuster}
+
+  Wir betrachten das folgende Programm für einen ATmega32-Mikro-Controller
+  (Datei: \gitfile{hp}{20180108}{aufgabe-2.c}).
+
+  \begin{minipage}[t]{7cm}
+    \begin{lstlisting}[gobble=6]
+      #include <stdint.h>
+      #include <avr/io.h>
+      #include <avr/interrupt.h>
+
+      uint8_t counter = 1;
+      uint8_t leds = 0;
+
+      ISR (TIMER0_COMP_vect)
+      {
+        if (counter == 0)
+          {
+            leds = (leds + 1) % 8;
+            PORTC = leds << 4;
+          }
+        counter++;
+      }
+    \end{lstlisting}
+  \end{minipage}\hfill\begin{minipage}[t]{8.5cm}
+    \begin{lstlisting}[gobble=6]
+      void init (void)
+      {
+        cli ();
+        TCCR0 = (1 << CS01) | (1 << CS00);
+        TIMSK = 1 << OCIE0;
+        sei ();
+        DDRC = 0x70;
+      }
+
+      int main (void)
+      {
+        init ();
+        while (1)
+          ; /* do nothing */
+        return 0;
+      }
+    \end{lstlisting}
+  \end{minipage}
+
+  An die Bits Nr.\ 4, 5 und 6 des Output-Ports C des Mikro-Controllers sind LEDs angeschlossen.\\
+  Sobald das Programm läuft, blinken diese in charakteristischer Weise:
+  \begin{quote}
+    \newcommand{\tdn}[1]{\raisebox{-2pt}{#1}}
+    \begin{tabular}{|c|c|c|c|}\hline
+      \tdn{Phase} & \tdn{LED oben (rot)} & \tdn{LED Mitte (gelb)} & \tdn{LED unten (grün)} \\[2pt]\hline
+      1 & aus & aus & an  \\\hline
+      2 & aus & an  & aus \\\hline
+      3 & aus & an  & an  \\\hline
+      4 & an  & aus & aus \\\hline
+      5 & an  & aus & an  \\\hline
+      6 & an  & an  & aus \\\hline
+      7 & an  & an  & an  \\\hline
+      8 & aus & aus & aus \\\hline
+    \end{tabular}
+  \end{quote}
+  % 8000000 / 64 = 125000
+  % 8000000 / 64 / 256 = 488.28125
+  % 8000000 / 64 / 256 / 256 = 1.9073486328125
+  Jede Phase dauert etwas länger als eine halbe Sekunde.
+  Nach 8 Phasen wiederholt sich das Schema.
+
+  Erklären Sie das Verhalten des Programms anhand des Quelltextes:
+  \vspace{-\medskipamount}
+  \begin{itemize}\itemsep0pt
+    \item[(a)]
+      Wieso macht das Programm überhaupt etwas,
+      wenn doch das Hauptprogramm nach dem Initialisieren lediglich eine Endlosschleife ausführt,
+      in der \emph{nichts} passiert?
+      \points{1}
+    \item[(b)]
+      Wieso wird die Zeile \lstinline|PORTC = leds << 4;| überhaupt aufgerufen,
+      wenn dies doch nur unter der Bedingung \lstinline|counter == 0| passiert,
+      wobei die Variable \lstinline|counter| auf 1 initialisiert,
+      fortwährend erhöht und nirgendwo zurückgesetzt wird?
+      \points{2}
+    \item[(c)]
+      Wie kommt das oben beschriebene Blinkmuster zustande?
+      \points{2}
+    \item[(d)]
+      Wieso dauert eine Phase ungefähr eine halbe Sekunde?
+      \points{2}
+    \item[(e)]
+      Was bedeutet "`\lstinline|ISR (TIMER0_COMP_vect)|"'?
+      \points{1}
+  \end{itemize}
+
+  Hinweis:
+  \vspace{-\medskipamount}
+  \begin{itemize}\itemsep0pt
+    \item
+      Die Funktion \lstinline|init()| sorgt dafür, daß der Timer-Interrupt Nr.\ 0 des Mikro-Controllers
+      etwa 488mal pro Sekunde aufgerufen wird.
+      Außerdem % schaltet sie eventuell an Port B angeschlossene weitere LEDs aus und
+      initialisiert sie die benötigten Bits an Port C als Output-Ports.
+      Sie selbst brauchen die Funktion \lstinline|init()| nicht weiter zu erklären.
+%    \item
+%      Während der Übung können Sie sich das Verhalten des Programms
+%      an einem RP6-Roboter vorführen lassen.
+  \end{itemize}
+
+  \clearpage
+  \solution
+
+  \begin{itemize}\itemsep0pt
+    \item[(a)]
+      \textbf{Wieso macht das Programm überhaupt etwas,
+      wenn doch das Hauptprogramm nach dem Initialisieren lediglich eine Endlosschleife ausführt,
+      in der \emph{nichts} passiert?}
+
+      Das Blinken wird durch einen Interrupt-Handler implementiert.
+      Dieser wird nicht durch das Hauptprogramm,
+      sondern durch ein Hardware-Ereignis (hier: Uhr) aufgerufen.
+
+    \item[(b)]
+      \textbf{Wieso wird die Zeile \lstinline|PORTC = leds << 4;| überhaupt aufgerufen,
+      wenn dies doch nur unter der Bedingung \lstinline|counter == 0| passiert,
+      wobei die Variable \lstinline|counter| auf 1 initialisiert,
+      fortwährend erhöht und nirgendwo zurückgesetzt wird?}
+
+      Die vorzeichenlose 8-Bit-Variable \lstinline{counter} kann nur
+      Werte von 0 bis 255 annehmen; bei einem weiteren
+      INkrementieren springt sie wieder auf 0 (Überlauf),
+      und die \lstinline{if}-Bedingung ist erfüllt.
+
+    \item[(c)]
+      \textbf{Wie kommt das oben beschriebene Blinkmuster zustande?}
+
+      In jedem Aufruf des Interrupt-Handlers wird die Variable
+      \lstinline{leds} um 1 erhöht und anschließend modulo 8 genommen.
+      Sie durchläuft daher immer wieder die Zahlen von 0 bis 7.
+
+      Durch die Schiebeoperation \lstinline{leds << 4} werden die 3 Bits 
+      der Variablen \lstinline{leds} an diejenigen Stellen im Byte
+      geschoben, an denen die LEDs an den Mikro-Controller
+      angeschlossen sind (Bits 4, 5 und 6).
+
+      Entsprechend durchläuft das Blinkmuster immer wieder
+      die Binärdarstellungen der Zahlen von 0 bis 7
+      (genauer: von 1 bis 7 und danach 0).
+
+    \item[(d)]
+      \textbf{Wieso dauert eine Phase ungefähr eine halbe Sekunde?}
+
+      Der Interrupt-Handler wird gemäß Hinweis 488mal pro Sekunde aufgerufen.
+      Bei jedem 256sten Aufruf ändert sich das LED-Muster.
+      Eine Phase dauert somit $\frac{256}{488} \approx 0.52$ Sekunden.
+
+    \item[(e)]
+      \textbf{Was bedeutet "`\lstinline|ISR (TIMER0_COMP_vect)|"'?}
+
+      Deklaration eines Interrupt-Handlers für den Timer-Interrupt Nr.\ 0
+  \end{itemize}
+
+\end{document}
diff --git a/20181210/hp-musterloesung-20181210.pdf b/20181210/hp-musterloesung-20181210.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..e49a72d2b2e879886e1d051d00b6ccc3e1790800
Binary files /dev/null and b/20181210/hp-musterloesung-20181210.pdf differ
diff --git a/20181210/hp-musterloesung-20181210.tex b/20181210/hp-musterloesung-20181210.tex
new file mode 100644
index 0000000000000000000000000000000000000000..655b9be4345ea22435674ca06a841701dca0773e
--- /dev/null
+++ b/20181210/hp-musterloesung-20181210.tex
@@ -0,0 +1,266 @@
+% hp-musterloesung-20181210.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019  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: Trickprogrammierung, Thermometer-Baustein an I²C-Bus
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+\usepackage{gensymb}
+\usepackage{sfmath}
+
+\newcommand{\ItwoC}{I\raisebox{0.5ex}{\footnotesize 2}C}
+\newcommand{\ITWOC}{I\raisebox{0.5ex}{\normalsize 2}C}
+
+\begin{document}
+
+  \section*{Hardwarenahe Programmierung\\
+            Musterlösung zu den Übungsaufgaben -- 10.\ Dezember 2018}
+
+  \exercise{Trickprogrammierung}
+
+  Wir betrachten das folgende Programm (Datei: \gitfile{hp}{20181210}{aufgabe-1.c}):
+  \begin{lstlisting}
+    #include <stdio.h>
+    #include <stdint.h>
+
+    int main (void)
+    {
+      uint64_t x = 4262939000843297096;
+      char *s = &x;
+      printf ("%s\n", s);
+      return 0;
+    }
+  \end{lstlisting}
+  Das Programm wird compiliert und auf einem 64-Bit-Little-Endian-Computer ausgeführt:
+  \begin{lstlisting}[style=terminal]
+    $ ¡gcc -Wall -O aufgabe-1.c -o aufgabe-1¿
+    aufgabe-1.c: In function `main':
+    aufgabe-1.c:7:13: warning: initialization from incompatible pointer type [...]
+    $ ¡./aufgabe-1¿
+    Hallo
+  \end{lstlisting}
+
+  \begin{itemize}
+    \item[(a)]
+      Erklären Sie die Warnung beim Compilieren. \points{2}
+    \item[(b)]
+      Erklären Sie die Ausgabe des Programms. \points{5}
+    \item[(c)]
+      Wie würde die Ausgabe des Programms auf einem 64-Bit-Big-Endian-Computer lauten? \points{3}
+  \end{itemize}
+  Hinweis: Modifizieren Sie das Programm
+  und lassen Sie sich Speicherinhalte ausgeben.
+
+  \solution
+
+  \begin{itemize}
+    \item[(a)]
+      \textbf{Erklären Sie die Warnung beim Compilieren.}
+
+      Zeile 7 des Programms enthält eine Zuweisung von \lstinline{&x}
+      an die Variable \lstinline{s}.
+      Der Ausdruck \lstinline{&x} steht für die Speicheradresse der Variablen \lstinline{x},
+      ist also ein Zeiger auf \lstinline{x},
+      also ein Zeiger auf eine \lstinline{uint64_t}.
+      Die Variable \lstinline{s} hingegen ist ein Zeiger auf \lstinline{char},
+      also ein Zeiger auf eine viel kleinere Zahl,
+      also ein anderer Zeigertyp.
+
+    \item[(b)]
+      \textbf{Erklären Sie die Ausgabe des Programms.}
+
+      Die 64-Bit-Zahl (\lstinline{uint64_t}) \lstinline{x}
+      belegt 8 Speicherzellen (Bytes) von jeweils 8 Bit.
+      Um herauszufinden, was diese enthalten,
+      lassen wir uns \lstinline{x} als Hexadezimalzahl ausgeben,
+      z.\,B.\ mittels \lstinline{printf ("%lx\n", x)}
+      (auf 32-Bit-Rechnern: \lstinline{"%llx\n"})
+      oder mittels \lstinline{printf ("%" PRIx64 "\n", x)}
+      (erfordert \lstinline{#include <inttypes.h>}
+      -- siehe die Datei \gitfile{hp}{20181210}{loesung-1-1.c}).
+      Das Ergebnis lautet:
+      \begin{lstlisting}[style=terminal,gobble=8]
+        3b29006f6c6c6148
+      \end{lstlisting}
+      Auf einzelne Bytes verteilt:
+      \begin{lstlisting}[style=terminal,gobble=8]
+        3b 29 00 6f 6c 6c 61 48
+      \end{lstlisting}
+      Auf einem Little-Endian-Rechner
+      ist die Reihenfolge der Bytes in den Speicherzellen genau umgekehrt:
+      \begin{lstlisting}[style=terminal,gobble=8]
+        48 61 6c 6c 6f 00 29 3b
+      \end{lstlisting}
+      Wenn wir uns diese Bytes als Zeichen ausgeben lassen
+      (\lstinline{printf()} mit \lstinline{%c} -- siehe die Datei \gitfile{hp}{20181210}{loesung-1-2.c}),
+      erhalten wir:
+      \begin{lstlisting}[style=terminal,gobble=8]
+        H a l l o  ) ;
+      \end{lstlisting}
+      Das Zeichen hinter "`Hallo"' ist ein Null-Symbol (Zahlenwert 0)
+      und wird von \lstinline{printf ("%s")} als Ende des Strings erkannt.
+      Damit ist die Ausgabe \lstinline[style=terminal]{Hallo}
+      des Programms erklärt.
+
+    \goodbreak
+    \item[(c)]
+      \textbf{Wie würde die Ausgabe des Programms auf einem 64-Bit-Big-Endian-Computer lauten?}
+
+      Auf einem Big-Endian-Computer (egal, wieviele Bits die Prozessorregister haben)
+      ist die Reihenfolge der Bytes in den Speicherzellen genau umgekehrt
+      wie auf einem Little-Endian-Computer, hier also:
+      \begin{lstlisting}[style=terminal,gobble=8]
+        3b 29 00 6f 6c 6c 61 48
+      \end{lstlisting}
+      \lstinline{printf ("%s")} gibt in diesem Fall die Hexadezimalzahlen
+      \lstinline[style=terminal]{3b} und \lstinline[style=terminal]{29}
+      als Zeichen aus. Danach steht das String-Ende-Symbol mit Zahlenwert 0,
+      und die Ausgabe bricht ab.
+      Da, wie oben ermittelt, die Hexadezimalzahl \lstinline[style=terminal]{3b}
+      für das Zeichen \lstinline[style=terminal]{;}
+      und \lstinline[style=terminal]{29}
+      für das Zeichen \lstinline[style=terminal]{)} steht,
+      lautet somit die Ausgabe:
+      \begin{lstlisting}[style=terminal,gobble=8]
+        ;)
+      \end{lstlisting}
+      Um die Aufgabe zu lösen, können Sie übrigens auch
+      auf einem Little-Endian-Computer (Standard-Notebook)
+      einen Big-Endian-Computer simulieren,
+      indem Sie die Reihenfolge der Bytes in der Zahl \lstinline{x} umdrehen
+      -- siehe die Datei \gitfile{hp}{20181210}{loesung-1-3.c}.
+  \end{itemize}
+
+  \exercise{Thermometer-Baustein an \ITWOC-Bus}
+
+  Eine Firma stellt einen elektronischen Thermometer-Baustein her,
+  den man über die serielle Schnittstelle (RS-232) an einen PC anschließen kann,
+  um die Temperatur auszulesen.
+  Nun wird eine Variante des Thermo"-meter-Bausteins entwickelt,
+  die die Temperatur zusätzlich über einen \ItwoC-Bus bereitstellt.
+
+  Um das neue Thermometer zu testen, wird es in ein Gefäß mit heißem Wasser gelegt,
+  das langsam auf Zimmertemperatur abkühlt.
+  Alle 10 Minuten liest ein Programm, das auf dem PC läuft,
+  die gemessene Temperatur über beide Schnittstellen aus
+  und erzeugt daraus die folgende Tabelle:
+
+  \begin{center}
+    \renewcommand{\arraystretch}{1.2}
+    \begin{tabular}{|c|c|c|}\hline
+      Zeit /\,min. & Temperatur per RS-232 /\,\degree C & Temperatur per \ItwoC\ /\,\degree C \\\hline\hline
+      \phantom{0}0 & 94 & 122 \\\hline
+      10 & 47 & 244 \\\hline
+      20 & 30 & 120 \\\hline
+      30 & 24 & \phantom{0}24 \\\hline
+      40 & 21 & 168 \\\hline
+    \end{tabular}
+  \end{center}
+
+  \begin{itemize}
+    \item[(a)]
+      Aus dem Vergleich der Meßdaten läßt sich
+      auf einen Fehler bei der \ItwoC-Übertragung schließen.\\
+      Um welchen Fehler handelt es sich,
+      und wie ergibt sich dies aus den Meßdaten?
+      \points{5}
+    \item[(b)]
+      Schreiben Sie eine C-Funktion \lstinline{uint8_t repair (uint8_t data)},
+      die eine über den \ItwoC-Bus empfangene fehlerhafte Temperatur \lstinline{data} korrigiert.
+      \points{5}
+  \end{itemize}
+
+  \solution
+
+  \begin{itemize}
+    \item[(a)]
+      \textbf{Aus dem Vergleich der Meßdaten läßt sich
+      auf einen Fehler bei der \ItwoC-Übertragung schließen.
+      Um welchen Fehler handelt es sich,
+      und wie ergibt sich dies aus den Meßdaten?}
+
+      Sowohl RS-232 als auch \ItwoC\ übertragen die Daten Bit für Bit.
+      Für die Fehlersuche ist es daher sinnvoll,
+      die Meßwerte als Binärzahlen zu betrachten:
+
+      \begin{center}
+        \renewcommand{\arraystretch}{1.2}
+        \begin{tabular}{|c|c|c|}\hline
+          Zeit /\,min. & Temperatur per RS-232 /\,\degree C & Temperatur per \ItwoC\ /\,\degree C \\\hline\hline
+          \phantom{0}0 & 94$_{10}$ = 01011110$_2$ & 122$_{10}$           = 01111010$_2$ \\\hline
+          10           & 47$_{10}$ = 00101111$_2$ & 244$_{10}$           = 11110100$_2$ \\\hline
+          20           & 30$_{10}$ = 00011110$_2$ & 120$_{10}$           = 01111000$_2$ \\\hline
+          30           & 24$_{10}$ = 00011000$_2$ & \phantom{0}24$_{10}$ = 00011000$_2$ \\\hline
+          40           & 21$_{10}$ = 00010101$_2$ & 168$_{10}$           = 10101000$_2$ \\\hline
+        \end{tabular}
+      \end{center}
+
+      Man erkennt, daß die Reihenfolge der Bits in den (fehlerhaften) \ItwoC-Meßwerten
+      genau die umgekehrte Reihenfolge der Bits in den (korrekten) RS-232-Mewßwerten ist.
+      Der Übertragungsfehler besteht also darin,
+      daß die Bits in der falschen Reihenfolge übertragen wurden.
+
+      Dies paßt gut damit zusammen,
+      daß die Bit-Reihenfolge von \ItwoC\ \emph{MSB First}, die von RS-232 hingegen \emph{LSB First\/} ist.
+      Offenbar haben die Entwickler der \ItwoC-Schnittstelle dies übersehen
+      und die \ItwoC-Daten ebenfalls \emph{LSB First\/} übertragen.
+
+    \goodbreak
+    \item[(b)]
+      \textbf{Schreiben Sie eine C-Funktion \lstinline{uint8_t repair (uint8_t data)},
+      die eine über den \ItwoC-Bus empfangene fehlerhafte Temperatur \lstinline{data} korrigiert.}
+
+      Die Aufgabe der Funktion besteht darin,
+      eine 8-Bit-Zahl \lstinline{data} entgegenzunehmen,
+      die Reihenfolge der 8 Bits genau umzudrehen
+      und das Ergebnis mittels \lstinline{return} zurückzugeben.
+
+      Zu diesem Zweck gehen wir die 8 Bits in einer Schleife durch
+      -- siehe die Datei \gitfile{hp}{20181210}{loesung-2.c}.
+      Wir lassen eine Lese-Maske \lstinline{mask_data} von rechts nach links
+      und gleichzeitig eine Schreib-Maske \lstinline{mask_result}
+      von links nach rechts wandern.
+      Immer wenn die Lese-Maske in \lstinline{data} eine 1 findet,
+      schreibt die Schreib-Maske diese in die Ergebnisvariable \lstinline{result}.
+
+      Da \lstinline{result} auf 0 initialisiert wurde,
+      brauchen wir Nullen nicht hineinzuschreiben.
+      Ansonsten wäre dies mit \lstinline{result &= ~mask_result} möglich.
+
+      Um die Schleife bis 8 zählen zu lassen,
+      könnte man eine weitere Zähler-Variable von 0 bis 7 zählen lassen,
+      z.\,B.\ \lstinline{for (int i = 0; i < 8; i++)}.
+      Dies ist jedoch nicht nötig, wenn man beachtet,
+      daß die Masken den Wert 0 annehmen,
+      sobald das Bit aus der 8-Bit-Variablen herausgeschoben wurde.
+      In \gitfile{hp}{20181210}{loesung-2.c} wird \lstinline{mask_data} auf 0 geprüft;
+      genausogut könnte man auch \lstinline{mask_result} prüfen.
+
+      Das \lstinline{return result} ist notwendig.
+      Eine Ausgabe des Ergebnisses per \lstinline{printf()} o.\,ä.\
+      erfüllt \emph{nicht\/} die Aufgabenstellung.
+      (In \gitfile{hp}{20181210}{loesung-2.c} erfolgt entsprechend \lstinline{printf()}
+      nur im Testprogramm \lstinline{main()}.)
+  \end{itemize}
+
+\end{document}
diff --git a/20181210/loesung-1-1.c b/20181210/loesung-1-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..26fcc817796b3da118b5dda92f45bfb870e315b6
--- /dev/null
+++ b/20181210/loesung-1-1.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+int main (void)
+{
+  uint64_t x = 4262939000843297096;
+  char *s = &x;
+  printf ("%lx\n", x);
+  printf ("%" PRIx64 "\n", x);
+  printf ("%s\n", s);
+  return 0;
+}
diff --git a/20181210/loesung-1-2.c b/20181210/loesung-1-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..7151db69b2e675f17517d7b7c3814bbda3b1fa89
--- /dev/null
+++ b/20181210/loesung-1-2.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+int main (void)
+{
+  uint64_t x = 4262939000843297096;
+  char *s = &x;
+  printf ("%lx\n", x);
+  printf ("%" PRIx64 "\n", x);
+  printf ("%c %c %c %c %c %c %c %c\n",
+          0x48, 0x61, 0x6c, 0x6c, 0x6f, 0x00, 0x29, 0x3b);
+  printf ("%s\n", s);
+  return 0;
+}
diff --git a/20181210/loesung-1-3.c b/20181210/loesung-1-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..fadccdef1155e4d16b5da0c8a82d8e7ae76ca3cc
--- /dev/null
+++ b/20181210/loesung-1-3.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+int main (void)
+{
+  uint64_t x = 0x48616c6c6f00293b;
+  char *s = &x;
+  printf ("%s\n", s);
+  return 0;
+}
diff --git a/20181210/loesung-2.c b/20181210/loesung-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..b02d98b51b9bc525a567afea2f0dce5a8e6413a5
--- /dev/null
+++ b/20181210/loesung-2.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdint.h>
+
+uint8_t repair (uint8_t data)
+{
+  uint8_t result = 0;
+  uint8_t mask_data = 0x01;
+  uint8_t mask_result = 0x80;
+  while (mask_data)
+    {
+      if (data & mask_data)
+        result |= mask_result;
+      mask_data <<= 1;
+      mask_result >>= 1;
+    }
+  return result;
+}
+
+int main (void)
+{
+  int data[] = { 122, 244, 120, 24, 168, -1 };
+  int i = 0;
+  while (data[i] >= 0)
+    printf ("%d\n", repair (data[i++]));
+  return 0;
+}
diff --git a/20181217/hp-musterloesung-20181217.pdf b/20181217/hp-musterloesung-20181217.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..bd59e3f1d9892bb04c4d67e2f9a54ea764110632
Binary files /dev/null and b/20181217/hp-musterloesung-20181217.pdf differ
diff --git a/20181217/hp-musterloesung-20181217.tex b/20181217/hp-musterloesung-20181217.tex
new file mode 100644
index 0000000000000000000000000000000000000000..bda69709b736dbeb8a8a79cb05eef6aa00ac1af6
--- /dev/null
+++ b/20181217/hp-musterloesung-20181217.tex
@@ -0,0 +1,554 @@
+% hp-musterloesung-20181217.pdf - Solutions to the Exercises on Low-Level Programming / Applied Computer Sciences
+% Copyright (C) 2013, 2015, 2016, 2017, 2018, 2019  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, Lauflicht, Länge von Strings (Neuauflage)
+
+\documentclass[a4paper]{article}
+
+\usepackage{pgscript}
+\usepackage{sfmath}
+
+\begin{document}
+
+  \section*{Hardwarenahe Programmierung\\
+            Musterlösung zu den Übungsaufgaben -- 17.\ Dezember 2018}
+
+  \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}{20181217}{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}{20181217}{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 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?}
+
+      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{Lauflicht}
+
+  \begin{minipage}[t]{8cm}
+    An die vier Ports eines ATmega16-Mikrocontrollers sind Leuchtdioden angeschlossen:
+    \begin{itemize}
+      \item
+        von links nach rechts\\
+        an die Ports A, B, C und D,
+      \item
+        von oben nach unten\\
+        an die Bits Nr.\ 0 bis 7.
+
+        \bigskip
+
+        \includegraphics[width=3cm]{leds.jpg}
+    \end{itemize}
+  \end{minipage}\hfill
+  \begin{minipage}[t]{7cm}
+    Wir betrachten das folgende C-Programm (Datei: \gitfile{hp}{20181217}{aufgabe-2.c})
+    für diesen Mikrocontroller:
+
+    \begin{lstlisting}[gobble=6]
+      #include <avr/io.h>
+      #include <avr/interrupt.h>
+
+      int counter = 0;
+
+      ISR (TIMER0_COMP_vect)
+      {
+        PORTA = 1 << ((counter++ >> 6) & 7);
+      }
+
+      int main (void)
+      {
+        cli ();
+        TCCR0 = (1 << CS01) | (1 << CS00);
+        TIMSK = 1 << OCIE0;
+        sei ();
+        DDRA = 0xff;
+        while (1);
+        return 0;
+      }
+    \end{lstlisting}
+  \end{minipage}
+
+  \medskip
+
+  Das Programm bewirkt ein periodisches Lauflicht in der linken Spalte von oben nach unten.
+  Eine Animation davon finden Sie in der Datei \gitfile{hp}{20181217}{aufgabe-2.gif}.
+
+  \begin{itemize}
+    \item[(a)]
+      Wieso bewirkt das Programm überhaupt etwas, wenn doch das Hauptprogramm
+      nach dem Initialisieren lediglich eine Endlosschleife ausführt,
+      in der \emph{nichts\/} passiert? \points 3
+    \item[(b)]
+      Erklären Sie, wie die Anweisung
+      \begin{lstlisting}[gobble=8]
+        PORTA = 1 << ((counter++ >> 6) & 7);
+      \end{lstlisting}
+      \vspace{-\medskipamount}
+      das LED-Blinkmuster hervorruft. \points 6
+
+      Hinweis: Zerlegen Sie die eine lange Anweisung in mehrere kürzere.\\
+      Wenn nötig, verwenden Sie zusätzliche Variable für Zwischenergebnisse.
+    \item[(c)]
+      Was bedeutet "`\lstinline{ISR (TIMER0_COMP_vect)}"'? \points 1
+    \item[(d)]
+      Wieso leuchten die Leuchtdioden PB2 und PD1? \points 2
+  \end{itemize}
+
+  \solution
+
+  \begin{itemize}
+    \item[(a)]
+      \textbf{Wieso bewirkt das Programm überhaupt etwas, wenn doch das Hauptprogramm
+      nach dem Initialisieren lediglich eine Endlosschleife ausführt,
+      in der \emph{nichts\/} passiert?}
+
+      Die Funktion \lstinline{ISR (TIMER0_COMP_vect)}
+      ist ein \emph{Interrupt-Handler\/}
+      (oder \emph{Interrupt Service Routine -- ISR\/})
+      und wird nicht durch das Hauptprogramm oder andere Funktionen aufgerufen,
+      sondern durch ein Hardware-Ereignis.
+
+      In diesem Fall sorgt die Initialisierung dafür,
+      daß die Funktion regelmäßig durch eine Uhr (\emph{Timer\/}) aufgerufen wird.
+
+      \bigskip
+      \goodbreak
+
+    \item[(b)]
+      \textbf{Erklären Sie, wie die Anweisung}
+      \begin{lstlisting}[gobble=8]
+        PORTA = 1 << ((counter++ >> 6) & 7);
+      \end{lstlisting}
+      \vspace{-\medskipamount}
+      \textbf{das LED-Blinkmuster hervorruft.}
+
+      Um die Anweisung zu verstehen, zerlegen wir sie in mehrere kürzere.
+      Dabei ist es wichtig, die Reihenfolge zu erkennen,
+      in der die einzelnen Operationen ausgeführt werden.
+
+      Zunächst stellen wir fest, daß der Post-Inkrement-Operator \lstinline{++}
+      erst nach der Anweisung -- also als letztes -- ausgeführt wird.
+      Die Anweisung ist somit äquivalent zu den folgenden zwei Anweisungen:
+
+      \begin{lstlisting}[gobble=8]
+        PORTA = 1 << ((counter >> 6) & 7);
+        counter++;
+      \end{lstlisting}
+
+      Von der verbleibenden langen Anweisung wird als erstes
+      die innerste Klammer ausgeführt:
+
+      \begin{lstlisting}[gobble=8]
+        int temp1 = counter >> 6;
+        PORTA = 1 << (temp1 & 7);
+        counter++;
+      \end{lstlisting}
+
+      Das Verschieben um 6 Binärstellen nach rechts
+      entspricht einer Division durch $2^6 = 64$.
+      Die Bedeutung der neu eingeführten Variablen ist somit ein Zähler,
+      der 64mal langsamer zählt als der ursprüngliche:
+
+      \begin{lstlisting}[gobble=8]
+        int slow_counter = counter >> 6;
+        PORTA = 1 << (slow_counter & 7);
+        counter++;
+      \end{lstlisting}
+
+      (Ohne diese Verlangsamung wäre das Lauflicht zu schnell,
+      um es es mit bloßem Auge wahrnehmen zu können.)
+
+      Als nächste Operation wird die bitweise Und-Verknüpfung ausgeführt:
+
+      \begin{lstlisting}[gobble=8]
+        int slow_counter = counter >> 6;
+        int temp2 = slow_counter & 7;
+        PORTA = 1 << temp2;
+        counter++;
+      \end{lstlisting}
+
+      Die Binärdarstellung von 7 sind drei Einsen: $7_{10} = 111_2$.
+      Eine Und-Verknüpfung mit 7 isoliert also die untersten drei Bits
+      von \lstinline{slow_counter}.
+
+      Mit drei Bits lassen sich Zahlen von 0 bis 7 darstellen.
+      Wenn also \lstinline{slow_counter} immer größer wird,
+      läuft \lstinline{slow_counter & 7} immer wieder von 0 bis 7:
+
+      \begin{lstlisting}[gobble=8]
+        int slow_counter = counter >> 6;
+        int slow_counter_0_to_7 = slow_counter & 7;
+        PORTA = 1 << slow_counter_0_to_7;
+        counter++;
+      \end{lstlisting}
+
+      (Bemerkung: Eine bitweise Und-Verknüpfung mit 7 ist gleichbedeutend
+      zur Berechnung des Rests bei Division durch 8:
+      \lstinline{slow_counter_0_to_7 = slow_counter % 8}.
+      Auch dadurch wird klar, daß das Ergebnis der Operation
+      immer wieder die Zahlen von 0 bis 7 durchläuft,
+      wenn \lstinline{slow_counter} immer größer wird.)
+
+      Die letzte Operation \lstinline{1 << slow_counter_0_to_7}
+      erzeugt eine Bitmaske, in der ein Bit von Position 0 bis Position 7,
+      also von rechts nach links wandert:
+
+      \begin{lstlisting}[style=terminal,gobble=8]
+        00000001
+        00000010
+        00000100
+        00001000
+        00010000
+        00100000
+        01000000
+        10000000
+      \end{lstlisting}
+
+      Die zyklische Zuweisung dieser Bitmasken an \lstinline{PORTA}
+      erzeugt das Lauflicht.
+
+      \bigskip
+
+      \textbf{Zusammenfassung:}
+      \begin{itemize}
+        \item
+          Das jeweils zum Schluß ausgeführte \lstinline{++}\\
+          läßt die Variable \lstinline{counter} bei jedem Aufruf um 1 hochzählen.
+        \item
+          Durch die Bit-Verschiebung um 6 nach rechts\\
+          erzeugen wir einen um den Faktor 64 langsameren Zähler.
+        \item
+          Die bitweise Und-Verknüpfung mit 7
+          isoliert die untersten 3 Bit des langsameren Zählers\\
+          und erzeugt so einen neuen Zähler,
+          der immer wieder von 0 bis 7 zählt.
+        \item
+          Die Linksverschiebung einer 1 um diesen neuen Zähler
+          erzeugt Bit-Masken mit jeweils einem Bit,
+          das von rechts nach links läuft.
+        \item
+          Die zyklische Zuweisung dieser Bitmasken an \lstinline{PORTA}
+          erzeugt das Lauflicht.
+      \end{itemize}
+      
+      \bigskip
+
+    \item[(c)]
+      \textbf{Was bedeutet "`\lstinline{ISR (TIMER0_COMP_vect)}"'?}
+
+      Es bezeichnet einen \emph{Interrupt-Handler\/}
+      (\emph{Interrupt Service Routine -- ISR\/}) für einen \emph{Timer-Interrupt},
+      also eine Funktion,
+      die durch ein von einer Uhr periodisch ausgelöstes Hardware-Ereignis
+      aufgerufen wird.
+
+      \bigskip
+
+    \item[(d)]
+      \textbf{Wieso leuchten die Leuchtdioden PB2 und PD1?}
+
+      Der Mikro-Controller enthält kein Betriebssystem.
+      Auf ihm läuft kein Programm außer dem, das wir auf ihn herunterladen.
+
+      Beim Start enthalten alle Ports \textbf{zufällige Werte}.
+      Wenn wir wünschen, daß eine LED aus ist,
+      muß unser Programm sie explizit ausschalten.
+
+      In diesem Fall ließe sich dies durch die Zeilen
+      \begin{lstlisting}[gobble=8]
+        DDRB = 0xff;
+        DDRC = 0xff;
+        DDRD = 0xff;
+        PORTB = 0;
+        PORTC = 0;
+        PORTD = 0;
+      \end{lstlisting}
+      im Hauptprogramm erreichen.
+
+      (Wegen der \lstinline{volatile}-Eigenschaft
+      der \lstinline{DDR}- und \lstinline{PORT}-Variablen
+      ist dies übrigens \emph{nicht\/} äquivalent zu den folgenden Zeilen:
+      \begin{lstlisting}[gobble=8]
+        DDRB = DDRC = DDRD = 0xff;
+        PORTB = PORTC = PORTD = 0;
+      \end{lstlisting}
+      Für Details siehe:
+      \url{http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_assign_chain})
+
+  \end{itemize}
+
+  \exercise{Länge von Strings}
+
+  Diese Aufgabe ist eine Neuauflage von Aufgabe 3 der
+  Übung vom 5.\ November 2017,\\
+  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}
+
+  Wir betrachten nun die folgenden Funktionen (Datei: \gitfile{hp}{20181217}{aufgabe-3.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}{20181105}{loesung-3c-1.c} (mit Array-Index)
+      und \gitfile{hp}{20181105}{loesung-3c-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}{20181105}{loesung-3d-1.c} und \gitfile{hp}{20181105}{loesung-3d-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}{20181105}{loesung-3e-1.c}
+      realisiert dies mit einem Array-Index,
+      Die Funktion \lstinline{fun_4()} in der Datei \gitfile{hp}{20181105}{loesung-3e-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}{20181105}{loesung-3e-1.c}
+      und \gitfile{hp}{20181105}{loesung-3e-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}
+
+\end{document}
diff --git a/20181217/loesung-1.c b/20181217/loesung-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..c2d6f6003924627ae97831407c191eaac42a09c1
--- /dev/null
+++ b/20181217/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/README.md b/README.md
index cb26cc04fed53a98caa64953e55a8033a68f072a..0eba719ef3be6a360e568137241ffd1512b997d0 100644
--- a/README.md
+++ b/README.md
@@ -60,6 +60,9 @@ Musterlösungen:
  * [12.11.2018: Text-Grafik-Bibliothek, Datum-Bibliothek, Kondensator](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181112/hp-musterloesung-20181112.pdf)
  * [19.11.2018: Arrays mit Zahlen, hüpfender Ball](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181119/hp-musterloesung-20181119.pdf)
  * [26.11.2018: Zahlensysteme, Mikrocontroller](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181126/hp-musterloesung-20181126.pdf)
+ * [03.12.2018: XBM-Grafik, LED-Blinkmuster](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181203/hp-musterloesung-20181203.pdf)
+ * [10.12.2018: Trickprogrammierung, Thermometer-Baustein an I²C-Bus](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181210/hp-musterloesung-20181203.pdf)
+ * [17.12.2018: Fakultät, Lauflicht, Länge von Strings (Neuauflage)](https://gitlab.cvh-server.de/pgerwinski/hp/raw/master/20181217/hp-musterloesung-20181217.pdf)
 
 Tafelbilder:
 ------------
diff --git a/hp-slides-2018ws.pdf b/hp-slides-2018ws.pdf
index c22b6bfd1d123bd1b79eb0cf05c629df624905d1..b4f541b3dc39f9f86438dd39f51262aa1a490099 100644
Binary files a/hp-slides-2018ws.pdf and b/hp-slides-2018ws.pdf differ