Risolvi un diagramma dello stato dello stack


15

Un diagramma dello stato dello stack mostra come i valori di uno stack vengono modificati nell'altro. Ad esempio, questo è un diagramma dello stato dello stack:

3 0 2 1 0

Ciò significa che esiste inizialmente uno stack contenente 3 valori (la 3parte). Questi valori sono indicizzati da 0 a 2, con 0 in alto: 2 1 0. La parte successiva 0 2 1 0descrive lo stato finale dello stack: anche il valore originariamente in cima allo stack è stato copiato sul retro.

Queste trasformazioni avvengono su uno stack che supporta diversi tipi di dati:

  • Il tipo "valore", che è ciò che è originariamente nello stack. Potrebbe essere una stringa, un numero intero, ecc. Ma non è necessario conoscerne il valore.
  • Il tipo "elenco", che è un elenco contenente valori di qualsiasi tipo di dati.

Per modellare questa trasformazione, sono consentite le seguenti operazioni:

  • S: Scambia i due valori in cima alla pila: 2 1 02 0 1
  • D: Duplica il valore in cima allo stack: 1 01 0 0
  • R: Rimuove il valore più alto dallo stack. 2 1 02 1
  • L: Trasforma il valore più alto in un elenco di un elemento contenente quel valore: 2 1 02 1 (0)
  • C: Concatena le prime due liste in pila: 2 (1) (0)2 (1 0)
  • U: Posiziona tutti i valori di un elenco nello stack: 2 (1 0)2 1 0

Questi sono equivalenti ai comandi Underload~ : ! a * ^ , a condizione che non vengano utilizzati altri comandi.

S, D, R, E Lpuò essere utilizzato con qualsiasi valore in cima alla pila, ma Ce Udeve avere liste in cima alla pila di funzionare. Un invio le cui sequenze generate tentano di eseguire operazioni non valide (come Dsu uno stack vuoto o Usu un non elenco) è errato e deve essere sanzionato .

Per risolvere un diagramma dello stato dello stack, trova una sequenza di comandi che trasformerà correttamente lo stato dello stack iniziale in quello nuovo. Ad esempio, una soluzione 3: 0 2 1 0è LSLCSLCULSLCLSLDCSC USLCU:

   2 1 0
L  2 1 (0)
S  2 (0) 1
L  2 (0) (1)
C  2 (0 1)
S  (0 1) 2
L  (0 1) (2)
C  (0 1 2)
U  0 1 2
L  0 1 (2)
S  0 (2) 1
L  0 (2) (1)
C  0 (2 1)
L  0 ((2 1))
S  ((2 1)) 0
L  ((2 1)) (0)
D  ((2 1)) (0) (0)
C  ((2 1)) (0 0)
S  (0 0) ((2 1))
C  (0 0 (2 1))
U  0 0 (2 1)
S  0 (2 1) 0
L  0 (2 1) (0)
C  0 (2 1 0)
U  0 2 1 0

Il tuo compito è quello di scrivere un programma che prende un diagramma di stato dello stack e genera una soluzione.

Casi test

2 1 0       ->

3 2 0       -> SR

9           -> RRRRRRRRR

2 0 1 0     -> LSLCDCUR

2 0 1 1     -> SD

6 2         -> RRSRSRSR

5 0 1 2 3 4 -> LSLCSLCSLCSLCU

4 2 0 1 3 2 -> LSLCSLSCSLCULSLSCSLSCLSLDCSCUSLCU

Questo è , quindi vince la risposta valida più breve (in byte).


Puoi avere un elenco contenente elenchi? EDIT: Non importa, puoi, è nell'esempio.
orlp

Gli Celenchi di necessità nella prima e nella seconda posizione dello stack? o l'elemento in seconda posizione potrebbe essere aggiunto a un elenco in alto?
edc65,

Celenchi di necessità in entrambe le posizioni. Non ha senso concatenare un valore e un elenco.
Esolanging Fruit,

Risposte:


9

