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
Bu problem için çeşitli programlama dillerinde yazılmış birçok çözüm önerilmiştir, ancak hepsi aynı kıvrımlı yaklaşımdan kaynaklanmaktadır. İndüksiyon kullanılarak kısaca ifade edilebilecek bir spiral hesaplamanın daha genel problemini ele alacağım.
Temel durum: (0, 0) 'dan başlayın, 1 kare ileri, sola dön, 1 kare ileri, sola dön. Endüktif adım: İleriye doğru n + 1 kareler, sola dönün, ileriye doğru n + 1 kareler, sola dönün.
Bu problemi ifade etmenin matematiksel şıklığı, çözümü hesaplamak için basit bir algoritma olması gerektiğini göstermektedir. Soyutlamayı akılda tutarak, algoritmayı belirli bir programlama dilinde değil, sahte kod olarak uygulamayı seçtim.
İlk önce 4 çift while döngüsü kullanarak spiralin sadece 2 tekrarını hesaplamak için bir algoritma düşüneceğim. Her çiftin yapısı benzerdir, ancak kendi başına farklıdır. Bu başlangıçta çılgınca görünebilir (bazı döngüler sadece bir kez yürütülür), ancak aynı olan ve dolayısıyla başka bir döngünün içine yerleştirilmiş tek bir çiftle değiştirilebilen 4 çift döngüye ulaşana kadar adım adım dönüşümler yapacağım. Bu, bize herhangi bir koşul kullanmadan genel bir hesaplama yinelemesi sağlayacaktır.
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
Yapacağımız ilk dönüşüm, yön için +1 veya -1 değerini tutan yeni bir d değişkeninin getirilmesidir. Her döngü çiftinden sonra yön değişir. D'nin değerini tüm noktalarda bildiğimiz için, her bir eşitsizliğin her iki tarafını da onunla çarpabilir, eşitsizliğin yönünü buna göre ayarlayabilir ve d'nin çarpımlarını sabit ile başka bir sabit arasında basitleştirebiliriz. Bu bizi aşağıdakilere bırakıyor.
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
Şimdi hem x * d hem de RHS'nin tamsayı olduğuna dikkat ediyoruz, böylece eşitsizliğin sonucunu etkilemeden RHS'den 0 ile 1 arasındaki herhangi bir gerçek değeri çıkarabiliriz. Daha fazla model oluşturmak için diğer her bir çift döngüdeki eşitsizliklerden 0.5 çıkarmayı seçiyoruz.
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
Artık while döngülerinin her bir çiftinde attığımız adım sayısı için başka bir m değişkeni ekleyebiliriz.
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
Son olarak, her bir while döngüsü çiftinin yapısının aynı olduğunu ve başka bir ilmeğin içine yerleştirilmiş tek bir ilmeğe indirgenebileceğini görüyoruz. Ayrıca, gerçek değerli sayılar kullanmaktan kaçınmak için m'nin başlangıç değerini çarptım; m değeri şu şekilde arttırılır; ve her bir eşitsizliğin her iki tarafı da 2.
Bu, bu cevabın başında gösterilen çözüme götürür.