<#; "#: ={},>
}=}(.);("@
Aslında yaptığımız @ MartinBüttner, bir başka collab en Bunun için neredeyse golf hepsi. Algoritmayı yenileyerek, program boyutunu biraz azaltmayı başardık!
Çevrimiçi deneyin!
açıklama
Hızlı bir Labrinth primer:
Labirent, yığın tabanlı bir 2B dilidir. İki yığın vardır, bir ana ve yardımcı yığın vardır ve boş bir yığıntan çıkma sıfır verir.
Yönergenin aşağıya hareket etmesi için birden fazla yolun bulunduğu her kavşakta, ana yığının tepesi, nereye gidileceğini görmek için kontrol edilir. Negatif sola, sıfır dümdüz ve pozitif sağa döner.
İki isteğe bağlı tamsayılı yığınının bellek seçenekleri açısından fazla esnekliği yoktur. Saymayı gerçekleştirmek için, bu program aslında iki yığını bir bant olarak kullanır, bir değeri bir yığından diğerine kaydırır ve bir bellek işaretçisini bir hücre tarafından sola / sağa hareket ettirmeye benzer. Bu tam olarak aynı değil, çünkü bir döngü sayacını yukarı çekmemiz gerekiyor.
Öncelikle, <
ve >
her iki ucunda bir ofset açılır ve bir sola veya sağa kaymış olan kod satırını döndürür. Bu mekanizma, kodun bir döngüde çalışmasını sağlamak için kullanılır - <
pop bir sıfır çıkar ve mevcut satırı sola döndürür, IP'yi kodun sağına yerleştirir ve >
pop bir başka sıfır çıkar ve satırı geri düzeltir.
Yukarıdaki diyagramla ilişkili olarak her yinelemede olanlar şöyledir:
[Section 1]
,} Read char of input and shift to aux - the char will be used as a counter
to determine how many elements to shift
[Section 2 - shift loop]
{ Shift counter from aux
" No-op at a junction: turn left to [Section 3] if char was EOF (-1), otherwise
turn right
( Decrement counter; go forward to [Section 4] if zero, otherwise turn right
= Swap tops of main and aux - we've pulled a value from aux and moved the
decremented counter to aux, ready for the next loop iteration
[Section 3]
@ Terminate
[Section 4]
; Pop the zeroed counter
) Increment the top of the main stack, updating the count of the number of times
we've seen the read char
: Copy the count, to determine how many chars to output
[Section 5 - output loop]
#. Output (number of elements on stack) as a char
( Decrement the count of how many chars to output; go forward to [Section 6]
if zero, otherwise turn right
" No-op
[Section 6]
} Shift the zeroed counter to aux
[Section 7a]
This section is meant to shift one element at a time from main to aux until the main
stack is empty, but the first iteration actually traverses the loop the wrong way!
Suppose the stack state is [... a b c | 0 d e ...].
= Swap tops of main and aux [... a b 0 | c d e ...]
} Move top of main to aux [... a b | 0 c d e ...]
#; Push stack depth and pop it (no-op)
= Swap tops of main and aux [... a 0 | b c d e ...]
Top is 0 at a junction - can't move
forwards so we bounce back
; Pop the top 0 [... a | b c d e ... ]
The net result is that we've shifted two chars from main to aux and popped the
extraneous zero. From here the loop is traversed anticlockwise as intended.
[Section 7b - unshift loop]
# Push stack depth; if zero, move forward to the <, else turn left
}= Move to aux and swap main and aux, thus moving the char below (stack depth)
to aux
; Pop the stack depth