Cubix, 238 234 217 151 110 100 byte
Risparmiato 14 byte grazie a ETHProductions
u'^.:s+.;;;\-?W?rsos\(rrOIO:ur>'=o;^u.;;.>$.vUo^'rsu1;;@!\q?s*su;;IOu*+qU../;(*\(s.;<..r:''uq....qu\
Allargato:
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 \ . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Provalo online!
Provalo qui
Spiegazione
Il codice è composto da 8 passaggi, con due loop. Esaminerò il codice parte per parte.
Passaggio 1 (A ^ B)
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
I O : u . . . . . . . . . . . . . . . .
U o ^ ' . . . . . . . . . . . . . . . .
; I O u . . . . . . / ; ( * \ . . . . .
? ? r : . . . . . . ? . . . \ ? ? ? ? ?
. . . . ? . . . . . ? . . . . . . . . .
? ? ? ? ?
. . . . .
. . . . .
. . . . .
. . . . .
Questo è il cubo con le parti che sono irrilevanti per il primo passo rimosso. Il punto interrogativo mostra le no-op che l'IP visiterà, per rendere più chiaro il suo percorso.
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)
Ora, lo stack è simile al seguente: A, B, A, B
Passaggio 2 (preparare il ciclo di stampa)
Il ciclo di stampa prende 3 argomenti (i primi 3 elementi nello stack): P
, Q
e R
. P
è la quantità di ripetizioni, Q
è il separatore (codice carattere) ed R
è il numero da ripetere. Fortunatamente, il loop si occupa anche del requisito in cui la stringa risultante dovrebbe finire R
, no Q
.
Vogliamo ripetere A*
esattamente i B
tempi, quindi è il separatore *
. Si noti che lo stack inizia come A, B, A, B
. Ancora una volta, ho rimosso tutte le istruzioni irrilevanti. L'IP inizia S
puntando verso nord.
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . r . . . . . . . . . . . . . . .
. . . . r . . . . . . . . . . . . . . .
. . . . * . . . . . . . . . . . . . . .
. . . . ' . . . . . . . . . . . . . . .
. . . . S . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
'*rr # Explanation
'* # Push * (Stack: A, B, A, B, *)
rr # Rotate top three elements twice
Lo stack è ora A, B, B, *, A
.
Passaggio 3/6/8 (il ciclo di stampa)
Concetto
E . . . . .
? r s o s u
\ ( r r O <
. . . . . S
L'IP entra nel loop attraverso S
, puntando verso nord, ed esce dal loop verso E
, puntando di nuovo verso nord. Per questa spiegazione, lo stack è impostato su [..., A, B, C]
. Vengono eseguite le seguenti istruzioni. Nota che l'IP non può lasciare il ciclo prima del punto interrogativo, quindi le prime quattro istruzioni verranno sempre eseguite.
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 ...
Implementazione
Ecco di nuovo il cubo, con le parti irrilevanti rimosse. L'IP inizia da S
, puntando verso est.
. . . . .
. . . . .
. . . . .
? r s o s
\ ( r r O
. . . . . S ' = o ; ^ u . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Come puoi vedere, l'IP arriva attraverso quattro istruzioni prima di entrare nel ciclo. Poiché il codice carattere viene nuovamente rimosso, raggiungiamo il loop con lo stesso stack esatto in cui abbiamo inserito questa parte.
'=o; # Explanation
'= # Push =
o # Output
; # Pop from stack
All'interno del ciclo, la spiegazione sopra vale.
Passaggio 4 (differenziazione degli IP)
Dato che utilizziamo il loop sopra più volte e tutti fanno sì che l'IP finisca nello stesso punto, dobbiamo differenziare tra più esecuzioni. Innanzitutto, possiamo distinguere tra il separatore (la prima esecuzione ha a *
, mentre le corse due e tre hanno un +
separatore). Possiamo distinguere tra le esecuzioni 2 e 3 controllando il valore del numero che si ripete. Se quello è uno, il programma dovrebbe terminare.
Primo confronto
Ecco come appare sul cubo. L'IP inizia da S e punta a nord. La pila contiene [..., * or +, A or 1, 0]
. Il numero 1 mostra dove finirà l'IP se questo è il primo loop (che punta a nord) e il numero 2 mostra dove finirà l'IP se questo è il secondo (o terzo) loop (che punta ad est).
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.
Se l'IP è ora 1
, lo stack è [A, *, +, -1]
. Altrimenti, lo stack è [A or 1, +, +, 0]
. Come puoi vedere, c'è ancora uno sconosciuto nello stack del secondo caso, quindi dobbiamo fare un altro confronto.
Secondo confronto
Poiché l'IP ha attraversato il passaggio 5, gli sguardi di stack come questo: [A^(B-1) or nothing, A or 1, +, +, 0]
. Se il primo elemento è nothing
, il secondo è 1
e anche il contrario. Il cubo si presenta così, con l'IP che inizia da S e punta verso est. Se questo è il secondo loop, l'IP finisce in E
, puntando verso ovest. Altrimenti, il programma colpisce @
e termina.
. . . . .
. . . . ;
. . . S W
. . . . .
. . . . .
. . . . . . . . . . . . . ; . . . . . .
. . . . . . . . . E @ ! \ q . . . . . .
. . . . . . . . . . . . ( * . . . . . .
. . . . . . . . . . . . q u . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Le istruzioni eseguite che non fanno nulla al flusso di controllo sono elencate di seguito.
;;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
Lo stack è ora [A^B, +, A^(B-1), A-1]
, a condizione che il programma non sia terminato.
Passaggio 5 (preparazione per "A +" (ripetere A ^ (B-1)))
Purtroppo, Cubix non ha un operatore di potenza, quindi abbiamo bisogno di un altro loop. Tuttavia, dobbiamo prima pulire lo stack, che ora contiene [B, A, *, +, -1]
.
Pulire
Ecco di nuovo il cubo. Come al solito, l'IP inizia da S (che punta a nord) e termina a E, che punta a ovest.
. . . ? .
. . . ; .
. . . S .
. . . . .
. . . . .
. . . . . . . . . . . . . . . . > $ . v
. . . . . . . . . . . . . . . . . . . ;
. . . . . . . . . . . . . . . . . . E <
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
;; # Explanation
;; # Remove top 2 elements (Stack: [B, A, *])
Calcolo di A ^ (B-1)
Un altro loop che funziona più o meno come il loop di stampa, ma è un po 'più compatto. L'IP inizia da S
, puntando verso ovest, con stack [B, A, *]
. L'IP esce E
indicando il nord.
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . . . . . . . . . . . E . . . . .
. . . . . . . . . . . . . . ? s * s u .
. . . . . . . . . . . . . . \ ( s . ; S
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Il corpo del loop è il seguente.
;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 ...
Lo stack risultante è [A, A^(B-1), 0]
.
Pulire la pila (di nuovo)
Ora dobbiamo tornare al ciclo di stampa, con la parte superiore della pila contenente [..., A^(B-1), +, A]
. Per fare ciò, eseguiamo quanto segue. Ecco di nuovo il cubo,
. . ^ ? :
. . . . .
. . . . .
. . . . .
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])
Passaggio 7 (preparazione per l'ultimo loop)
Lo stack è ora [A^B, +, A^(B-1), A-1]
, l'IP inizia a S
, andando verso ovest, e finisce a E
, andando a destra.
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . . E . . . . . . . . . . . . . .
. . . . . . u 1 ; ; S . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Le istruzioni eseguite:
;;1 # Explanation
;; # Delete top two elements
1 # Push 1
Lo stack ora appare [A^B, +, 1]
e l'IP sta per entrare nel ciclo di stampa, quindi abbiamo finito.