Die offenen Spinde

Werbung
Die offenen Spinde
Die klassische Herangehensweise
Wir betrachten hier ein Problem, daß als "Locker-Problem" in der Informatik bekannt ist. Es geht
dabei um folgendes:
In den Umkleiderräumen eines Schwimmbades stehen 100 Studenten. Der erste Student verschließt alle Spinde. Der zweite Student öffnet jeden zweiten Spind. Der dritte Student ändert den
Zustand jedes dritten Spindes, d.h. der Spinde 3, 6, 9 usw. trifft er auf einen offenen Spind, so
verschließt er diesen, trifft er auf einen verschlossenene Spind, so öffnet er ihn. Die Frage lautet
nun: Welche Spinde sind am Ende, wenn alle 100 Studenten die Umkleideräume passiert haben,
noch offen?
Wir werden diese Fragestellung, wie auch die zuvor schon behandelten Probleme zunächt im
klassichen Programmierstil mit Mathematica lösen. Die Lösung ist hier kein größeres Problem. Die
Lösung läßt sich mit zwei geschachtelten Schleifen einfach ermitteln. Der Einfachheit halber beginnen wir erst mit dem zweiten Studenten und der Ausgangssituation, daß alle Spinde offen sind.
offeneSpinde@n_D := Module@8spinde = Table@True, 8n<D<,
For@i = 2, i § n, i += 1, H*Alle Studenten, außer dem ersten*L
For@j = i, j < n, j += i, spinde@@jDD = Not@spinde@@jDDDD D;
H* invertieren des Zustands*L
Print@Flatten@Position@spinde, TrueDDD H* Ausgabe der Lösung*L
D
offeneSpinde@100D
81, 4, 9, 16, 25, 36, 49, 64, 81, 100<
Es bleiben also alle Spinde deren Nummern Quadratzahlen sind offen. Ein durchaus nicht offensichtliches Ergebnis.
Die Mathematica Herangehensweise
Nun soll auch dieses Problem wieder im Mathematica Stil angegangen und gelöst werden. Die
Grundidee ist dabei die offenen Spinde als Liste von Zahlen zu repräsentieren. Dabei steht +1 für
einen offenen Spind und -1 für einen verschlossenen Spind. DieseWahl der Darstellung ermöglicht
es die Invertierung des jeweiligen Spindzustandes durch eine Multiplikationm mit -1 zu realisieren.
Dies wiederum ermöglicht es die zugrundeliegende Ieration mit Hilfe der Mathematica-eigenen
Itgerationsfunktionen (hier FoldList) zu implementieren. Betrachten wir die Vorgehensweise etwas
genauer, indem wir das Problem Schritt für Schritt lösen. Wir betrachten dabei anzahl Spinde.
Zunächst die Spinde:
Remove@anzahl, offeneSpinde, invertieren, studenten, datenD H* Aufräumen *L
anzahl = 20;
2
SpindProblem.nb
offeneSpinde = Table@1, 820<D
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1<
Daneben noch die Studenten:
studenten = Range@anzahlD
81, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20<
Das Auf- oder Zuschließen des Spindes mit der Nummer i entspricht nun dem "Umdrehen" des
Vorzeichens an der i-ten Position in der Liste der offenen Spinde. Der Student Nummer k bewirkt
also das Umdrehen des Vorzeichens an den Positionen k, 2k, 3k, .. n*k, solange bis n*k größer wird
als die Anzahl der Spinde. Diesen Effekt erreicht man einfach dadurch, das die Liste der offenen
Spinde mit einer entsprechend generierten Liste multipliziert wird. Diese Listen sind jedoch einfach
zu erzeugen. Hier zum Beispiel die Folge für den dritten Studenten
ReplacePart@offeneSpinde, - 1, Table@8i<, 8i, 3, anzahl, 3<DD
81, 1, - 1, 1, 1, - 1, 1, 1, - 1, 1, 1, - 1, 1, 1, - 1, 1, 1, - 1, 1, 1<
Der Befehl ReplacePart[...] kann nun also benutzt werden, um eine Folge von Listen derart zu
erzeugen, daß die i-te Liste die Aktion des i-ten Studenten abbildet. Dazu definieren wir eine Funktion invertieren wie folgt:
invertieren@k_D := ReplacePart@offeneSpinde, - 1, Table@8i<, 8i, k, anzahl, k<DD
Mit Hilfe dieser Funktion können wir nun mit einem einzigen Befehl die Aktionen der Studenten 1
bis n erzeugen:
invertieren êü studenten
88- 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1,
- 1<, 81, - 1, 1, - 1, 1, - 1, 1, - 1, 1, - 1, 1, - 1, 1, - 1, 1, - 1, 1, - 1, 1, - 1<,
81, 1, - 1, 1, 1, - 1, 1, 1, - 1, 1, 1, - 1, 1, 1, - 1, 1, 1, - 1, 1, 1<,
81, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, - 1<,
81, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1<,
81, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, - 1, 1, 1<,
81, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1<,
81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1<<
Damit kann das Problem elegant mit der Funktion FoldList gelöst werden. Mit Hilfe dieser Funktion wird das Verhalten Studenten 1, 2, 3, ... anzahl einfach durch Multiplikation der
entsprechenden Zeile (invertieren[i]) auf den aktuellen Stand der Spinde erzeugt.
SpindProblem.nb
p
(
)
p
daten = FoldList@Times, - offeneSpinde, invertieren êü studentenD;
3
g
Die graphische Darstellung ist nun besonders einfach, jede Zeile repräsentiert hier den Durchgang
eines Studenten
ArrayPlot@daten, ColorRules Ø 8- 1 Ø Black, 1 Ø White<, Mesh Ø TrueD
Die nach Durchgang aller Studenten noch offenen Spinde erhält man dann einfach mit:
Position@Last@datenD, 1D êê Flatten
81, 4, 9, 16<
Zusammenfassend erhalten wir das folgende Mathematica Programm:
spinde@n_D :=
Module@8daten, offeneSpinde = Table@1, 8n<D, studenten = Range@nD<,
student@k_D := ReplacePart@offeneSpinde, - 1, Table@8i<, 8i, k, n, k<DD;
daten = FoldList@Times, - offeneSpinde, student êü studentenD;
Print@Position@Last@datenD, 1D êê FlattenD;
ArrayPlot@daten, ColorRules Ø 8- 1 Ø Black, 1 Ø White<, Mesh Ø TrueD
D
Für 100 Spinde erhalten wir
4
SpindProblem.nb
spinde@100D
81, 4, 9, 16, 25, 36, 49, 64, 81, 100<
Herunterladen