RLE Brainfuck dialecto

14

RLE Brainfuck

(relacionada con BF-RLE )

El hipotético dialecto RLE ( Run-Length Encoding ) de Brainfuck acepta los símbolos para los 8 comandos y también acepta dígitos. Los dígitos se utilizan para representar el número de repeticiones sucesivas de un comando, lo que permite la codificación de longitud de ejecución del código fuente.

8>es igual a >>>>>>>>.

La longitud siempre está en el lado izquierdo del comando.

Su tarea es escribir el programa / función más corto que traduzca la cadena de entrada (fragmento RLE Brainfuck) en un programa Brainfuck normal.

Por ejemplo:

Entrada:

10+[>+>3+>7+>10+4<-]3>2+.>+.7+2.3+.2<2+.>15+.>.3+.6-.8-.2<+.<.

Ouptut:

++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>++.>+.+++++++..+++.<<++.>+++++++++++++++.>.+++.------.--------.<<+.<.

Ganará el código más corto en recuento de bytes en cada idioma.

Galen Ivanov
fuente
10
Hola, rechacé esta pregunta porque siento que va a estar dominada por uno o dos algoritmos de expresión regular basados ​​en RLE que luego se copian al formato de expresión regular individual de cada idioma. Aquí hay muy poco espacio para jugar al golf.
AdmBorkBork
13
Esto se parece mucho a un desafío genérico de decodificación de longitud de ejecución . La diferencia aquí es que se admiten números de varios dígitos. Creo que todavía es un engaño, pero no lo martillaré.
xnor
44
@xnor La otra diferencia es que los dígitos no siempre están presentes: esta forma de RLE garantiza mucha menos estructura, y la OMI puede conducir a técnicas interesantes (¡compare mi respuesta de Python aquí con la del desafío vinculado!)
Lynn
1
@ Lynn No he descrito esto explícitamente, pero como se ve en el ejemplo, se omite 1; agregar 0 no acorta la cadena, por lo que la respuesta es no, no hay ceros que puedan anteponer un comando.
Galen Ivanov
66
La otra dirección sería más interesante, creo (es decir, transformar un programa brainfuck en el programa RLE brainfuck equivalente más corto).
Paŭlo Ebermann

Respuestas:

24

Python 2 , 62 61 bytes

lambda s:eval(re.sub('(\d*)(.)',r'+1*\1*1*"\2"',s))
import re

Pruébalo en línea!

La sustitución de expresiones regulares se expande 3<2+-en la cadena:

+1*3*1*"<"+1*2*1*"+"+1**1*"-"

que luego se evaled. (Observe cómo cuando \1está vacío, obtenemos 1**1 = 1). El primero +es un operador unario que se une al primer número, y los otros +s son concatenación de cadenas. Esto supera a lo más obvio

lambda s:re.sub('(\d+)(.)',lambda m:int(m.group(1))*m.group(2),s)
import re

por 14 bytes. Por lo general "\2"no lo haría siempre trabajo, pero por suerte \y "no son comandos brainfuck.


xnor guardó un byte, proporcionando el 1*\1*1truco. Anteriormente tenía \1Len la expresión regular, y se define L=1como un argumento lambda, que también es bastante bueno: 3Les un largo int literal y Les una variable.

Lynn
fuente
1
Es un uso hábil de Lmanejar la cadena vacía. Sin embargo, hay un camino más corto r'+1*\1*1*"\2"'.
xnor
3
... ¿Por qué está import redebajo de la lambda?
Financia la demanda de Mónica el
1
Poner el lambda primero significa que puedo usar la función de encabezado / pie de página de tio.run para mostrar cómo se supone que se debe invocar el código (lo puse f=\ en el encabezado, ¡ahora el lambda tiene un nombre!)
Lynn
18

Pyth , 2 bytes

r9

Pruébalo aquí!

Cómo funciona

r9: programa completo que recibe la cadena de STDIN.

r: conjunto de operaciones de cadena extendidas de Pyth.
 9 - El noveno comando de ese conjunto (decodificación de longitud de ejecución). Esto admite números de varios dígitos.
