Intérprete de manipulación de cuerdas

11

Resumen

¡Se ha creado un nuevo lenguaje de manipulación de cadenas, utilizando solo los caracteres $+#-!*|@>! Su tarea es implementar un intérprete en el menor número de bytes posible.

Entrada

Una cadena, que es una sola línea de este lenguaje. Esto se puede tomar de cualquier manera razonable (stdin, parámetro de función, argumento de línea de comando, etc.), o como una variable predefinida. Si el programa solicita la entrada del usuario, acepte toda la entrada del usuario que solicita de stdin y nada más, consulte a continuación. Puede suponer que es un programa válido.

Salida

Cualquiera que sea el idioma que salga, especificaciones a continuación. Debe generar una cadena de cualquier manera razonable (stdout, salida de función, etc.) o un valor variable. Cuando el lenguaje sale explícitamente, esto debe ir a stdout. Las lagunas estándar están prohibidas.

Especificaciones de idioma

Procesamiento y sintaxis

El lenguaje tiene una forma muy simple de procesamiento, ya que solo manipula cadenas: comienza con una cadena vacía ( "") y la cambia con cada término. Un término se compone de una o dos partes: una función (abajo) seguida posiblemente de un parámetro (abajo), que edita su comportamiento. Los términos están separados por tuberías ( |). Puede suponer que no será un programa vacío y que ningún término estará vacío. Debe generar el valor al final del programa.

Las funciones

El lenguaje tiene solo 6 funciones, como se muestra a continuación. Cada función acepta uno o cero parámetros.

  • + concatenar cadenas (toma un parámetro de cadena, lo concatena al valor actual)
  • ! invertir el orden de los caracteres del valor actual (sin parámetro)
  • * repite la cadena (toma un parámetro entero, repite el valor actual muchas veces)
  • - elimina todas las ocurrencias de un valor (toma un parámetro de cadena, elimina todas las ocurrencias del valor actual)
  • $ [pseudo-] baraja aleatoriamente el valor actual (sin parámetro)
  • <enviar el valor actual a stdout(sin parámetros)

Valores

Estos son los valores que se pueden pasar a las funciones, representados por expresiones regulares que los emparejarían:

  • @[^|]*un literal de cadena, que incluye cualquier carácter que no sean tuberías. Puede estar vacio.
  • #[0-9]+ un literal entero
  • >la proxima linea de stdin. Si se usa con *, convertir a entero.

Casos de prueba

╔════════════════════════╤═════════════╤══════════════╗
║code                    │input        │output        ║
╟────────────────────────┼─────────────┼──────────────╢
║+>|!|+@hello|*>         │13           │31hello31hello║
║                        │2            │              ║
╟────────────────────────┼─────────────┼──────────────╢
║+>|+@abcdefg|$          │hello        │hcloeebafdlg  ║
╟────────────────────────┼─────────────┼──────────────╢
║+@how areyou|-@o|->     │w            │h areyu       ║
╟────────────────────────┼─────────────┼──────────────╢
║+@out|<|*#3             │             │out           ║
║                        │             │outoutout     ║
╟────────────────────────┼─────────────┼──────────────╢
║+>                      │what ever 345│what ever 345 ║
╟────────────────────────┼─────────────┼──────────────╢
║+@$pe<i@l|<|-@$pe<i@l|+>│A|$o $pe<!@| │$pe<i@l       ║
║                        │             │A|$o $pe<!@|  ║
╟────────────────────────┼─────────────┼──────────────╢
║<|+>|!|<                │input text   |              ║
║                        │             │txet tupni    ║ 
║                        │             │txet tupni    ║
╟────────────────────────┼─────────────┼──────────────╢
║+@>#                    │             |>#            ║
╚════════════════════════╧═════════════╧══════════════╝

Tenga en cuenta que el caso de prueba 2 es aleatorio, por lo que cualquier permutación de los caracteres es válida. Además, los resultados de la tabla están separados por nuevas líneas, pero su programa no tiene que hacer lo mismo. El último valor en cada caso es la salida final.

Ejemplo de intérprete de Python (sin golf)

Pruébalo en línea! OMI mejor si lo ejecutas a través de IDLE o lo que sea que uses. (Después lo bajé a 424 bytes, pero estoy seguro de que muchos pueden hacerlo mejor).

Artemisa todavía no confía en SE
fuente
2
Permitir que la entrada ya esté en una variable no es estándar, al igual que permitir que la salida esté en una.
Jonathan Allan
Sus ejemplos parecen imprimir una nueva línea cada vez que <se encuentra. ¿Es esto obligatorio?
Encarnación de la ignorancia
¿Tendrá el programa nuevas líneas? Porque si puede, invalida la respuesta de Chas Brown
Encarnación de la ignorancia
2
Para sus preguntas futuros, por favor considere evitando engorrosos formatos de E / S . Limitar la entrada a stdin cuesta bytes adicionales en algunos idiomas y no aporta mucho al desafío.
Arnauld
1
@digEmAll ¿Cómo está el que acabo de agregar +@>#? Yo solía #también.
Artemis todavía no confía en SE

Respuestas:

3

Ruby -palF\| , 146 142 bytes

r='';$F.map{|i|x=i[1]!=?>?i[2..-1]:gets.chomp;eval %w[r.reverse! r*=x.to_i 0 $><<r r=r.chars.shuffle*'' r.gsub!x,'' r+=x][i[0].ord*5%11]};$_=r

Pruébalo en línea!

La respuesta de Python de Port of Chas Brown . No imprime nuevas líneas después de la salida.

