Cubix, 94 83 82 79 63 56 bayt
p>q'-?w.uh'e@U7.'hqi?oqB-!ul.-..$WWu_q<o'\;>....6t?.../!@
Expanded:
p > q '
- ? w .
u h ' e
@ U 7 .
' h q i ? o q B - ! u l . - . .
$ W W u _ q < o ' \ ; > . . . .
6 t ? . . . / ! @ . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
notlar
- Tercüman, program başladığında giriş alanını devre dışı bırakır. Bu nedenle, sonsuz bir girdi akışı imkansızdır. Bu program girişi karakter karakter alır, bu nedenle bu sınırlama için olmasaydı, düzgün çalışacaktı.
- Bu program yığını temizlemez ve çok çabuk dağınık olur. Bu makinenin görünüşe göre sonsuz girdi akışları verebileceği için, aynı zamanda sonsuz belleğe sahip olduğunu varsaymak makul gözükmektedir.
- Her türlü golf yardımı çok takdir edilmektedir.
Çevrimiçi deneyin
Programı burada deneyebilirsiniz .
açıklama
Genel fikir
Genel fikir, bir karakteri okumak ve ardından değişen karakterlere karşı kontrol etmek istediğimizdir (önce h
, sonra e
sonral
vs.). Kaçırdığımız karakteri takip etmek için, yığının en altında tutuyoruz. İhtiyacımız olduğunda kolayca tekrar tepeye getirebiliriz.
Okuma / Yazma döngüsü
Okuma-yazma döngüsü sadece 5. satırdır. Kullanılmayan tüm karakterler no-ops ( .
) ile değiştirilir :
. . . .
. . . .
. . . .
@ . . .
' h q i ? o q B - ! u l . - . .
. . . . _ . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Bu iki bölüme ayrılabilir: Okuma ve (yazma ve kontrol etme). İlk bölüm, soru işaretini içeren ve içerdiği talimatları içerir. İkinci kısım, hattın geri kalanı. Çünkü bu etrafta dolanıyor, bir yığınla başladığımızı varsayıyoruz.[...]
@
'hqi?
_
Explanation
'h Push the character code of the h
Stack: [..., 104]
q Send it to the bottom
Stack: [104, ...]
i Read one character of the input (-1 for EOF)
Stack: [104, ..., input]
? Start of condition:
if (input < 0):
@ execute '@', ending the program
if (input = 0):
continue going right
if (input > 0):
_ turn to the right, reflect back ('_') and
turn right again, effectively not changing
the direction at all
İkinci kısım (yazı ve kontrol) yine doğrusaldır. Yığın olarak başlar [next-char, ..., input]
. Bir sonraki karakteri soyutladık, çünkü bu programın ilerleyen kısımlarında değişiyor.
oqB-!ul.- Explanation
o Output the character at the top of the stack
q Send the input to the bottom of the stack
Stack: [input, next-char, ...]
B Reverse the stack
Stack: [..., next-char, input]
- Push the difference of the top two characters, which
is 0 if both are equal, something else otherwise
Stack: [..., next-char, input, diff]
! if (diff = 0):
u make a u-turn to the right
else:
l. execute two no-ops
- push [input - next-char - input], which is disregarded
later, so it effectively is a no-op as well.
Şimdi, IP bu döngünün başında tekrar başlayacak ve kontrol edilecek bir sonraki karakteri sıfırlayacak. h
.
Bir sonraki karakterin eşleştirilmesi
IP bir u dönüşü yaptıysa (yani, okuduğumuz ve yazdırdığımız karakter sonraki karakter ile eşleşti 'hello'
), girişin hangi karakter olduğunu kontrol etmemiz gerekir ve buna bağlı olarak, sonraki karakteri yığının dibine iter. Bundan sonra h
, yığına basmadan okuma / yazma döngüsüne geri dönmemiz gerekir , o yüzden oraya ulaşmak için başka bir yola ihtiyacımız var.
İlk önce ilk şeyler: girişin hangi karakter olduğunu belirleyin. Yığın şuna benzer: [..., prev-char, input, 0]
.
. . . .
- ? . .
u h ' e
. . . .
. . . . . . . . . ! u . . . . .
. . . . . . . . . \ ; . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Girişi karşılaştırmak için h
tekrar karakter kodunu kullanırız . Başlangıçta, bunun nedeni, bununla nasıl başa çıkacağımı gerçekten bilmiyordum ve h
kontrol edilecek ilk karakterdi, ama oldukça uygun oldu. Biz girişten h karakteri kodunu çıkarmak, biz olsun -3
girilirse e
, 0
giriş ise h
, 4
girdi ise l
ve 7
giriş ise o
.
Bu kullanışlıdır, çünkü ?
komut negatif değerleri kolayca pozitif değerlerden ve sıfırdan kolayca ayırmamızı sağlar. Dolayısıyla, IP sola dönerse, fark negatif, yani giriş öyleydi e
, bu yüzden bir sonraki karakter bir olmalı l
. IP düz devam ederse, fark öyleydi 0
, bu yüzden giriş, bir h
sonraki karakter bir olmalıdır e
. Giriş bir l
veya bir o
ise, IP sağa döner.
Yukarıda belirtilen soru işaretinden önce gerçekleştirilen tüm talimatlar:
;!e'h- Explanation
; Delete the top of the stack
Stack: [..., prev-char, input]
! if (input = 0):
e execute 'e' (no-op)
'h Push the character code of h
Stack: [..., prev-char, input, 104]
- Push the difference of the input and 104
Stack: [..., prev-char, input, 104, diff]
Şimdi IP yukarıda belirtilen şekilde yönünü değiştiriyor. Farklı olasılıkları gözden geçirelim.
Giriş 'e'
İlk önce , farkın 3 olduğu e
için IP'nin yukarı doğru hareket etmesine neden olan girişi dikkate alacağız ?
. Tüm alakasız karakterler küpten kaldırılmıştır.
. > q '
. ? . .
. . . .
. . . .
. . q . . . . . . . . l . . . .
$ W W . . . . . . . . > . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Karakterler bu sırada yürütülür (bazı kontrol akışı karakterleri hariç):
q'l$WWq
q Save the difference (-3) to the bottom of the stack so
we can tell whether the l on the bottom of the stack is
the first or the second l in hello
Stack: [-3, ...]
'l Push the character code of l to the stack
Stack: [-3, ..., 108]
$W no-op
W Sidestep into the loop
q Send the character code to the bottom
Stack: [108, -3, ...]
Şimdi IP tekrar okuma / yazma döngüsüne ulaştı.
Giriş 'h'
Girdi olsaydı, 'h'
fark 0 olur, bu yüzden IP yönünü değiştirmez. İşte yine küp, ilgisiz tüm karakterler kaldırıldı. Bu yol epeyce no-ops içerdiğinden, geçtiği tüm no-oplar yerini aldı &
. IP soru işaretinde başlar.
. . . .
. ? w .
. . ' e
. . . .
. . . . . . . . . ! . . . . . .
. . . u _ q < . . \ . . . . . .
. . ? & & & / . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
Yürütülen talimatlar:
'e!\?q_
'e Push the character code of the e
Stack: [..., 101]
! if (101 = 0):
\ reflect away (effectively a no-op)
? if (101 > 0):
turn right (always happens)
q Move 101 to the bottom of the stack
Stack: [101, ...]
_ No-op
Ve şimdi tekrar okuma / yazma döngüsüne giriyoruz, bu yüzden işimiz bitti.
Diğer girişler
Diğer tüm girişler pozitif bir farkla sonuçlanır, bu nedenle IP soru işaretinde sağa döner. Hala ayırmak gerekir l
veo
, o yüzden bundan sonra yapacağımız şey bu.
Ayırarak 'l'
ve'o'
Aradaki farkın 7 o
ve 4 için l
olduğunu ve giriş bir ise programı sonlandırmamız gerektiğini unutmayın o
. Burada yine a ile değiştirilmiş alakasız kısımları olan .
ve IP çaprazları ve işareti olmayan no-op'larla değiştirilmiş küp var.
. . q .
. ? w .
. h ' .
. U 7 .
. . . . . . . . . . . . . - . .
. . . . . . . . . . . . . & . .
. . . . . . / ! @ . . . . & . .
. . . . . . & . . . . . . & . .
. . & .
. . & .
. . & .
. . & .
h7'wq-!@
h no-op
7 Push 7 to the stack
Stack: [..., diff, 7]
'wq Push w to the stack and send it to
the bottom. We don't care about it,
so it's now part of the ellipsis.
Stack: [..., diff, 7]
-! if (diff = 7):
@ End the program
İki 'l'
s arasında ayırt
Şimdi girdilerin bir olduğunu biliyoruz l
, fakat hangisini bilmiyoruz l
. Birincisi, l
yığının dibine bir tane daha basmamız gerekir, ancak ikinciyse, bir tane basmamız gerekir o
. İlkini -3
itmeden hemen önce yığının dibine kaydettiğimizi hatırlıyor musun l
? Bunu iki dalı ayırmak için kullanabiliriz.
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
6 t ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Yığın olarak başlar [..., -3 or 140, ...]
Explanation
6t?
6t Take the 6th item from the top and move
it to the top (which is either -3 or 140)
? If that's positive, turn right, otherwise,
turn left
İlk 'l'
Eğer bu 'l'
ilkseydi, bir başkasına basmamız gerekir 'l'
. Bayt kaydetmek için ilk karakterle aynı karakterleri kullanırız 'l'
. Yığını basitleştirebiliriz [...]
. İşte no-op'lar ve işaretleri ile değiştirilmiş küpün ilgili kısmı.
p > q '
. . . .
. . . .
. . . .
' . q . . . . . . . . l . . . .
$ W W . . . . . . . . > & & & &
. . ? . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
Aşağıdaki talimatlar uygulanır:
$'pq'lq
$' no-op
pq no-op
'l Push the character code of l
Stack: [..., 108]
q Send it to the bottom
Stack: [108, ...]
Okuma / yazma döngüsüne girmek üzereyiz, bu yüzden bu dalla işimiz bitti.
İkinci 'l'
Giriş, ikinci ise 'l'
de 'hello'
, IP soru işareti doğru döndü. Bir kez daha, yığını basitleştirebiliriz [...]
ve IP ?
bu kez güneye dönük olarak başlar .
. . . .
. . . .
. . . .
. . . .
. . . . . . . . . . . . . . . .
. . . u _ q < o ' \ . . . . . .
. . ? . . . . . . & . . . . . .
. . & . . . . . . & . . . . . .
. . . .
& & & &
. . . .
. . . .
Yürütülen talimatlar:
'oq_
'o Push the character code of 'o'
Stack: [..., 111]
q Move the top item to the bottom
Stack: [111, ...]
_ No-op
Ve IP tekrar okuma / yazma döngüsüne girmek üzere, bu yüzden de bu dalla işimiz bitti.