Skip to content

Latest commit

 

History

History
222 lines (179 loc) · 5.99 KB

File metadata and controls

222 lines (179 loc) · 5.99 KB

Tag 06 - Spaltenweise Arithmetik

Aufgabe

Verarbeitung von arithmetischen Ausdrücken, die spaltenweise statt zeilenweise organisiert sind.

  • Teil 1: Spaltenweise Addition oder Multiplikation
  • Teil 2: Spaltenweise Ausdrücke mit Operatoren-Priorisierung

Lösung

Eingabeformat

Mehrere Zeilen mit Zahlen und Operatoren, die spaltenweise gelesen werden müssen.

Beispiel:

1 2 3 +
4 5 6 *

Spaltenweise gelesen:

  • Spalte 1: ['1', '4'] → Zahl oder Rechnung
  • Spalte 2: ['2', '5'] → Zahl oder Rechnung
  • Spalte 3: ['3', '6'] → Zahl oder Rechnung
  • Spalte 4: ['+', '*'] → Operatoren

Algorithmus

Teil 1 - Einfache spaltenweise Arithmetik

for rechnung in list(zip(*[zeile.split() for zeile in aufgabe.zeilen])):
    *operanden, operator = rechnung
    aufgabe.loesung1 += sum(map(int, operanden)) if operator == "+" else prod(map(int, operanden))

Schritt für Schritt:

  1. Zeilen aufteilen:

    [zeile.split() for zeile in aufgabe.zeilen]
    • Jede Zeile wird an Leerzeichen gesplittet
    • Ergebnis: Liste von Listen
    • Beispiel: [['1', '2', '3', '+'], ['4', '5', '6', '*']]
  2. Transponieren (Zeilen → Spalten):

    zip(*[...])
    • * unpacked die Liste
    • zip() gruppiert Element-Position-weise
    • Beispiel: [('1', '4'), ('2', '5'), ('3', '6'), ('+', '*')]
  3. Operanden und Operator trennen:

    *operanden, operator = rechnung
    • Letztes Element: operator
    • Alle vorherigen: operanden (als Liste)
    • Beispiel: rechnung = ('1', '4', '+')operanden = ['1', '4'], operator = '+'
  4. Berechnung:

    sum(map(int, operanden)) if operator == "+" else prod(map(int, operanden))
    • Addition (+): Summiere alle Operanden
    • Multiplikation (*): Multipliziere alle Operanden
    • prod() von math Modul: Produkt aller Elemente

Beispiel:

Eingabe:
1 2 +
3 4 +

Spalten:
('1', '3', '+') → 1 + 3 = 4
('2', '4', '+') → 2 + 4 = 6

Lösung1 = 4 + 6 = 10

Teil 2 - Komplexe spaltenweise Ausdrücke

faktoren = []
for spalte in list(zip_longest(*[zeile for zeile in aufgabe.zeilen]))[:-1]:
    if all(zeichen == ' ' for zeichen in spalte):
        continue
    *operanden, operator = spalte
    operand = int(''.join(operand for operand in operanden))
    if operator in ("+", "*"):
        aufgabe.loesung2 += prod(faktoren)
        faktoren = []
        befehl = "addiere" if operator == "+" else "multipliziere"
    if befehl == "addiere":
        aufgabe.loesung2 += operand
    else:
        faktoren.append(operand)
aufgabe.loesung2 += prod(faktoren)

Unterschiede zu Teil 1:

  1. zip_longest statt zip:

    zip_longest(*[zeile for zeile in aufgabe.zeilen])
    • Behält alle Spalten, auch wenn Zeilen unterschiedlich lang sind
    • Füllt kürzere Zeilen mit None auf
    • Wichtig: Zeilen werden nicht gesplittet (zeichenweise!)
  2. Letzte Spalte ignorieren:

    [...][:-1]
    • Vermutlich Padding oder Separator
  3. Leerzeichen-Spalten überspringen:

    if all(zeichen == ' ' for zeichen in spalte):
        continue
    • Spalten mit nur Leerzeichen werden ignoriert
  4. Operanden zu Zahl zusammenfügen:

    operand = int(''.join(operand for operand in operanden))
    • Mehrere Zeichen werden zu einer Zahl kombiniert
    • Beispiel: ['1', '2', '3']"123"123
  5. Operator als Modus-Wechsel:

    if operator in ("+", "*"):
        aufgabe.loesung2 += prod(faktoren)
        faktoren = []
        befehl = "addiere" if operator == "+" else "multipliziere"
    • + oder * sind Befehle, nicht unmittelbare Operationen
    • Setzen den Modus für folgende Operanden
    • Vor Modus-Wechsel: Produkt der gesammelten Faktoren addieren
  6. Zwei Modi:

    Modus "addiere":

    if befehl == "addiere":
        aufgabe.loesung2 += operand
    • Operand wird direkt zur Lösung addiert

    Modus "multipliziere":

    else:
        faktoren.append(operand)
    • Operand wird zu Faktoren-Liste hinzugefügt
    • Produkt wird erst bei nächstem Operator-Wechsel berechnet
  7. Abschluss:

    aufgabe.loesung2 += prod(faktoren)
    • Nach allen Spalten: Verbleibende Faktoren multiplizieren und addieren

Beispiel:

Eingabe (zeichenweise):
1 + 2 3 *
↓ ↓ ↓ ↓ ↓

Spalte 1: ('1',) → Operator fehlt → benutze vorherigen Modus
Spalte 2: ('+',) → Modus = "addiere"
Spalte 3: ('2',) → addiere: 0 + 2 = 2
Spalte 4: ('3',) → addiere: 2 + 3 = 5
Spalte 5: ('*',) → Modus = "multipliziere"

Komplexität

Teil 1:

  • Zeit: O(n * m) wobei n = Anzahl Zeilen, m = Anzahl Spalten
    • zip() und Iteration durch alle Spalten
  • Platz: O(n * m) für transponierte Datenstruktur

Teil 2:

  • Zeit: O(n * m)
    • zip_longest() und Iteration durch alle Spalten
    • String-Join und Int-Konvertierung pro Spalte
  • Platz: O(n * m + k) wobei k = Anzahl Faktoren in Liste

Besonderheiten

Transposition mit zip():

  • zip(*liste) ist die idiomatische Python-Methode für Matrix-Transposition
  • Beispiel: zip(*[[1,2], [3,4]])[(1,3), (2,4)]

zip vs. zip_longest:

  • zip(): Stoppt bei kürzester Sequenz
  • zip_longest(): Geht bis zur längsten Sequenz, füllt mit None auf

Unpacking mit *variable:

  • *operanden, operator = liste packt alle außer letztes Element
  • Python 3 Feature für flexible Zuweisungen

prod() Funktion:

  • Seit Python 3.8 in math Modul
  • Äquivalent zu sum() für Multiplikation
  • prod([]) = 1 (neutrales Element der Multiplikation)

Operator als Modus:

  • Operatoren sind nicht Befehle für vorherige Operanden
  • Sondern Modus-Setter für folgende Operanden
  • Wichtig für Verständnis der Teil 2 Logik

Zeichenweise vs. Token-weise:

  • Teil 1: Token-weise (split())
  • Teil 2: Zeichenweise (kein split())
  • Erklärt warum operand = int(''.join(...)) nötig ist