Sr. Xcoder
fuente
31
Recordatorio necesario: deja de votar por soluciones triviales (como esta).
Sr. Xcoder
44
No es tan trivial saber sobre ese comando, y saber que funciona cuando faltan números
Luis Mendo
1
@ Mr.Xcoder Espera, ¿qué? ¿No es todo el punto de código de golf tener el conteo de bytes más bajo?
Diácono
44
@Deacon sí, pero una respuesta de Python con golf suele ser mucho más difícil de hacer y más interesante que una respuesta de golf de 2 bytes.
Stephen
8
@Deacon Upvoting no se trata solo de upvoting soluciones cortas. En general, se alienta a los usuarios a votar sobre soluciones que sean interesantes y creativas en lugar de soluciones cortas triviales en idiomas de golf.
Letra de
17

Lua, 65 64 63 Bytes

Excelente ! ¡Por una vez, Lua vence a Python!

Editar: guardado un byte gracias a @Jarhmander, gracias a él por el truco útil para forzar un solo resultado

print(((...):gsub("(%d+)(.)",function(a,b)return b:rep(a)end)))

Pruébalo en línea!

Explicaciones

print)((...):gsub(             -- iterate over the argument and replace the strings
            "(%d+)(.)",       -- matching this pattern (at least one digit and a non-digit)
            function(a,b)     -- capture the digit and non-digit parts in separate variables
              return b:rep(a) -- repeat the non-digit a times, a being the digit part
            end)))                    
Katenkyo
fuente
1
Vencerte :)
Lynn
@ Lynn ¡Un byte menos, quedan 3 más!
Katenkyo
Puede guardar un byte eliminando ,""y encerrando entre paréntesis todo el argumento de impresión. Las expresiones entre paréntesis se ajustan a un valor en Lua (ver lua.org/manual/5.3/manual.html#3.4 ).
Jarhmander el
11

Scala , 73 69 bytes

"(\\d+)(.)".r.replaceSomeIn(_:String,m=>Some("$2"*m.group(1).toInt))

Pruébalo en línea!

oowekyala
fuente
2
Esta es una buena respuesta! Bienvenido al sitio. :)
DJMcMayhem
8

vim, 29 25 23 22 16 bytes

:s/\D/a&<C-v><ESC>/g
D@"

<C-V>es 0x16, <ESC>es 0x1b.

Funciona reemplazando cada no dígito con un comando que agrega ese carácter al búfer. Los recuentos se dejan solos y modifican esos comandos. En este punto, el búfer es un programa vimscript que produce el programa Brainfuck deseado, por lo que lo colocamos en un registro y lo ejecutamos.

Pruébalo en línea!

Editar: Reducciones de tamaño gracias a sugerencias: H.PWiz: 5, TheFamilyFroot: 5, DJMcMayhem: 1

Rayo
fuente
TheFamilyFroot tenía un buen consejo de golf: no necesita usar un grupo de captura, solo puede usar el grupo 0 (&o\0) en su lugar sin paréntesis. Además, un consejo de mí, no TheFamilyFroot es que se puede utilizarDen lugar deddpor-1byte.
DJMcMayhem
1
Gracias por todas las sugerencias, H.PWiz, TheFamilyFroot y DJMcMayhem. Eso lo llevó por debajo de la solución Perl de 18 bytes y al segundo lugar. Ahora solo necesitamos encontrar otros 15 bytes de los que podamos deshacernos y vencerá al Pyth incorporado. :-)
Ray
8

RLE Brainfuck, 204 bytes

-3>,[[->+>+<<]>>47-3<10+<->[-<+4>->+<[>-]>[3<+<[-]4>->]5<]3>57+[-]+<<[>>-<<[3>+3<-]]3>[3<+3>-]<[>>+7<+[->11-<+[-<+]->>+[-<[->10+<]>>+]<[-4>.4<]4>[-]-3<-<+7>-7<[8>+8<-]]8>[8<+8>-]<[3<.3<[-]-6>-]7<--5>-]<,]

Según tengo entendido, las especificaciones para el entorno de brainfuck no están súper bien definidas. Este programa asume que las celdas en la cinta permiten enteros positivos y negativos arbitrariamente grandes, sin desbordamiento. Este código también transcribirá comentarios que no sean de comando, pero expandirá la codificación de la longitud de ejecución de los comentarios (por ejemplo, "ver 3b" → "ver bbb"). El programa resultante debería ejecutarse igual, así que no estoy demasiado preocupado.

Estoy bastante seguro de que todavía podría jugar unos pocos bytes de esto, pero estoy cansado de trabajar con él.

