Seite 1 von 1

Die Tücken des remove()-Befehls

Verfasst: Sonntag 15. Juli 2012, 00:31
von Azimoth
In kurz:

(Ich arbeite übrigens mit Python3)

Bei der Ausführung des Codes generiert dieser Abschnitt

Code: Alles auswählen

        zwischenspeicher = options
        print("Zwischenspeicher:", zwischenspeicher)

        while multiplicant < 100:
            options = zwischenspeicher
            str_multiplicant = str(multiplicant)
            if num_check(multiplicant) == True:
                if ergebnis%multiplicant == 0:
                    for ziffer in str_multiplicant:
                        options.remove(ziffer)
                        print("Zwischenspeicher:", zwischenspeicher)
Folgenden Output
Zwischenspeicher: ['1', '3', '6', '8', '9']
Zwischenspeicher: ['3', '6', '8', '9']
Zwischenspeicher: ['6', '8', '9']
Frage:
Wieso verändert sich der "zwischenspeicher", obwohl die Werte doch nur aus "options" entfernt werden (sollten)?


Hintergrund:
Ich versuche gerade das Project Euler Problem 32 zu lösen.

Da es hierbei darum geht eine Gleichung "Multiplikator" * "Multiplikant" = "Ergebnis" zu erhalten, ich diese aber quasi rückwärts aufrolle, verwende ich die Begriffe aus der gesuchten Gleichung (das was nachher das Ergebnis sein soll heißt also die ganze Zeit "Ergebnis", auch wenn es im Kontext gerade ein Dividend ist.)

Die Grundidee ist, alle bereits verwendeten Ziffern aus einer Liste zu streichen, so dass keine Ziffer mehr als ein Mal in der Rechnung vorkommt.
Die num_check Funktion überprüft hierbei nur, ob die Zahl Nullen oder Ziffern doppelt enthält bzw. ob die Ziffern alle noch in der Liste (Options) stehen, also nicht verwendet wurden.

Zuerst suche ich ein "Ergebnis" aus vier verschiedenen Ziffern. Diese werden dann aus der Liste gestrichen (im oberen Beispiel: 2357)
Ausgehend von der Zahl aus den ersten beiden Ziffern in der Liste (hier also 23) wird dann nach einem zweistelligen "Multiplikators" zu dem "Ergebnis" gesucht (if ergebnis%teiler == 0 etc). Ist ein "Multiplikator" gefunden, werden seine Ziffern ebenfalls aus der Liste gestrichen.

Da ja aber ein "Ergebnis" mehrere Teiler, also mehrere "Multiplikatoren", haben kann wird die Liste nach Ausstreichen der "Ergebnis"-Ziffern zwischengespeichert (im "zwischenspeicher).

Der Plan war jetzt zu Beginn der Überprüfung eines "Multiplikators" die "Options"-Liste immer wieder auf den Stand des Zwischenspeichers zurück zu setzen, damit jedes Mal fünf mögliche Ziffern zur Wahl stehen.

Jedoch bleibt der Zwischenspeicher aus einem mir nicht erklärlichen Grund konstant während nach möglichen Teilern für dasselbe "Ergebnis" gesucht wird...

Re: Die Tücken des remove()-Befehls

Verfasst: Sonntag 15. Juli 2012, 01:26
von cofi
Azimoth hat geschrieben:Frage:
Wieso verändert sich der "zwischenspeicher", obwohl die Werte doch nur aus "options" entfernt werden (sollten)?
Antwort:
Weil beide identisch sind.

Eine Zuweisung bindet einen Wert an einen Namen und erzeugt keine Kopien. Wenn du eine Kopie willst, dann musst du sie explizit erstellen, z.B. mit `options = list(zwischenspeicher)`

Ohne auf den Code jetzt weiter einzugehen, das machen bestimmt noch andere, dass es sowohl `zwischenspeicher = options` und `options = zwischenspeicher` gibt kommt mir reichlich komisch vor ...

Und bitte lege dich auf eine Sprache fest, Python, Deutsch und Englisch ist einfach eine zu viel.

Re: Die Tücken des remove()-Befehls

Verfasst: Sonntag 15. Juli 2012, 12:16
von Azimoth
Vielen Dank, das hat geholfen!

Vor der while-Schleife wird eine Kopie des "Optionen"-Wertes in einem "zwischenspeicher" erstellt (ja, in obigem Beispiel nicht, aber das ist ja soeben erklärt und gleich korrigiert worden)

In der while-Schleife wird der "Optionen"-Wert verändert, aber wenn die Schleife das nächste mal durchläuft (dann mit einem anderen Multiplikant-Wert) soll die ursprüngliche Liste aus dem "zwischenspeicher" geholt werden, nicht mit den vorher durchgeführten Veränderungen weitergearbeitet.

Bei der ersten Runde (wo "Optionen" gerade erst in den "zwischenspeicher" gepackt wurde) macht das keinen Sinn, aber in allen darauf folgenden Runden.