Expansión de soporte!


36

Su desafío es expandir algunos corchetes en la entrada de un programa como se muestra:

  1. Encuentre una cadena s entre dos corchetes coincidentes [y ], con un solo dígito n después del corchete de cierre.
  2. Retirar los soportes.
  3. Reemplace s con sí mismo repetido n veces. (Si n es 0, simplemente elimine s .)
  4. Vaya al paso 1 hasta que no haya más corchetes coincidentes en la entrada.

Reglas y aclaraciones adicionales:

  • Tomará entrada y dará salida a través de cualquier medio permitido.
  • Se permite una nueva línea final en la salida.
  • Solo necesita manejar ASCII imprimible en la entrada.
  • Puede suponer que todos los corchetes coinciden, es decir, nunca recibirá la entrada []]]]o [[[[].
  • Puede suponer que cada paréntesis de cierre ]tiene un dígito después.

Casos de prueba:

Input                -> Output
[Foo[Bar]3]2         -> FooBarBarBarFooBarBarBar
[one]1[two]2[three]3 -> onetwotwothreethreethree
[three[two[one]1]2]3 -> threetwoonetwoonethreetwoonetwoonethreetwoonetwoone
[!@#[$%^[&*(]2]2]2   -> !@#$%^&*(&*($%^&*(&*(!@#$%^&*(&*($%^&*(&*(
[[foo bar baz]1]1    -> foo bar baz
[only once]12        -> only once2
[only twice]23456789 -> only twiceonly twice3456789
[remove me!]0        -> 
before [in ]2after   -> before in in after

Como se trata de , gana la respuesta más corta en cada idioma. ¡Buena suerte!



13
Debería publicar otro desafío para comprimir una cadena de nuevo a su formato más corto
Jo King,

¿Vale la pena declarar explícitamente que su cadena snunca debe contener otros corchetes? Por ejemplo, intentar resolver [Foo[Bar]3]2expandiendo la cadena Foo[Bar3 veces resultaría en un estado inválidoFoo[BarFoo[BarFoo[Bar]2
BradC

@BradC, todo depende de cómo elija implementar la tarea.
MD XF

¿Eso significa que hay dos respuestas válidas para [a[b]2c[d]2e]2? Se obtiene abbcddeabbcddeexpandiéndose by dprimero, pero ababcdbcdedbabcdbcdedeexpandiéndose a[by d]2eprimero.
BradC

Respuestas:


13

Gema , 17 personajes

[#]?=@repeat{?;#}

Ejecución de muestra:

bash-4.4$ gema '[#]?=@repeat{?;#}' <<< '[three[two[one]1]2]3'
threetwoonetwoonethreetwoonetwoonethreetwoonetwoone

¡Guau, habla sobre encontrar el idioma adecuado para el trabajo!
MD XF

O el trabajo adecuado para el idioma. Muchos desafíos tuvieron que saltarse porque el argumento recursivo no era lo suficientemente flexible.
manatwork

Al aceptar esto por ahora porque no veo de ninguna manera que sea superado, pero no será aceptado en el improbable caso de que lo haga.
MD XF


7

Haskell , 101 96 bytes

fst.(""%)
infix 4%
s%']':d:r=(['1'..d]>>s,r)
s%'[':r|(t,q)<-""%r=s++t%q
s%x:r=s++[x]%r
s%e=(s,e)

Pruébalo en línea! En lugar de usar expresiones regulares como la mayoría de las otras respuestas, esto implementa un analizador recursivo.

-5 bytes gracias a BMO !


44
Una declaración de fijación para le (%)ahorra 1 byte y le ['1'..d]ahorra otros 4, vea esto .
ბიმო

3
@BMO Niza, no esperaba que una declaración de fijación alguna vez fuera útil para el golf de código. Creo que deberías agregar eso a la pregunta de consejos.
Laikoni

7

Perl 5 , 34 33 29 + 1 ( -p) = 30 bytes

s/.([^[]*?)](.)/$1x$2/e&&redo

Pruébalo en línea!

Córtalo con ayuda de @Shaggy y @TonHospel.


3
No sé perla pero rehacer parece magnífico!
officialaimm

Creo que deberías poder guardar un byte al no escapar del ].
Shaggy

1
No sé Perl, pero esto parece funcionar para 30 + 1 bytes.
Shaggy

2
Estos 29 + 1 también funcionan: perl -pe 's/.([^[]*?)](.)/$1x$2/e&&redo'yperl -pe 's/.([^][]*)](.)/$1x$2/e&&redo'
Ton Hospel

5

Japt v2 , 21 20 19 bytes

Guardado 2 bytes gracias a @Shaggy

e/.([^[]*?)](./@YpZ

¡Pruébelo en línea!

ees un reemplazo recursivo, que hace un reemplazo a la vez hasta que no haya más coincidencias. En este caso, coincidencias de la expresión regular/\[([^[]*?)](\d)/g se reemplazan con <texto interno> repetido <digit> veces hasta que no haya más coincidencias.

Según lo que he planeado ( aquí ), esta expresión regular debería ser al menos 3 2 bytes más corta:

‹[“⁽[»₋”]“.›

2
Como " podemos suponer que cada paréntesis de cierre ]tiene un dígito después ", debería poder reemplazarlo (\dpor (..
Shaggy

También puede reemplazar \[con.
Shaggy

@ Shaggy Nice, gracias!
ETHproductions

4

JavaScript, 71 67 66 bytes

¡ Tenía una solución de 54 bytes pero el segundo caso de prueba lo arruinó! :(

f=s=>s!=(x=s.replace(/.([^[]*?)](.)/,(_,y,z)=>y.repeat(z)))?f(x):x

Casos de prueba

f=s=>s!=(x=s.replace(/.([^[]*?)](.)/,(_,y,z)=>y.repeat(z)))?f(x):x
o.innerText=`[Foo[Bar]3]2
[one]1[two]2[three]3
[three[two[one]1]2]3
[!@#[$%^[&*(]2]2]2
[[foo bar baz]1]1
[only once]12
[only twice]23456789
[remove me!]0
before [in ]2after`.split`\n`.map(x=>x.padEnd(22)+`:  `+f(x)).join`\n`
<pre id=o></pre>



4

Scala , 173 bytes

l.foreach{x=>def r(c:String):String={val t="""\[([^\[\]]*)\](.)""".r.unanchored;c match{case t(g,h)=>r(c.replaceAllLiterally(s"[$g]$h",g*h.toInt));case _=>c}};println(r(x))}

Pruébalo en línea!

Expandido:

l.foreach { x =>
  def remove(current: String): String = {
    val test ="""\[([^\[\]]*)\](.)""".r.unanchored
    current match {
      case test(g, h) => remove(current.replaceAllLiterally(s"[$g]$h", g * h.toInt))
      case _ => current
    }
  }

  println(remove(x))
}

Vieja solución

Scala , 219 215 213 212 199 bytes

l.foreach{x=>def r(c:String):String={"""\[([^\[\]]*)\](.)""".r.findFirstMatchIn(c).map{x=>val g=x.group(1);val h=x.group(2).toInt;r(c.replaceAllLiterally(s"[$g]$h",g*h))}.getOrElse(c)};println(r(x))}

Pruébalo en línea!

Expandido:

l.foreach { x =>
  def remove(current: String): String = {
    """\[([^\[\]]*)\](.)""".r.findFirstMatchIn(current).map { x =>
      val g = x.group(1)
      val h = x.group(2).toInt
      remove(current.replaceAllLiterally(s"[$g]$h", g * h))
    }.getOrElse(current)
  }
  println(remove(x))
}

Donde l es la lista de cadenas que procesaremos.

Gracias Kevin Cruijssen por -1 byte

Pasó de 212 a 199 eliminando un parámetro no utilizado, no prestó atención.


44
Bienvenido a PPCG! Pruebe el intérprete scala de tio en tio.run/#scala y vea si puede enviar un enlace para la respuesta, para que otros puedan probarlo en línea. :)
officialaimm

2
¡Gracias! Edité la respuesta para incluir el enlace. Esperemos que esté bien cómo se declara el encabezado, el código y el pie de página para que sea un envío adecuado.
Shikkou el

1
Hola, bienvenido a PPCG! Gran primera respuesta, +1 de mi parte. Creo que puede guardar 1 byte cambiando (\d)a (.), porque sabemos que un paréntesis de bloque ]siempre va seguido de un dígito.
Kevin Cruijssen

3

Apilado , 39 38 bytes

¡Salvamos 1 byte gracias a Shaggy, jugamos al golf!

['\[([^[\]]+)](.)'{.y x:x#~y*}recrepl]

Pruébalo en línea!

Simplemente reemplaza recursivamente una expresión regular '\[([^[\]]+)](.)'con la regla de repetición.


Creo que puede guardar un byte al no escapar del último ].
Shaggy

3

Python 3, 155 148 101 97 bytes

def f(x):
 a=x.rfind('[')
 if~a:b=x.find(']',a);x=f(x[:a]+x[a+1:b]*int(x[b+1])+x[b+2:])
 return x

Pruébalo en línea

Gracias a HyperNeutrino y Mego por -47 bytes y user202729 por -4 bytes.


Haga una línea para guardar un par de bytes:def f(x):a=x.rfind('[');b=x.find(']',a);return f(x[:a]+x[a+1:b]*int(x[b+1])+x[b+2:])if~a else x
Mathmandan

3

JavaScript - 77 75 72 bytes

f=a=>a.replace(/(.*)\[([^[]*?)](.)(.*)/,(a,b,c,d,e)=>f(b+c.repeat(d)+e))

Editar: expresiones regulares actualizadas con la recomendación de Shaggy

Retazo:


2
Bienvenido a PPCG! Puede reducir esto a 70 bytes ajustando su RegEx.
Shaggy

Sí, 72 bytes, obviamente, lo siento; ¡Me estaba olvidando de contar f=!
Shaggy

2

QuadR con el argumento, 30 28 bytes

\[[^[]+?].
∊(⍎⊃⌽⍵M)⍴⊂1↓¯2↓⍵M

Pruébalo en línea!

\[[^[]+?]. reemplazar " [no [material] " con

¯2↓⍵M soltar los dos últimos caracteres del M atch ( " ]dígito ')
1↓ deje caer el primer carácter (' [")
 encierran a ser tratado como un todo
(... )⍴r eshape de longitud:
⌽⍵M revertir el M atch
 escoger el primero (el dígito)
 evaluar
ε nlist ( aplanar)

 repita hasta que no ocurran más cambios


La función APL Dyalog equivalente es de 47 bytes:

'\[[^[]+?].'R{∊(⍎⊃⌽⍵.Match)⍴⊂1↓¯2↓⍵.Match}⍣≡

Pruébalo en línea!


2

Java 8, 250 249 241 239 bytes

s->{for(;s.contains("[");)for(int i=0,j,k;i<s.length();)if(s.charAt(i++)==93){String t="",r=t;for(j=k=s.charAt(i)-48;j-->0;)t+=s.replaceAll(r="(.*)\\[([^\\]]+)\\]"+k+"(.*)","$2");s=k<1?t:s.replaceFirst(r,"$1$3").replace("",t);}return s;}

-2 bytes gracias a @JonathanFrech (el código contiene dos caracteres ASCII no imprimibles ahora, que se pueden ver en el enlace TIO a continuación).

Suspiro ... Java con expresiones regulares es tan limitado ... Citaré otra respuesta aquí:

Reemplazar WWWWcon 222Wes fácil en Java, pero 4Wno con ... Si solo Java tuviera una forma de usar el grupo de captura de expresiones regulares para algo ... Obtener la longitud con "$1".length(), reemplazar la coincidencia en sí misma "$1".replace(...), convertir la coincidencia en un entero con new Integer("$1"), o usar algo similar a Retina (es decir, s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))o JavaScript (es decir s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))) sería mi cosa número 1 que me gustaría ver en Java en el futuro para beneficiar al codegolfing ...>.> Creo que esta es la décima vez que odio que Java no pueda hacer cualquier cosa con la coincidencia del grupo de captura
.

Explicación:

Pruébalo en línea.

s->{                           // Method with String as both parameter and return-type
  for(;s.contains("[");)       //  Loop as long as the String contains a block-bracket
    for(int i=0,j,k;i<s.length();)
                               //   Inner loop over the characters of the String
      if(s.charAt(i++)==93){   //    If the current character is a closing block-bracket:
        String t="",r=t;       //     Create two temp-Strings, starting empty
        for(j=k=s.charAt(i)-48;//     Take the digit after the closing bracket
            j-->0;)            //     Loop that many times:
          t+=s.replaceAll(r="(.*)\\[([^\\]]+)\\]"+k+"(.*)","$2");
                               //      Append `t` with the word inside the block brackets
        s=k<1?                 //     If the digit was 0:
           t                   //      Replace the input with an empty String as well
          :                    //     Else:
           s.replaceFirst(r,"$1$3").replace("",t);}
                               //      Replace the word between brackets by `t`,
                               //      and remove the digit
  return s;}                   //  Return the modified input-String as result

1
Creo que puede usar un carácter verdaderamente ASCII aunque no imprimible para guardar dos bytes . (Su solución realmente toma 241 bytes, 239 caracteres.)
Jonathan Frech

@ JonathanFrech Gracias! Estaba buscando un carácter de 1 byte fuera del rango ASCII imprimible. No pensé en usar un no imprimible ..
Kevin Cruijssen


2

C, 407 368 bytes

Gracias a Jonathan Frech por guardar bytes.

golfed (archivo soporte.c):

i,j,k,l,n;char*f(a,m)char*a;{for(i=0;a[i];++i){a[i]==91&&(j=i+1);if(a[i]==93){k=a[i+1]-48;if(!k){for(l=i+2;l<m;)a[++l-i+j-4]=a[l];a=realloc(a,m-3);return f(a,m-3);}for(l=j;l<i;)a[~-l++]=a[l];for(l=i+2;l<m;)a[++l-4]=a[l];m-=3;n=m+~-k*(i---j--);a=realloc(a,n);for(l=i;l<m;)a[l+++~-k*(i-j)]=a[l];for(m=0;m<k;++m)for(l=j;l<i;)a[l+++m*(i-j)]=a[l];return f(a,n);}}return a;}

sin golfista con el programa:

#include <stdlib.h>
#include <stdio.h>

// '[' = 133
// ']' = 135
// '0' = 48

i, j, k, l, n;

char* f(a,m) char*a;
{
  for (i=0; a[i]; ++i) {
    a[i]==91&&(j=i+1);

    if (a[i]==93) {
      k=a[i+1]-48;

      if (!k) {
        for (l=i+2; l<m; )
          a[++l-i+j-4] = a[l];

        a = realloc(a,m-3);
        return f(a,m-3);
      }
      for (l=j;l<i;)
        a[~-l++] = a[l];
      for (l=i+2; l<m; )
        a[++l-4] = a[l];
      m -= 3;
      n = m+~-k*(i---j--);
      a = realloc(a,n);

      for (l=i; l<m; )
        a[l+++~-k*(i-j)] = a[l];
      for (m=0; m<k; ++m)
        for (l=j; l<i;)
          a[l+++m*(i-j)] = a[l];

      return f(a,n);
    }
  }
  return a;
}

int main()
{
  char c[]="[Foo[Bar]3]2";
  char *b;

  char cc[]="[remove me!]0";
  char *bb;

  char ccc[]="[only once]12";
  char *bbb;

  b=malloc(13);
  bb=malloc(14);
  bbb=malloc(14);

  for (i=0; i<13; ++i)
    b[i] = c[i];

  for (i=0; i<14; ++i)
    bb[i] = cc[i];

  for (i=0; i<14; ++i)
    bbb[i]=ccc[i];

  printf("%s\n", f(b, 13));
  printf("%s\n", f(bb, 14));
  printf("%s\n", f(bbb, 14));

  return 0;
}

Compilado con gcc 5.4.1, gcc bracket.c



387 con la inclusión necesaria (para realloc). Haré una actualización limpia (con la versión sin golf) más adelante. Gracias
Tsathoggua

Si usa GCC, creo que el compilador intentará adivinar la definición de ambos mallocy realloc, incluso stdlib.hpor sí mismo.
Jonathan Frech

No lo sabia. Buena característica para golf de código. Gracias.
Tsathoggua

2

Rojo , 147 bytes

f: func[t][a: charset[not"[]"]while[parse t[any a some[remove["["copy h any a"]"copy d a](insert/dup v: copy""h to-integer d)insert v | skip]]][]t]

Sin golf:

f: func [t][
    a: charset [not "[]"]                          ; all chars except [ and ]
    while [ parse t [                              ; repeat while parse is returning true
        any a                                      ; 0 or more chars other than [ and ]
        some [                                     ; one or more block:
            remove ["[" copy h any a "]" copy d a] ; remove the entire block, store the
                                                   ; substring between the [] in h,
                                                   ; the digit into d
            (insert/dup v: copy "" h to-integer d) ; makes d copies of h 
            insert v                               ; and inserts them in place 
            | skip ]                               ; skip if no match
        ]                                       
    ][]                                            ; empty block for 'while'
    t                                              ; return the modified string
]

Ayer empecé a aprender el dialecto de Red's Parse, así que estoy seguro de que mi código se puede mejorar aún más. Parse es incomparablemente más detallado que regex, pero es muy claro, flexible y legible y se puede mezclar libremente con el resto del lenguaje rojo.

Pruébalo en línea!


1

Jalea , 30 bytes

œṡ”]µḢUœṡ”[ẋ€1¦Ṫ©Ḣ$FṚ;®
Çċ”]$¡

Pruébalo en línea!


Explicación.


œṡ”]µḢUœṡ”[ẋ€1¦Ṫ©Ḣ$FṚ;®    Helper link 1, expand once.
                           Assume input = "ab[cd]2ef".

œṡ      Split at first occurence of
  ”]      character "]".
    µ   Start new monadic chain. Value = "ab[cd","2ef".

Ḣ       ead. "ab[cd"
 U      Upend. "dc[ba"
  œṡ”[  Split at first occurence of "[". | "dc","ba".

ẋ€        Repeat ...
  1¦        the element at index 1...
          by ...
    Ṫ Ḣ$    the ead of the ail of ...
          the input list ("ab[cd","2ef") (that is, 2)

          The command  also pop the head '2'. The remaining
            part of the tail is "ef".
     ©    Meanwhile, store the tail ("ef") to the register.

          Current value: "dcdc","ba"
FṚ        Flatten and everse. | "abcdcd"
  ;®      Concatenate with the value of the register. "abcdcdef"

Çċ”]$¡    Main link.

 ċ”]$     Count number of "]" in the input.
     ¡    Repeatedly apply...
Ç           the last link...
            that many times.

1

C, 381 bytes

Versión compacta:

while(1){int t=strlen(i);int a,c=-1;char*w;char*s;char*f;while(c++<t){if(i[c]==']'){int k=c-a;w=calloc((k--),1);memcpy(w,&i[a+1],k);s=calloc((t-c-1),1);memcpy(s,&i[c+2],t-c-2);i[a]=0;int r=i[c+1]-48;if(r==0){f=calloc(t,1);sprintf(f,"%s%s",i,s);}else{f=calloc((t+k),1);sprintf(f,"%s%s[%s]%d%s",i,w,w,r-1,s);}free(i);i=f;break;}else if(i[c]=='[')a=c;}free(w);free(s);if(c>=t)break;}

Versión completa:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

void proceed(char* input)
{
  while(1)
  {
    int t=strlen(input);
    int start,cursor=-1;
    char* word;
    char* suffix;
    char* final;
    while(cursor++<t)
    {
      if(input[cursor]==']')
      {
        int wordlength = cursor-start;
        word=calloc((wordlength--),sizeof(char));
        memcpy(word, &input[start+1], wordlength );
        suffix=calloc((t-cursor-1),sizeof(char));
        memcpy( suffix, &input[cursor+2], t-cursor-2 );
        input[start]='\0';
        int rep=input[cursor+1]-'0';
        if(rep==0)
        {
          final=calloc(t,sizeof(char));
          sprintf(final,"%s%s",input,suffix);
        }
        else
        {
          final=calloc((t+wordlength+5),sizeof(char));
          sprintf(final,"%s%s[%s]%d%s",input,word,word,rep-1,suffix);
        }
        free(input);
        input=final;
        break;
      }
      else if(input[cursor]=='[')
        start=cursor;
    }
    free(word);
    free(suffix);

    if(cursor>=t)break;
  }
}

int main()
{
  char* input=calloc(256,sizeof(char));
  sprintf(input,"a[[toto]2b]2[ana]3");
  printf("in : %s\n",input);
  proceed(input);
  printf("out: %s\n",input);
  return 0;
}

3
Bienvenido a PPCG!
Shaggy

1
Bienvenido al sitio! Tenga en cuenta que las presentaciones en C deben ser programas o funciones completos, no solo fragmentos.
MD XF

1

Python, 80 bytes

import re
b=re.sub
s=lambda x:eval(b(r"\](.)",r"')*\1+'",b(r"\[","'+('","%r"%x)))

Pruébalo en línea!

s("[Foo[Bar]3]2")Convierte [Foo[Bar]3]2a ''+('Foo'+('Bar')*3+'')*2+''y se evaluará.

No se puede ingresar con comillas entre paréntesis (p [']3. Ej. )


Desestimé esta respuesta ya que la pregunta requiere el manejo de cualquier ASCII imprimible en la entrada, y esta respuesta no. Notifíqueme si lo arregla, y felizmente retractaré mi voto.
caird coinheringaahing
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.