Aquí está el intérprete personalizado + pruebas que he estado usando para probarlo. Si pasa la entrada en el cuadro Entrada estándar, debería ejecutarse contra esa entrada en lugar de ejecutar las pruebas.

Mi área de trabajo desordenada y sin golf:

->>>,
[
  [->+>+<<]>>  clone 2 into 3 and 4
  if read char is between zero and nine
  (num buffer | max | is_digit | original char | read | temp0 | temp1)
                                                   ^
  47-
  <<<10+  set max
  <->  handle gross 0 case
  [  while max
    -  max minus one
    <+  buffer plus one
    >>>>-  read minus one
    IF STATEMENT : if read is 0
    >+<
    [>-]>[<
      <<+  is_digit = 1
      <[-]>>>  max = 0
    >->]<<  back to read
    <<<     back to max
  ]

  >>>57+[-]  reset `read` (need to add first to avoid infinite negative)

  +<<  check is_digit flag
  ( end marker | 0 | is_digit | original char | temp0 | temp1 | temp2 | temp3)
  x[  IF READ WAS DIGIT
    CODE 1a
    >>temp0 -<<x
    [>>>temp1 +<<<x-]
  ]
  >>>temp1 [<<<x+>>>temp1 -]
  <temp0 [
    START CODE 2a
    >>temp2 +
    7<y+[  IF THERE IS A NUMBER PREFIX
      -
      START CODE 1b
      >11-  end marker is negativeone
      <   on smallest digit
      +[-<+]->  find largest digit
      >+[  sum digits until we hit the end marker negativeone
        -
        <[->10+<]>  h1 = ten * h0; h0 = 0
        >
        +
      ]  leave the negativeone at zero though
      num | 0 | 0 | 0 | original char
            ^
      <num
      [->>>>.<<<<]  print `original char` `num` times
      >>>>[-]-  set `char` to negativeone
      <<<- last ditch guess
      END CODE 1b
      <y+
      7>temp2 -
      7<y[8>temp3 +8<y-]
    ]
    8>temp3 [8<y+8>temp3 -]
    <temp2 [
      CODE 2b
      <<<.  print original char
      <<<[-]-  set num buffer to new left edge
      >>>>>>temp2 -
    ]
    7<y--

    END CODE 2a
    5>temp0 -
  ]
  <
  ,
]
Orez
fuente
¿El caso bruto 0 solo se refiere a recuentos de cero reales, o también ocurre al analizar, por ejemplo 10+? El OP aclaró en un comentario que el recuento siempre será mayor que 0, por lo que es posible que pueda recortar algunos bytes si es el primero.
Ray
El caso bruto 0 es para analizar cualquier 0. Dado que el while maxbucle siempre se ejecuta al menos una vez, y estoy subiendo incondicionalmente el búfer donde almaceno el valor del dígito en ese bucle, necesito iniciar ese búfer en -1. Me pregunto si podría guardar algunos bytes al dejar ese búfer lógicamente en value+1at
Orez
6

Apilado , 24 bytes

