Cubix, 238 234 217 151 110 100 bayt
ETHProductions sayesinde 14 bayt kurtardı
u'^.:s+.;;;\-?W?rsos\(rrOIO:ur>'=o;^u.;;.>$.vUo^'rsu1;;@!\q?s*su;;IOu*+qU../;(*\(s.;<..r:''uq....qu\
Expanded:
u ' ^ . :
s + . ; ;
; \ - ? W
? r s o s
\ ( r r O
I O : u r > ' = o ; ^ u . ; ; . > $ . v
U o ^ ' r s u 1 ; ; @ ! \ q ? s * s u ;
; I O u * + q U . . / ; ( * \ ( s . ; <
. . r : ' ' u q . . . . q u \ . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Çevrimiçi deneyin!
Burada dene
açıklama
Kod iki aşamada 8 adımdan oluşmaktadır. Kod bölüm bölüm gözden geçireceğim.
1. Adım (A ^ B)
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
I O : u . . . . . . . . . . . . . . . .
U o ^ ' . . . . . . . . . . . . . . . .
; I O u . . . . . . / ; ( * \ . . . . .
? ? r : . . . . . . ? . . . \ ? ? ? ? ?
. . . . ? . . . . . ? . . . . . . . . .
? ? ? ? ?
. . . . .
. . . . .
. . . . .
. . . . .
Bu, kaldırılan ilk adımla alakasız parçaları olan küp. Soru işareti, IP'nin ziyaret edemediği kişileri yolunu daha net hale getirmek için gösterir.
IO:'^o;IO:r*(; # Explanation
I # Push the first input (A)
O # output that
: # duplicate it
'^ # Push the character "^"
o # output that
; # pop it from the stack
I # Push the second input (B)
O # output that
: # duplicate
r # rotate top 3 elements
* # Push the product of the top two elements
( # decrease it by one
; # pop it from the stack (making the last
# two operations useless, but doing it
# this way saves 10B)
Şimdi, yığın şöyle gözüküyor: A, B, A, B
2. Adım (yazdırma döngüsü için hazırlanın)
Baskı döngü 3 bağımsız değişkenleri (yığın ilk 3 öğeleri) alır: P
, Q
ve R
. P
tekrarların miktarı Q
, ayırıcı (karakter kodu) ve R
tekrarlanacak sayıdır. Neyse ki, döngü de sonuç dizesi sona gerektiğini şartı ilgilenir R
değil Q
.
A*
Tam olarak tekrar etmek istiyoruz B
, bu yüzden ayırıcı *
. Yığın olarak başladığını unutmayın A, B, A, B
. Bir kez daha alakasız talimatları kaldırdım. IP S
kuzeyi işaret etmeye başlar .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . r . . . . . . . . . . . . . . .
. . . . r . . . . . . . . . . . . . . .
. . . . * . . . . . . . . . . . . . . .
. . . . ' . . . . . . . . . . . . . . .
. . . . S . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
'*rr # Explanation
'* # Push * (Stack: A, B, A, B, *)
rr # Rotate top three elements twice
Yığın şimdi A, B, B, *, A
.
Adım 3/6/8 (yazdırma döngüsü)
kavram
E . . . . .
? r s o s u
\ ( r r O <
. . . . . S
IP, döngüye girip S
kuzeye doğru girer ve döngüden E
tekrar kuzeye doğru çıkar . Bu açıklama için, yığın olarak ayarlanır [..., A, B, C]
. Aşağıdaki talimatlar uygulanır. IP'nin döngüden soru işaretinden önce çıkamayacağını, bu nedenle ilk dört talimatın her zaman yürütüleceğini unutmayın.
Orr(?rsos # Explanation
O # Output `C`
rr # Rotate top three elements twice (Stack: [..., B, C, A])
( # Decrease A by one (Stack: [..., B, C, A-1])
? # If top of stack (A) > 0:
r # Rotate top of stack (Stack: [..., A-1, B, C])
s # Swap top elements (Stack: [..., A-1, C, B])
o # Output top of stack (B) as character code
s # Swap top elements (Stack: [..., A-1, B, C]
#
# ... and repeat ...
uygulama
İşte yine küp, alakasız kısımlar çıkarıldı. IP S
doğudan işaret ederek başlar .
. . . . .
. . . . .
. . . . .
? r s o s
\ ( r r O
. . . . . S ' = o ; ^ u . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Gördüğünüz gibi IP, döngüye girmeden önce dört yönergeyle karşılaşır. Karakter kodu tekrar kaldırıldığından, bu parçaya girdiğimizle aynı yığına sahip döngüye ulaşırız.
'=o; # Explanation
'= # Push =
o # Output
; # Pop from stack
Döngünün içinde, yukarıdaki açıklama tutar.
4. Adım (IP'leri ayırt etme)
Yukarıdaki döngüyü birçok kez kullandığımızdan ve hepsi IP'nin aynı noktada bitmesine neden olduğundan, birden fazla çalışma arasında ayrım yapmamız gerekir. İlk olarak, ayırıcıyı ayırabiliriz (ilk çalıştırmada a vardır *
, oysa iki ve üçte bir +
ayırıcı vardır). Tekrarlanan sayının değerini kontrol ederek 2. ve 3. sıraları birbirinden ayırabiliriz. Bu ise, program sonlandırılmalıdır.
İlk karşılaştırma
İşte küpte göründüğü gibi. IP S'de başlar ve kuzeyi gösterir. Yığın içeriyor [..., * or +, A or 1, 0]
. 1 rakamı, bu birinci döngü (kuzeyi işaret eder) ise IP'nin nerede biteceğini gösterir ve 2 sayısı, bu ikinci (veya üçüncü) döngü ise (doğuyu işaret eden) IP'nin nerede biteceğini gösterir.
u ' . . .
s + . 1 .
; \ - ? 2
S . . . .
. . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
;s'+-? # Explanation
; # Delete top element (0)
s # Swap the top two elements (Stack: 1/A, */+)
'+ # Push the character code of +
- # Subtract the top two elements and push
# that to the stack (Stack: 1/A, */+, +, (*/+)-+)
? # Changes the direction based on the top
# item on the stack. If it's 0 (if (*/+) == +)
# the IP continues going right, otherwise, it
# turns and continues going north.
IP şimdi ise 1
, yığın [A, *, +, -1]
. Aksi takdirde, yığın [A or 1, +, +, 0]
. Gördüğünüz gibi, ikinci durumun yığında hala bilinmeyen bir şey var, bu yüzden başka bir karşılaştırma yapmalıyız.
İkinci karşılaştırma
IP 5. adımda, böyle yığın görünüyor geçirdi Çünkü: [A^(B-1) or nothing, A or 1, +, +, 0]
. İlk eleman ise nothing
, ikinci elemandır 1
ve tersi de tutar. Küp bu gibi gözüküyor, IP S'den başlıyor ve doğuya bakıyor. Bu ikinci döngü ise, IP E
batıya dönük olarak sona erer . Aksi takdirde, program vurur @
ve sona erer.
. . . . .
. . . . ;
. . . S W
. . . . .
. . . . .
. . . . . . . . . . . . . ; . . . . . .
. . . . . . . . . E @ ! \ q . . . . . .
. . . . . . . . . . . . ( * . . . . . .
. . . . . . . . . . . . q u . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Kontrol akışına hiçbir şey yapmayan talimatlar aşağıda listelenmiştir.
;;q*q(!@
;; # Delete top two elements (Stack [A^(B-1)/null, A/1, +])
q # Send top element to the bottom (Stack [+, A^(B-1)/0, A/1])
* # Push product of top two elements
# (Stack [+, A^(B-1)/0, A/1, A^B/0])
q # Send top element to the bottom
# (Stack [A^B/0, +, A^(B-1)/0, A/1])
( # Decrease the top element by 1
# (Stack [A^B/0, +, A^(B-1)/0, (A-1)/0])
! # If (top element == 0):
@ # Stop program
Yığın şimdi [A^B, +, A^(B-1), A-1]
, programın sonlandırılmaması şartıyla.
5. Adım ("A +" için hazırlanıyor (A ^ (B-1) 'i tekrarlayın))
Ne yazık ki, Cubix bir elektrik operatörüne sahip değil, bu yüzden başka bir döngüye ihtiyacımız var. Ancak, ilk önce şu anda bulunan yığını temizlememiz gerekir [B, A, *, +, -1]
.
Temizlemek
İşte yine küp. Her zamanki gibi IP, S'de başlar (kuzeyi gösterir) ve E'de biter ve batıya bakar.
. . . ? .
. . . ; .
. . . S .
. . . . .
. . . . .
. . . . . . . . . . . . . . . . > $ . v
. . . . . . . . . . . . . . . . . . . ;
. . . . . . . . . . . . . . . . . . E <
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
;; # Explanation
;; # Remove top 2 elements (Stack: [B, A, *])
A ^ (B-1) hesaplanıyor
Kabaca baskı döngüsüyle aynı şekilde çalışan başka bir döngü, ancak biraz daha kompakt. IP S
, batıya bakacak şekilde istif ile başlar [B, A, *]
. IP E
kuzeyi işaret etmek için çıkar .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . . . . . . . . . . . E . . . . .
. . . . . . . . . . . . . . ? s * s u .
. . . . . . . . . . . . . . \ ( s . ; S
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Döngü gövdesi aşağıdaki gibidir.
;s(?s*s # Explanation
; # Pop top element.
s # Shift top elements.
( # Decrease top element by one
? # If not 0:
s # Shift top elements again
* # Multiply
s # Shift back
#
# ... and repeat ...
Ortaya çıkan yığın [A, A^(B-1), 0]
.
Yığını temizleme (tekrar)
Şimdi yığının üst kısmı ile birlikte tekrar baskı döngüsüne gitmemiz gerekiyor [..., A^(B-1), +, A]
. Bunu yapmak için aşağıdakileri uygularız. İşte yine küp.
. . ^ ? :
. . . . .
. . . . .
. . . . .
E . . . .
. . . . . s . . . . . . . . ; . . $ . .
. . . . . + q U . . . . . . S . . s . .
. . . . . ' u q . . . . . . . . . ? . .
. . . . . . . ? . . . . . . . . . ? . .
. . . . . . . ? . . . . . . . . . ? . .
. . ? . .
. . ? . .
. . ? . .
. . ? . .
. . ? . .
;:$sqq'+s # Explanation
; # Delete top element (Stack: [A, A^(B-1)])
: # Copy top element
$s # No-op
qq # Send top two elements to the bottom
# (Stack: [A^(B-1), A^(B-1), A])
'+ # Push +
# (Stack: [A^(B-1), A^(B-1), A, +])
s # Swap top two elements
# (Stack: [A^(B-1), A^(B-1), +, A])
7. Adım (son döngü için hazırlanıyor)
Yığın şimdi [A^B, +, A^(B-1), A-1]
, IP başlıyor, S
batıya gidiyor ve bitiyor, E
sağa gidiyor
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . . E . . . . . . . . . . . . . .
. . . . . . u 1 ; ; S . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Yürütülen talimatlar:
;;1 # Explanation
;; # Delete top two elements
1 # Push 1
Yığın şimdi benziyor [A^B, +, 1]
ve IP yazdırma döngüsüne girmek üzere, bu yüzden işimiz bitti.