Como de costumbre, la versión Ruby 2.6 será 2 bytes más corta con indexación de rango sin fin ( i[2..]).

Kirill L.
fuente
6

R , 287 286 273 269 bytes

function(C,x='',`[`=gsub,`!`=intToUtf8,`?`=utf8ToInt){for(k in el(strsplit(C,'\\|'))){B=eval(parse(t='^.'['','(?<=.)>$'['readLines(,1)','[@#](.+)'['"\\1"',k],,T]]));x=switch((?substr(k,1,1))%%13-2,strrep(x,B),paste0(x,B),,B['',x,f=T],!rev(?x),print(x),,!sample(?x))};x}

Pruébalo en línea!

  • -1 gracias a @Kirill L.
  • -4 gracias a @Giuseppe

Código desenrollado y explicación:

function(C){                                      # C is the string manipulation expression
  x = ''                                          # initialize x = ''
  tokens = el(strsplit(C,'\\|'))                  # split C by pipe '|'
  for(k in tokens){                               # for each token k
    arg2 = k
    arg2 = gsub('[@#](.+)','"\\1"',k)             # replace @X or #X with "X" (in quotes)
    arg2 = gsub('(?<=.)>$','"readLines(,1)"',
                 arg2,perl=T)                     # replace > with readLines(,1)
    arg2 = gsub('^.','',arg2)                     # remove the first character
    B = eval(parse(t=arg2))                       # evaluate the string : this will be our 
                                                  # second argument B
    A = substr(k,1,1)                             # take the first character : 
                                                  # i.e. the main command (+,-,! etc)
    x = switch(A,                                 # switch on the main command, execute the 
            '+'=paste0(x,B),                      # corresponding expression and 
            '!'=intToUtf8(rev(utf8ToInt(x))),     # store the result into x
            '*'=strrep(x,B),                      # Note: in the actual code we switch on
            '-'=B['',x,f=T],                      # the utf8 value MOD 13-2 of the command
            '$'=intToUtf8(sample(utf8ToInt(x))),
            '<'=print(x)
        )
    }
    x                                             # return x (and print it implicitly)
}
digEmAll
fuente
3

Python 2 , 215 219 209 208 bytes

from random import*
I=raw_input;o=''
for t in I().split('|'):p=t[1:]=='>'and I()or t[2:];exec"o=o[::-1] o*=int(p) 0 print(o) o=''.join(sample(o,len(o))) o=o.replace(p,'') o+=p".split()[ord(t[0])*5%11]
print o

Pruébalo en línea!

-4 porque raw_inputse requiere.

9 bytes gracias a Encarnación de la ignorancia ; 1 byte de Ascii-only .

Chas Brown
fuente
La entrada que no sea el programa debe ser de stdin, como se especifica en la pregunta.
Artemis todavía no confía en SE
Yo uso Python 3, pero que yo sepa, ese uso de entrada requiere raw_input. Corrígeme si me equivoco ...
Artemis todavía no confía en SE
De acuerdo con Py 2.7 docs: input([prompt])Equivalente a eval (raw_input (prompt)). Esta función no detecta errores del usuario. Si la entrada no es sintácticamente válida, se generará un SyntaxError.
Artemisa todavía no confía en SE
Entonces, el problema que está planteando es algo así como aquí , donde las cadenas de entrada tendrían que ser citadas, en lugar de no citadas como en una situación estándar 'verdadera'. Nuevamente, generalmente las reglas de E / S son un poco laxas; pero lo modificare
Chas Brown el
Gracias por cambiar Puede guardar algunos bytes cambiando a Python 3 y usando su código anterior + 3 bytes para paréntesis, pero ... +1 de todos modos
Artemis todavía no confía en SE
2

C # (compilador interactivo de Visual C #) , 305 bytes

a=>{string s="",d,g;foreach(var c in a.Split('|')){g=$"{c,2}";d=g[1]==62?ReadLine():g.Substring(2);var z=c[0]%14;s=z<1?string.Concat(Enumerable.Repeat(s,int.Parse(d))):z<2?s+d:z<4?s.Replace(d,""):z<5?s:z<6?string.Concat(s.Reverse()):string.Concat(s.OrderBy(_=>Guid.NewGuid()));Write(z==4?s:"");}return s;}

Pruébalo en línea!

Encarnación de la ignorancia
fuente
1

Perl 5 -MList::Util=shuffle -pF/\|/ , 220 217 210 183 bytes

map{$,=s/..//r;$\=reverse$\if/^!/;$,ne""||chomp($,=<>),$\=~s/\Q$,//g if/^-/;say$\if/^</;$\=join"",shuffle$\=~/./g if/^\$/;$\.=$,eq""?<>=~s/\n//r:$,if/^\+/;$\x=$,eq""?<>:$,if/^\*/}@F}{

Pruébalo en línea!

Xcali
fuente
1

Javascript, 292 267 bytes

f=(p)=>{c='';p.split`|`.map(l=>{v=l.substr(2);v=l[1]=='#'?parseInt(v):l[1]=='>'?prompt():v;c={'+':_=>c+v,'-':_=>c.split(v).join``,'*':_=>c.repeat(v),'$':_=>[...c].sort(_=>.5-Math.random()).join``,'!':_=>[...c].reverse().join``,'<':_=>alert(c)||c}[l[0]]();});return c}

JSFiddle

Johan du Toit
fuente
El caso de prueba 6 no funciona del todo ...
Artemis todavía no confía en SE
1
@ArtemisFowl, gracias, la expresión regular no funcionaba correctamente y cambiar a dividir ... unirse ahorró un par de bytes.
Johan du Toit