['(\d+)(.)'[\#~*]3/repl]

Pruébalo en línea!

Explicación

['(\d+)(.)'[\#~*]3/repl]
[                      ]   anonymous function, taking string as argument
 '(\d+)(.)'                for all matches of this regex:
           [    ]3/repl      replace (stack = (whole match, digit, repetend))
            \#~              convert digit to number
               *             repeat the character by that digit
Conor O'Brien
fuente
5

TeX, 124 bytes

\newcount\n\def\b{\afterassignment\r\n0}\def\r#1{\ifx;#1\else\p#1\expandafter\b\fi
}\def\p#1{#1\ifnum\n>1\advance\n-1\p#1\fi}

(escribió en dos líneas para ser visible, pero el código se puede escribir en una línea)

Esto define una macro \bque toma la entrada en el formulario \b<input>;e imprime la salida deseada para el documento.

Manuel
fuente
5

Retina , 28 23 bytes

gracias a @Leo por -5 bytes

\d+
$*
+`1(1\D)
$1$1
1

Pruébalo en línea!

ovs
fuente
¿Se puede usar \ben la segunda expresión regular para que solo coincida con una 1por ejecución de 1s?
Neil
O podrías hacer algo como esto
Leo
4

Pyon , 66 bytes

print(re.sub("\d+.",lambda k:(int(k.group()[:-1])*k.group()[-1]),a

Pruébalo en línea!

Pyon es más o menos Python, pero es más corto porque rese importa automáticamente cuando lo usa, ya se establece automáticamente en un argumento o la entrada

-4 bytes gracias al Sr. Xcoder

Hiperneutrino
fuente
Debe cambiar g[0]a g[:-1](falla para el caso de prueba dado o cualquier número superior a 9).
Sr. Xcoder
De todos modos, ¿por qué necesitarías un lambdaque realmente desperdicia bytes? Golfed y corregido por 66 bytes
Mr. Xcoder
@ Mr.Xcoder grita, no estoy seguro de lo que estaba pensando ... gracias
HyperNeutrino
@ Mr.Xcoder oh sí, trato de jugar muchas cosas que terminan siendo ungolfs xD
HyperNeutrino
4

Pitón 2 , 100 93 89 bytes

-7 con agradecimiento a Mr.Xcoder

n=b=""
for y in input():
 if"/"<y<":":n+=y
 elif""==n:b+=y
 else:b+=y*int(n);n=""
print b

Pruébalo en línea!

ElPedro
fuente
Unos campos de golf para 93 bytes . Sin embargo, se puede jugar más al golf.
Sr. Xcoder
3

R , 121 106 90 bytes

function(s,a=strsplit)cat(rep(el(a(gsub("\\d","",s),"")),pmax(el(a(s,"\\D")),"1")),sep="")

Pruébalo en línea!

Se guardaron 15 bytes al darse cuenta de que rep()se convertirá en numérico. Ahorré otros 16 gracias a Giuseppe, principalmente por el uso de pmaxreemplazar cadenas vacías con1

function(s) {
  x <- el(strsplit(s,"\\D")) # Split the string on anything that is not a digit...
  x <- pmax(x, "1")          # ... and replace any empty strings with 1. This gets us the numbers of repeats
  y <- gsub("\\d","",s)      # Remove all digits from the original string...
  y <- el(strsplit(y))       # ... and split into individual units. This gets us the symbols to repeat
  z <- rep(y, x)             # Implement the repeats. x is coerced to numeric
  cat(z, sep = "")           # Print without separators
}
usuario2390246
fuente
¡muy agradable! Creo que ifelse(x>"",x,1)es un byte más corto, y \\Des equivalente [^\\d] y lo mejor de todo, no es necesario perl=T, por lo que este es un dulce 99 bytes . ¡Realmente no pensé que esto podría ser menos de 100 bytes!
Giuseppe
90 bytes conpmax
Giuseppe
@Giuseppe Uso muy inteligente de pmaxdar una gran mejora agradable - ¡gracias!
user2390246
reemplace "1"con 1lo pmaxque obligará a characterla comparación.
Giuseppe
85 bytes cambiando los alias
Giuseppe
2

PowerShell , 66 62 bytes

-join("$args"-split'\b'|%{(,$(,$_[0]*$n+$_))[!!($n=$($_-1))]})

Pruébalo en línea!

Descompostura

¡Que desastre!

A partir de $args, que es una matriz de un solo elemento que contiene la cadena RLE, estoy forzando una cadena real envolviéndola entre comillas.

Luego divídalo por límite de palabra (\b en expresiones regulares). Eso me dará una serie de cadenas, donde cada elemento es un número o los tokens BF que vienen después del número. Entonces, en el ejemplo, los primeros 4 elementos de esta matriz dividida son10 , +]>+>, 3,+> (todos son cadena).

Luego, canalizo eso en ForEach-Object (% ) para tratar con cada elemento .

El centro es un conocido golfismo de PowerShell, con un giro; Es esencialmente un operador ternario de bricolaje, en el que crea una matriz de 2 elementos y luego lo indexa utilizando la expresión booleana que desea probar, por lo que un resultado falso le da el elemento 0 y un resultado verdadero le da el elemento 1.

En este caso, en realidad creo una matriz de un solo elemento con la coma unaria , , porque no quiero salida en el caso verdadero.

Primero echemos un vistazo al indexador, aunque se ejecute más tarde.

La idea de esto es que $_(el elemento actual) podría ser un número válido o alguna otra cadena. Si es un número, quiero $nser el valor de ese número menos 1 (como un número, no una cadena). Si no es así, quiero$n ser falso.

PowerShell generalmente intenta forzar el valor de la mano derecha al tipo del lado izquierdo, pero puede depender de la operación. Además, "10"+5le daría una nueva cadena "105", mientras que 10+"5"le dará un entero ( 15).

Pero las cadenas no se pueden restar, por lo que PowerShell puede inferir el valor numérico automáticamente con una cadena en el lado izquierdo de la resta, por lo tanto "10"-5 da5 .

Entonces, empiezo con $_-1, lo que me dará el número que quiero cuando en $_realidad es un número, pero cuando no lo es, no obtengo nada. En la superficie, "nada" es falsey, pero el problema es que detiene la ejecución de esa tarea, así que$n lo que conservará su valor anterior; no es lo que quiero!

Si lo envuelvo en una subexpresión, cuando falla, obtengo mi valor falsey: $($_-1) .

Todo eso se asigna $ny dado que esa asignación está envuelta entre paréntesis, el valor que se asignó a$n también se pasa a la canalización.

Como lo estoy usando en el indexador y quiero que, 1si la conversión se realizó correctamente, utilizo dos notexpresiones booleanas !!para convertir este valor en booleano. Una conversión de números exitosa termina siendo cierta, mientras que la nada falsa nos da ese dulce, dulce0 que permite devolver el único elemento en ese falso conjunto ternario.

Volviendo a esa matriz, el elemento es este: $("$($_[0])"*$n*$_) $(,$_[0]*$n+$_)

"$($_[0])"- esta es una forma molestamente larga de obtener el primer carácter del elemento actual (digamos, obteniendo +de +[>+), pero como una cadena y no como un[char] objeto. Necesito que sea una cadena porque puedo multiplicar una cadena por un número para duplicarla, pero no puedo hacerlo con un carácter.

En realidad, logré guardar 4 caracteres usando una [char]matriz en lugar de una cadena (usando otra coma unitaria ,), por lo que pude eliminar las comillas y la subexpresión adicional. I puedo multiplicar una matriz para duplicar sus elementos. Y dado que el resultado completo de esta iteración termina siendo una matriz de todos modos y debe ser-join editado, el uso de una matriz aquí no conlleva ningún costo adicional.

Luego, multiplico esa matriz de cadenas por $n, para duplicarla $nveces. Recuerde que $npodría ser $nullo podría ser el valor de los dígitos anteriores menos uno.

Luego +$_agrega el elemento actual al final del primer carácter duplicado de ese elemento. Por eso $nes menos uno.

De esta manera, 10+[>+termina $nigual a 9, luego hacemos 9 +y agregamos eso de nuevo a la+[>+ cadena para obtener el 10 requerido, más los otros elementos individuales a lo largo del recorrido.

El elemento está envuelto en una subexpresión $()porque cuando $nes así $null, la expresión completa falla, por lo que la creación de la matriz falla, por lo que el indexador nunca se ejecuta, por lo que $nnunca se asigna.

La razón por la que este truco utilizado ternario es debido a una de sus peculiaridades: a diferencia de un operador ternario reales, las expresiones que definen los elementos no se evalúan si son o no son "seleccionados", y la primera para el caso.

Como necesito asignar y luego usar $nen iteraciones separadas, esto es útil. El valor del elemento de matriz ternario se evalúa con el $nvalor de la iteración anterior , luego el indexador vuelve a asignar$n para la iteración actual.

Entonces, los ForEach-Objectbucles terminan generando todo lo que se supone que debe hacer (un montón de errores que ignoramos), pero como una serie de nuevas cadenas.

De modo que todo está entre paréntesis y luego precedido por unario -joinpara dar la cadena de salida.

briantista
fuente
1
Gran explicación, eso solo justifica un voto a favor ya.
Mástil
1
Gracias @Mast, y debido a tu comentario, volví a revisar mi respuesta y me di cuenta de cómo podía ahorrar 4 bytes.
briantist
2

QuadR , 17 bytes

\d+.
¯1((⍎↓)⍴↑)⍵M

Pruébalo en línea!

Gracias a Adám por proporcionar la versión correcta del código.

Cómo funciona:

\d+.           Regex to match any sequence of digits followed by a character.
¯1((⍎↓)⍴↑)⍵M   Transformation line
¯1(      )⍵M   Arguments: -1 and the matching expression
   ( ↓)        'Drop' the last item (-1) from the match (⍵M), yielding a string which is a sequence of digits.
              Execute. In this case, it transforms a string into a number.
              'Take' the last item (-1) from the match (⍵M), yielding a character.
              Reshape it. That will take the character resulting from the 'Take' operation and repeat it n times,
               where n is the result from the 'Drop' and 'Execute' operations.
J. Sallé
fuente
Equivalente a la función APL'\d+.'⎕R{¯1((⍎↓)⍴↑)⍵.Match}
Adám
1

Java 8, 148 bytes

s->{for(s=s.format(s.replaceAll("(\\d+)","%1\\$0$1d"),0);!s.matches("\\D+");s=s.replaceAll("0(\\D)","$1$1"));return s.replaceAll("((.)+)\\2","$1");}

Malditas expresiones regulares de Java son tan inútiles a veces ... La última vez fue lafalta de usar el grupo de captura"$1"para algo, ahora esto ... Quiero reemplazar3cconccco000cconccc una sola línea, pero desafortunadamente Java no tiene forma de hacerlo sin un lazo. Ah bueno.

Explicación:

Pruébalo aquí.

s->{                          // Method with String as both parameter and return-type
  for(s=s.format(s.replaceAll("(\\d+)","%1\\$0$1d"),0);
                              //  Replace every numbers of that many zeroes
                              //  (i.e. "3>2+" -> "000>00+")
      !s.matches("\\D+");     //  Loop as long as the String contains zeroes
    s=s.replaceAll("0(\\D)",  //   Replace every 0 followed by a non-0 character,
                   "$1$1")    //   with two times this captured non-0 character
  );                          //  End of loop
  return s.replaceAll("((.)+)\\2","$1");
                              //  Reduce every repeated character amount by 1,
                              //  and return this as result
}                             // End of method
Kevin Cruijssen
fuente
1
Hola Kevin, me alegro de verte aquí, lidiando con otros rompecabezas que no sean retorcidos :)
Galen Ivanov
@GalenIvanov ¡Oh, hola! No tenía idea de que también estuvieras activo en PPCG.
Kevin Cruijssen
No estaba hasta hace poco :) Estoy aprendiendo J y decidí que esta es una buena oportunidad para poner a prueba mis habilidades.
Galen Ivanov el
1

Haskell , 84 bytes

f s@(x:r)|(n:m,x:r)<-span(`elem`['0'..'9'])s=(x<$[1..read$n:m])++f r|1<3=x:f r
f e=e

Pruébalo en línea!

Explicación:

span(`elem`['0'..'9'])sdivide la cadena dada sen un prefijo de dígitos y el resto. La coincidencia en el resultado del patrón (n:m,x:r)garantiza que el prefijo de dígitos no esté vacío y une el carácter después de los dígitos xy el resto a r. x<$[1..read$n:m]lee la cadena de dígitos n:mcomo número y la repite xmuchas veces. El resultado se concatena con el tratamiento recursivo de la cadena restante r.

Laikoni
fuente
1

R , 151 bytes

Superado por el usuario 2390246 ! Esto es básicamente un enfoque basura en comparación con ese, pero continuaré mejorando.

function(s,G=substr)for(i in el(strsplit(gsub("(\\d+.)","!\\1!",s),"!")))cat("if"(is.na(g<-as.double(G(i,1,(n=nchar(i))-1))),i,rep(G(i,n,n),g)),sep='')

Pruébalo en línea!

También genera un montón de advertencias.

function(s){
s <- gsub("(\\d+.)","!\\1!",s)               # surround groups with !
X <- el(strsplit(s,"!"))                   # split to groups
for( i in X ){                             # iterate over groups
 n <- nchar(i)                             # length of group
 r <- substr(i,1,n-1)                      # potential number (first n-1 chars)
 d <- substr(i,n,n)                        # last character
 if( is.na(as.double(r)) ){                # if it's not a number
   cat(i)                                  # print out the whole string
  } else {
   cat(rep(d,as.double(r)),sep="")         # repeat d r times, and print with no separator
  }
 }
}

A continuación, ver si usar un grepes más eficiente quesubstr

Giuseppe
fuente
Un enfoque diferente
user2390246
1

JavaScript (ES6), 46 bytes

a=>a.replace(/(\d+)(.)/g,(_,n,b)=>b.repeat(n))

Explicación bastante directa:

a=>a.replace(/(\d+)(.)/g,                      // Match globally the following: a number N followed by a character
                         (_,n,b)=>b.repeat(n)) // Replace each occurrence by the matched character repeated N times
XavCo7
fuente
1

Cálculo Lambda sin tipo , 452 bytes

(λp.λq.(λb.λg.(λi.(λp.λq.λb.p q b)(q(λq.λj.λl.j((λq.λj.qλq.λl.(λu.g i j(λp.u)(g j(λq.λg.q(b(p(λp.λq.p q))(p(λp.λq.p(p q)))q g))(λp.u)(λu.u qλq.λu.g j i q(b l(p(λp.λq.p(p(p(p q)))))q u))))λp.p(λp.λb.q p((λp.λq.l(λp.l)(λp.λq.p q)(λq.p j q)q)p b))λp.λp.p)l q))(λp.p)(λp.p(λp.λp.p)λp.λp.p)(λp.λq.p)))(b(p(λp.λp.p))(p(λp.λq.p(p q)))))(λp.λq.λb.p(q b))λp.λq.q(λp.λq.λb.p(λp.λb.b(p q))(λp.b)λp.p)p)λp.λq.λb.q(q(q(q(q(q(p q b))))))

La entrada y la salida comprenden listas plegadas a la derecha de códigos de caracteres codificados por la iglesia , por ejemplo, el código de caracteres de una nueva línea es 10, por lo que la codificación de la iglesia sería λf.λx.f(f(f(f(f(f(f(f(f(f x))))))))). La conversión de "ABCD" a una lista parece λf.λx.f 65 (f 66 (f 67 (f 68 x)))pero con los números codificados por la iglesia.

Aplicar una cadena codificada al programa y reducirla por completo debería proporcionarle una cadena de salida codificada con el RLE aplicado.

PixelToast
fuente
1
Hola y bienvenidos al sitio! Esto parece una solución interesante, pero esperamos que los idiomas tengan un intérprete válido, ¿tiene uno de Untyped Lambda Calculus?
Post Rock Garf Hunter
Además, ¿qué significa la qλqnotación? Nunca he visto eso antes.
Zacharý
1

C ++, 239 235 bytes

-4 bytes gracias a Zacharý

#include<regex>
using s=std::string;std::regex m("[0-9]*[<>+.,\\[\\]-]");s t(s r){s d,h;std::sregex_iterator i(r.begin(),r.end(),m),e;while(i!=e){h=(*i)[0];int g=std::strtol(h.data(),NULL,10);g+=!g;d+=s(g,h[h.size()-1]);++i;}return d;}
HatsuPointerKun
fuente
1
¿Se puede cambiar g=(g?g:1)a g+=!g? Si eso no funciona, ¿no puedes quitar los paréntesisg?g:1
Zacharý
0

Dart, 78 bytes (con expresiones regulares), 102 bytes (sin expresiones regulares)

Con Regex:

(i)=>i.splitMapJoin(new RegExp(r"(\d+)(.)"),onMatch:(m)=>m[2]*int.parse(m[1]))

Sin expresión regular:

(i,[n=0,d=0])=>i.codeUnits.map((c)=>i[d++]*((c-=48)>=0&&c<10?0*(n=n*10+c):n<1?1:(n=0*(c=n))+c)).join()

Ambos deben ser invocados como (<code here>)("input string") .

Regex one es bastante estándar, pero el regex-less es bastante especial.

Regex-less abusa de los parámetros opcionales para asignar variables locales en la función de "retorno único", de lo contrario, necesitaría hacer un bloque y tener la palabra clave return. Para cada unidad de código, si la unidad de código está entre 0 y 9, se acumula ny se devuelve una cadena vacía. De lo contrario, el carácter se multiplica por el valor de n(caso especial si n == 0, en ese caso siempre emitirá 1 carácter) y nse establece en 0. (n=0*(c=n))+cestablece el argumento del código char en el valor den , multiplica n/ ccon 0 , almacena 0 en n, luego agrega c. Esto restablece nuestro nsin estar en un contexto de declaración.

Dwayne Slater
fuente
0

Python3, 96 bytes

s,r=input(),""
while s:
 d=0
 while"/"<s[d]<":":d+=1
 r+=int(s[:d] or 1)*s[d];s=s[d+1:]
print(r)

Intenté otra implementación en Python, pero no supero /codegolf//a/146923/56846 :(

usuario285259
fuente