<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
Girdiyi, N
sayısal olmayan herhangi bir karakterle ayrılmış dizge izler.
Çevrimiçi deneyin!
Bu Sp3000 ile birlikte yazılmıştır (yani bir algoritma bulmak için canımı sıkmazdım, bu yüzden üzerinde çalışmaya başladı, 118 baytlık bir çözüm üretti, ancak golfü rahatsız edemedi, bu yüzden golf oynadım.) .. takım çalışması için yay).
açıklama
Sp'in normal astarı (her zamanki gibi hafifçe değiştirilmiş):
- Labirent, ana ve yardımcı olmak üzere iki yığıntan oluşan yığın tabanlı bir 2B dilidir. Ana yığında hemen hemen her şey olur, ancak değerleri diğerine kaydırabilirsiniz, örneğin bunları tersine çevirmek veya daha sonra kullanmak üzere saklayabilirsiniz.
- Yığınlar dipsizdir ve sıfırlarla doludur, bu nedenle boş bir yığıntan çıkmak bir hata değildir.
- Yürütme ilk geçerli karakterden başlar (burada sol üstte). Her bir kavşakta, talimat göstergesinin (IP) alınması için iki veya daha fazla yolun olduğu yerlerde, nereye gidileceğini belirlemek için yığının tepesi kontrol edilir. Negatif sola döner, sıfır ileri gider ve pozitif sağa döner. Bu edilirken geliyordu , kıvrılan pasajlar sarma gibi kod görünmesi için, bu koşullar her hücrede kontrol edilir "odalar" yapmaktan durdurma şey yok. Bunlar tahmin edilemez davranışlar sağlayabilir, ancak golf oynamak için mükemmeldir.
- Kaynak kod (ve bu nedenle labirentin yerleşimi), çalışma
<>^v
sırasındaki bir satır veya sütunu veya ızgarayı döngüsel olarak değiştiren çalışma zamanında değiştirilebilir .
"
hayır ops.
İşte başlıyoruz.
Kod <
, uzun bir lineer kod parçası ile başlarken birkaç kez kullandığım bir golf oyunudur. İlk satırı döngüsel olarak sola kaydırır, IP üzerindedir , böylece kaynak şöyle görünür:
<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
Fakat şimdi IP hiçbir yere taşınamıyor, bu yüzden <
tekrar yürütüyor . Bu, bu duruma ulaşana kadar devam eder:
<
,,}:?
.
;(" {(={}{".
,",;=};} }) "{@
Bu noktada IP, hücreden ayrılabilir ve ?
. Öyleyse işte doğrusal kod bozuldu:
? # Read the first integer on STDIN, i.e. N.
:} # Duplicate it and move one copy over to the auxiliary stack.
, # Read the separator character.
,. # Read the first character of the input string and directly print it.
IP şimdi 2x2 saat yönünde iki adet sıkıca sıkıştırılmış (örtüşen) 2x2 döngü olan bu 3x2 odasına giriyor. İlk döngü N-1
karakterleri STDIN'den okur ve atar .
; # Discard the top of the stack. On the first iteration, this is the
# separator we've already read. On subsequent iterations this will be
# one of the N-1 characters from the input string.
( # Decrement N. If this hits zero, we leave the loop, otherwise we continue.
, # Read the next character from STDIN to be discarded.
Şimdi girdi dizisinin kalanını okuyan ikinci döngüye giriyoruz. Çünkü EOF algılayabilir ,
dönecektir -1
bu durumda IP sola yapım.
, # Read a character. Exit the loop if EOF.
( # Decrement it.
Bu düşüş aslında işe yaramaz, ancak daha sonra ücretsiz olarak geri alabiliriz ve burada iki döngüyü üst üste binmemize izin verir.
5 ABCDEFGHIJKLMNOP
Girdiyi örnek olarak alırsak , yığın şöyle görünür:
Main [ ... 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O' -1 | 5 ... ] Auxiliary
Bunların aslında giriş karakterlerine karşılık geldiğini FGHIJKLMNOP
(onları azalttığımız için) ve gerçekte bunlardan ilkini basmak istemediğimizi unutmayın (yalnızca N-1
karakterleri attık , ancak atlamak istiyoruz N
).
Şimdi yığını bir sonraki döngü için hazırlayan kısa bir doğrusal bit var:
; # Discard the -1.
= # Swap the tops of the stacks, i.e. N with the last character.
# By putting the last character on the auxiliary stack, we ensure that
# it doesn't get discarded in the next loop.
} # Move N over to the auxiliary stack as well.
Yığınlar şimdi şuna benziyor:
Main [ ... 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' | 5 'O' ... ] Auxiliary
Saat yönünde bir 2x2 daha giriyoruz. Bu N
, ana karakterdeki üst karakterleri atar :
; # Discard the top of the main stack.
{ # Pull N over from the auxiliary stack.
( # Decrement it. It it's 0 we leave the loop.
} # Push N back to the auxiliary stack.
=
Dönüştüğümüzde döngü onu 0
ve giriş dizesinin son karakterini tekrar değiştirir. Şimdi yığınlar şuna benziyor:
Main [ ... 'E' 'F' 'G' 'H' 'I' 'O' | ... ] Auxiliary
Ana yığının içeriğini (alt eleman hariç ve tümü 1 ile artırılmış olarak) soldan yazdırmak istiyoruz . Bu, yardımcı yığına geçmemiz gerektiği anlamına gelir. Sonraki 2x2 (saat yönünde) döngünün yaptığı şey:
{ # Pull an element over from the auxiliary stack. This is necessary so we
# have a 0 on top of the stack when entering the loop, to prevent the IP
# from turning right immediately.
} # Move the top of the main stack back to the auxiliary stack. If this was the
# bottom of the stack, exit the loop.
) # Increment the current character.
} # Move it over to the auxiliary stack.
Şimdi yığınlar:
Main [ ... | 'F' 'G' 'H' 'I' 'J' 'P] ... ] Auxiliary
Bunlardan ilki (basmak istemediğimiz) ana yığına geri götürüyoruz {
. Ve şimdi son 2x2 ( saat yönünün tersine ) döngüsüne giriyoruz , gerisini yazdırıyor:
{ # Pull another character over from the auxiliary stack. Exit the loop
# if that's the zero at the bottom of the stack.
. # Print the character.
Sonunda programı sonlandırıyoruz @
.
'
sayma karakteri gibi birşeyle unary olarak almak doğru mudur ? Örneğin:''123321
?