#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUM_DIGITS 10   // Es gibt 10 Ziffern: 0 bis 9

int main(void) {
    char *strichlisten[NUM_DIGITS] = {NULL};  // Array für die Strichlisten-Strings, einer pro Ziffer
    int  counts[NUM_DIGITS] = {0};            // Zählt, wie oft jede Ziffer vorkommt
    int  c;                                   // Variable für das aktuell eingelesene Zeichen

    // Initialisiere alle Strichlisten als leere Strings
    for (int i = 0; i < NUM_DIGITS; ++i) {
        strichlisten[i] = malloc(1);          // Reserviere 1 Byte für den leeren String ('\0')
        if (!strichlisten[i]) {               // Prüfe, ob Speicher reserviert werden konnte
            fprintf(stderr, "Speicherfehler!\n"); // Fehlermeldung ausgeben
            // Bereits reservierten Speicher wieder freigeben
            for (int j = 0; j < i; ++j) free(strichlisten[j]);
            return 1;                         // Programm mit Fehlercode beenden
        }
        strichlisten[i][0] = '\0';            // Setze den String auf leer (nur das Endzeichen)
    }// für jede Zahl wird ein leerer String angelegt

    // Lese Zeichen ein, bis das Dateiende (EOF) erreicht ist
    while ((c = getchar()) != EOF) {
        if (c >= '0' && c <= '9') {           // Prüfe, ob das Zeichen eine Ziffer ist
            int idx = c - '0';                // Rechne das Zeichen in eine Zahl um (z.B. '3' -> 3)
            counts[idx]++;                    // Zähle die Ziffer mit

            // Ermittle die Länge des bisherigen Strichlisten-Strings
            size_t oldlen = strlen(strichlisten[idx]);
            // Reserviere neuen Speicher: alter String + 1 Strich + 1 für '\0'
            char *neu = malloc(oldlen + 2);
            if (!neu) {                       // Prüfe, ob Speicher reserviert werden konnte
                fprintf(stderr, "Speicherfehler!\n");
                // Speicher aufräumen
                for (int j = 0; j < NUM_DIGITS; ++j) free(strichlisten[j]);
                return 1;
            }
            strcpy(neu, strichlisten[idx]);   // Kopiere den alten String in den neuen Speicher
            neu[oldlen] = '|';                // Füge einen Strich ans Ende an
            neu[oldlen+1] = '\0';             // Setze das String-Ende
            free(strichlisten[idx]);          // Gib den alten Speicher frei
            strichlisten[idx] = neu;          // Setze den neuen String als aktuelle Strichliste
        }
        // Alle anderen Zeichen werden ignoriert
    }

    // Gib für jede Ziffer die Anzahl und die Strichliste aus
    for (int i = 0; i < NUM_DIGITS; ++i) {
        printf("%d: %d %s\n", i, counts[i], strichlisten[i]);
        free(strichlisten[i]);                // Speicher für die Strichliste freigeben
    }

    return 0;                                // Programm erfolgreich beenden
}