let x = 0
let y = 0
let d = 1
let m = 1
while true
while 2 * x * d < m
print(x, y)
x = x + d
while 2 * y * d < m
print(x, y)
y = y + d
d = -1 * d
m = m + 1
Es wurden viele Lösungen für dieses Problem vorgeschlagen, die in verschiedenen Programmiersprachen geschrieben wurden, aber alle scheinen aus demselben verschlungenen Ansatz zu stammen. Ich werde das allgemeinere Problem der Berechnung einer Spirale betrachten, die durch Induktion präzise ausgedrückt werden kann.
Basisfall: Beginnen Sie bei (0, 0), bewegen Sie sich 1 Feld vorwärts, biegen Sie links ab, bewegen Sie sich 1 Feld vorwärts, biegen Sie links ab. Induktiver Schritt: Bewegen Sie sich vorwärts n + 1 Quadrate, biegen Sie links ab, bewegen Sie sich vorwärts n + 1 Quadrate, biegen Sie links ab.
Die mathematische Eleganz, dieses Problem auszudrücken, legt nahe, dass es einen einfachen Algorithmus geben sollte, um die Lösung zu berechnen. Unter Berücksichtigung der Abstraktion habe ich mich entschieden, den Algorithmus nicht in einer bestimmten Programmiersprache zu implementieren, sondern als Pseudocode.
Zuerst werde ich einen Algorithmus betrachten, um nur 2 Iterationen der Spirale unter Verwendung von 4 Paaren von while-Schleifen zu berechnen. Die Struktur jedes Paares ist ähnlich, jedoch eigenständig. Dies mag zunächst verrückt erscheinen (einige Schleifen werden nur einmal ausgeführt), aber Schritt für Schritt werde ich Transformationen durchführen, bis wir zu 4 Paaren von Schleifen gelangen, die identisch sind und daher durch ein einzelnes Paar innerhalb einer anderen Schleife ersetzt werden können. Dies bietet uns eine allgemeine Lösung für die Berechnung von Iterationen ohne Verwendung von Bedingungen.
let x = 0
let y = 0
//RIGHT, UP
while x < 1
print(x, y)
x = x + 1
while y < 1
print(x, y)
y = y + 1
//LEFT, LEFT, DOWN, DOWN
while x > -1
print(x, y)
x = x - 1
while y > -1
print(x, y)
y = y - 1
//RIGHT, RIGHT, RIGHT, UP, UP, UP
while x < 2
print(x, y)
x = x + 1
while y < 2
print(x, y)
y = y + 1
//LEFT, LEFT, LEFT, LEFT, DOWN, DOWN, DOWN, DOWN
while x > -2
print(x, y)
x = x - 1
while y > -2
print(x, y)
y = y - 1
Die erste Transformation, die wir durchführen werden, ist die Einführung einer neuen Variablen d für die Richtung, die entweder den Wert +1 oder -1 enthält. Die Richtung wechselt nach jedem Schleifenpaar. Da wir den Wert von d an allen Punkten kennen, können wir jede Seite jeder Ungleichung damit multiplizieren, die Richtung der Ungleichung entsprechend anpassen und alle Multiplikationen von d mit einer Konstanten zu einer anderen Konstante vereinfachen. Dies lässt uns folgendes übrig.
let x = 0
let y = 0
let d = 1
//RIGHT, UP
while x * d < 1
print(x, y)
x = x + d
while y * d < 1
print(x, y)
y = y + d
d = -1 * d
//LEFT, LEFT, DOWN, DOWN
while x * d < 1
print(x, y)
x = x + d
while y * d < 1
print(x, y)
y = y + d
d = -1 * d
//RIGHT, RIGHT, RIGHT, UP, UP, UP
while x * d < 2
print(x, y)
x = x + d
while y * d < 2
print(x, y)
y = y + d
d = -1 * d
//LEFT, LEFT, LEFT, LEFT, DOWN, DOWN, DOWN, DOWN
while x * d < 2
print(x, y)
x = x + d
while y * d < 2
print(x, y)
y = y + d
Nun stellen wir fest, dass sowohl x * d als auch die RHS ganze Zahlen sind, sodass wir jeden reellen Wert zwischen 0 und 1 von der RHS subtrahieren können, ohne das Ergebnis der Ungleichung zu beeinflussen. Wir ziehen es vor, 0,5 von den Ungleichungen jedes zweiten Paares von while-Schleifen zu subtrahieren, um ein besseres Muster zu erhalten.
let x = 0
let y = 0
let d = 1
//RIGHT, UP
while x * d < 0.5
print(x, y)
x = x + d
while y * d < 0.5
print(x, y)
y = y + d
d = -1 * d
//LEFT, LEFT, DOWN, DOWN
while x * d < 1
print(x, y)
x = x + d
while y * d < 1
print(x, y)
y = y + d
d = -1 * d
//RIGHT, RIGHT, RIGHT, UP, UP, UP
while x * d < 1.5
print(x, y)
x = x + d
while y * d < 1.5
print(x, y)
y = y + d
d = -1 * d
//LEFT, LEFT, LEFT, LEFT, DOWN, DOWN, DOWN, DOWN
while x * d < 2
print(x, y)
x = x + d
while y * d < 2
print(x, y)
y = y + d
Wir können jetzt eine weitere Variable m für die Anzahl der Schritte einführen, die wir bei jedem Paar von while-Schleifen ausführen.
let x = 0
let y = 0
let d = 1
let m = 0.5
//RIGHT, UP
while x * d < m
print(x, y)
x = x + d
while y * d < m
print(x, y)
y = y + d
d = -1 * d
m = m + 0.5
//LEFT, LEFT, DOWN, DOWN
while x * d < m
print(x, y)
x = x + d
while y * d < m
print(x, y)
y = y + d
d = -1 * d
m = m + 0.5
//RIGHT, RIGHT, RIGHT, UP, UP, UP
while x * d < m
print(x, y)
x = x + d
while y * d < m
print(x, y)
y = y + d
d = -1 * d
m = m + 0.5
//LEFT, LEFT, LEFT, LEFT, DOWN, DOWN, DOWN, DOWN
while x * d < m
print(x, y)
x = x + d
while y * d < m
print(x, y)
y = y + d
Schließlich sehen wir, dass die Struktur jedes Paares von while-Schleifen identisch ist und auf eine einzelne Schleife reduziert werden kann, die innerhalb einer anderen Schleife platziert ist. Um die Verwendung von reellen Zahlen zu vermeiden, habe ich den Anfangswert von m multipliziert. der Wert m wird erhöht um; und beide Seiten jeder Ungleichung um 2.
Dies führt zu der am Anfang dieser Antwort gezeigten Lösung.