Python 3, 84 byte

lambda n,*s:"DLL"+"L".join(i*"SLSC"+"LSLSCDURLCULCULSC"for i in s[::-1])+n*"SR"+"UR"

Uso:

# Example: 4 2 0 1 3 2 -> LSLCSLSCSLCULSLSCSLSCLSLDCSCUSLCU
>>> f = lambda ...
>>> f(4, 2, 0, 1, 3, 2)
'DLLSLSCSLSCLSLSCDURLCULCULSCLSLSCSLSCSLSCLSLSCDURLCULCULSCLSLSCLSLSCDURLCULCULSCLLSLSCDURLCULCULSCLSLSCSLSCLSLSCDURLCULCULSCSRSRSRSRUR'

Spiegazione: Per iniziare dupliciamo lo zero e lo inseriamo in un elenco:

DL -> 3 2 1 0 (0)

Questa è la nostra base Ora spiegherò un algoritmo generale che si trasforma ... 1 0 (x)in ... 1 0 (i x)intero arbitrario i. Userò come esempio i = 2e abbiamo un elenco arbitrario (x). Iniziamo avvolgendo il nostro elenco attuale (x)in un altro elenco:

L -> 3 2 1 0 ((x))

Ora ripetiamo i seguenti itempi di sequenza :

SLSC -> 3 2 1 (0 (x))
SLSC -> 3 2 (1 0 (x))

Ora siamo pronti per inserire il 2 nell'elenco (x). Questo è il seguente:

LSLSC -> 3 (2 (1 0 (x)))
DU -> 3 (2 (1 0 (x))) 2 (1 0 (x))
RLCU -> 3 2 (1 0 (x)) 2
LCU -> 3 2 1 0 (x) 2
LSC -> 3 2 1 0 (2 x)

Nota che continuiamo a spingere nuovi numeri interi a sinistra. Quindi il primo in cui (0)abbiamo iniziato rimane sulla destra.

Dopo aver inserito tutti i numeri interi di cui abbiamo bisogno nell'elenco, rimuoviamo il resto dello stack scambiando e rimuovendo n time ( SR). Infine decomprimiamo il nostro elenco ed eliminiamo il primo che 0abbiamo inserito per iniziare il nostro elenco ( UR).


Intendevi digitare sinvece di l?
Zacharý,

@ZacharyT Oops, sì. Ha funzionato mescolando le cose perché è lstato definito sul mio REPL.
orlp

L'esempio mostrato non sembra funzionare ... ( DLLSLSCSLSCSLSCSLSCLSLSCDURLCULCULSCLSLSCSLSCSLSCLSLSCDURLCULCULSCLSLSCSLSCLSLSCDURLCULCULSCLSLSCLSLSCDURLCULCULSCLLSLSCDURLCULCULSCSRSRSRSRUR ). Tenta di eseguire Sun'istruzione quando c'è solo 1 valore nello stack.
Esolanging Fruit,

@ Challenger5 E ho anche dimenticato di aggiornare l'esempio ... Dovrebbe essere risolto ora.
orlp

Sì, adesso sta bene!
Esolanging Fruit,

0

CJam, 54 byte

Solo una traduzione dalla soluzione Python di orlp in CJam. Non c'è niente di nuovo qui.

"DLL"q~("SR"*\W%{"SLSC"*"LSLSCDURLCULCULSC"+}%'L*\"UR"

Spiegazione:

"DLL"                  e# Push string
q~                     e# Read input and evaluate
(                      e# Pop the first value
"SR"                   e# Push string
*                      e# Repeat string n times
\                      e# Swap (bring s to front)
W%                     e# Reverse
{                      e# For each:
  "SLSC"               e#   Push string
  *                    e#   Repeat i times
  "LSLSCDURLCULCULSC"+ e#   Append string to end
}%                     e# End
'L*                    e# Join with 'L'
\                      e# Swap (bring "SR"*n to front)
"UR"                   e# Push string
                       e# [Stack is implicitly output.]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.