Üçüncü Yığını Kullan
Başlığı okuduysanız, biraz kafanız karışmış olabilir. Kesinlikle Brain-Flak'ta sadece iki yığın var? Ancak sizi temin ederim ki Brain-Flak yazarken ve golf oynamanın en güçlü aracı olmasa da en güçlülerden biri.
"Üçüncü Yığın" nedir?
Her Brain-Flak programı üçüncü yığını bir şekilde ya da başka bir şekilde kullanır, ancak kullanımın çoğu sahnelerin ardında devam eder ve genellikle var olduğu gerçeğini göz ardı etmek genellikle yararlıdır. Programdaki her parantez, bir öğeyi yığına ekler veya kaldırır. Açık parantezlerin ([<
üçü yığına bir öğe eklerken, üç konjugatının )]>
tümü bir öğeyi yığından kaldırır. Yığındaki öğenin değeri, programın geçerli kapsamının değeridir ve nilantların kullanılması bu değeri belirli şekillerde değiştirir. Yakın parantez )
, bir öğenin Üçüncü Yığından geçerli yığına taşınmasını sağlayan benzersiz bir işleve sahiptir; bir itme.
Umarım bu sizin için netleşiyor. Üçüncü Yığın, zaten yürütülmüş olan kodun dönüş değerlerini hatırlayan bir tür yığın. İki normal yığının ve Üçüncü Yığının izini süren basit bir program örneği üzerinden geçelim.
Örnek
Aşağıdaki programdan geçeceğiz. Bu program -3, 1, -2
yığına iter .
(([()()()])(()))
Sıfırı üçüncü yığına iten üç açık ayraçla başlıyoruz.
Artık stoklarımız şu şekilde görünüyor: Üçüncü Yığın sağdaki ve aktif yığının da ^
altında:
0
0
0 0 0
^
(([()()()])(()))
^
Şimdi üç ()
nilamız var. Bunlar normal iki yığına hiçbir şey yapmaz, ancak her biri Üçüncü Yığın üstüne bir tane ekler ve yığınlarımızın şöyle görünmesini sağlar:
3
0
0 0 0
^
(([()()()])(()))
^
Şimdi ]
yakın parantezlerin Üçüncü ]
Yığındaki bir öğeyi çıkarmasından önce belirtildiği gibi karşımıza çıkıyor, ancak yığının üstünden çıkardığı öğeyi çıkarma işlevine sahip. Böylece yeni yığınlarımız şöyle görünecek:
-3
0 0 0
^
(([()()()])(()))
^
Bu mantıklı; [...]
olumsuzlama yapar bu yüzden ]
aşağı doğru çıkarmalı.
Şimdi bir tane yürütmeliyiz )
. Büyük olasılıkla hatırlayacağınız )
gibi, programda eşyaların yığına itildiği yer olduğundan, Üçüncü Yığın üstünü mevcut yığına taşıyacağız -3
, ayrıca üçüncü yığındaki bir sonraki elemana ekleyeceğiz .
-3 0 -3
^
(([()()()])(()))
^
Bir kez daha üç açık telimizden biriyle karşılaşıyoruz, böylece Üçüncü Yığımıza başka bir öğe daha ekleyeceğiz.
0
-3 0 -3
^
(([()()()])(()))
^
Daha önce ()
de söylediğimiz gibi üçüncü yığımızın tepesini birer birer artıracağız.
1
-3 0 -3
^
(([()()()])(()))
^
Ve )
Üçüncü Yığının üstünü aktif yığına taşıyacak ve aşağıya doğru ekleyeceğiz
1
-3 0 -2
^
(([()()()])(()))
^
Sonuncusu )
, Üçüncü Yığını aktif yığına taşır ve Üçüncü Yığın üzerinde eklenmesi gereken herhangi bir öğe kalmadığından başka hiçbir şey yapmaz.
-2
1
-3 0
^
(([()()()])(()))
^
Program sona erdi, bu yüzden sonlandırıyoruz ve çıktı veriyoruz.
Bu örnek, Üçüncü Yığın'ın ne olduğu ve yaptığı hakkında size bir fikir vermeyi amaçlamaktadır. Tüm işlemleri içermez, ancak umarım her birinin kendi başına ne yaptığını çözebilirsiniz. Eğer hala mücadele ediyorsanız, size yardımcı olmak için bu cevabın altına bir "cheatsheet" ekledim.
Tamam, peki ne?
Tamam, şimdi Üçüncü Yığını anlıyorsunuz, ama "Öyleyse ne?" “Üçüncü Yığın” olarak adlandırmasanız bile zaten kullanıyordunuz, Üçüncü Yığın açısından düşünmek golf oynamanıza nasıl yardımcı oluyor?
Bir probleme bakalım. Bir sayının üçgenini almak istiyorsun . Bu, n'den küçük olan tüm sayıların toplamıdır.
Bir yaklaşım, offstack'ta bir akümülatör oluşturmak ve siz geri sayım yaparken buna eklemek olabilir. Bu şuna benzeyen bir kod oluşturur:
(<>)<>{(({}[()])()<>{})<>}{}<>({}<>)
Çevrimiçi Deneyin!
Bu kod oldukça kompakt ve biri daha küçük olamayacağını düşünebilir. Bununla birlikte, üçüncü bir yığın bakış açısıyla yaklaşırsak, bunun son derece verimsiz olduğu anlaşılmaktadır. Akümülatörümüzü offstack'a koymak yerine, a ile üçüncü yığına koyabilir (
ve kullandığımız sonunda geri alabiliriz )
. Tüm sayıları bir kez daha tekrarlayacağız, ancak bu sefer Üçüncü Yığını arttırmak için fazla bir şey yapmak zorunda değiliz, program bizim için yapıyor. Bu gibi görünüyor:
({()({}[()])}{})
Çevrimiçi Deneyin
Bu kod daha önce yaptığımız oldukça iyi golf versiyonunun boyutunun yarısından daha az. Aslında bir bilgisayar araması, bu programın bu görevi gerçekleştirebilecek en kısa program olduğunu kanıtlamıştır. Bu program "tüm koşuların toplamı" yaklaşımı kullanılarak açıklanabilir, ancak Üçüncü Yığın yaklaşımı kullanılarak açıklandığında daha sezgisel ve açık olduğunu düşünüyorum.
Üçüncü Yığını ne zaman kullanırım?
İdeal olarak Brain-Flak'ta yeni bir problem üzerinde çalışmaya başladığınızda, kendinize Üçüncü Yığın'ı düşünerek bunu nasıl yapacağımı düşünmelisiniz. Bununla birlikte, ne zaman bir akümülatör tipini takip etmeniz ya da akan bir toplamınız olması gerektiğine dair genel bir kural olarak, bunu iki gerçek yığının yerine üçüncü yığınıza koymak iyi bir fikirdir.
Üçüncü yığınızı kullanmayı düşünmenin iyi bir fikir olabileceği bir başka zaman, diğer iki yığında bir miktar değer depolayacak boşluğunuz olmadığı zamandır. Bu, mevcut iki yığında manipülasyonlar yaparken ve nerede olduğunu takip etmek zorunda kalmadan daha sonra kullanmak üzere bir değer kaydetmek istediğinizde özellikle yararlı olabilir.
Üçüncü Yığın Sınırlamaları
Üçüncü Yığın birçok yönden çok güçlüdür ancak kendi sınırlamaları ve sakıncaları ile birlikte gelir.
İlk olarak, herhangi bir noktada Üçüncü Yığın için maksimum yığın yüksekliği derleme zamanında belirlenir. Bu, yığında bir miktar boşluk kullanmak istiyorsanız, programı yazarken bu alanı tahsis etmeniz gerektiği anlamına gelir.
İkincisi, Üçüncü Yığın Rasgele Erişim değildir. Bu, en yüksek değerden başka hiçbir değerde işlem yapamayacağınız anlamına gelir. Ek olarak, istif üzerindeki değerleri taşıyamazsınız (ilk iki elemanı değiştir).
Sonuç
Üçüncü Yığın güçlü bir araçtır ve her Brain-Flak kullanıcısı için gerekli olduğunu düşünüyorum. Brain-Flak'ta programlama hakkındaki düşüncelerinize alışmak biraz değişiyor, ancak doğru kullanıldığı zaman golf oynamaya gelince iyi ve inanılmaz bir fark yaratıyor.
Kopya kağıdı
İşte operasyonların listesi ve Üçüncü Yığını nasıl etkilediklerini
Operation | Action
====================================================
(,[,< | Put a zero on top of the Third Stack
----------------------------------------------------
) | Add the top of the Third Stack to the
| second element and move it to the
| active stack
----------------------------------------------------
] | Subtract the top of the Third Stack
| from the second element and pop it
----------------------------------------------------
> | Pop the top of the Third Stack
----------------------------------------------------
() | Add one to the top of the Third Stack
----------------------------------------------------
{} | Pop the top of the active stack and
| add it to the top of the Third Stack
----------------------------------------------------
[] | Add the stack height to the Third
| Stack
----------------------------------------------------
<>,{,} | Nothing