Expansão de suporte!

36

Seu desafio é expandir alguns colchetes na entrada de um programa, como mostrado:

  1. Encontre uma string s entre dois colchetes correspondentes [e ], com um único dígito n após o colchete de fechamento.
  2. Retire os suportes.
  3. Substitua s por si mesmo repetido n vezes. (Se n for 0, basta remover s .)
  4. Vá para a etapa 1 até que não haja mais colchetes correspondentes na entrada.

Regras e esclarecimentos adicionais:

  • Você receberá e dará saída por qualquer meio permitido.
  • Uma nova linha à direita na saída é permitida.
  • Você só precisa manipular ASCII imprimível na entrada.
  • Você pode assumir que todos os colchetes correspondem, ou seja, você nunca receberá a entrada []]]]ou [[[[].
  • Você pode supor que cada colchete de fechamento ]tenha um dígito depois dele.

Casos de teste:

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 , a resposta mais curta em cada idioma vence. Boa sorte!

MD XF
fonte
13
Você deve publicar um outro desafio para comprimir um back corda para baixo ao seu formato mais curto
Jo rei
Vale a pena declarar explicitamente que sua string snunca deve conter outros colchetes? Por exemplo, tentar resolver [Foo[Bar]3]2expandindo a cadeia Foo[Barde caracteres 3 vezes resultaria em um estado inválido.Foo[BarFoo[BarFoo[Bar]2
BradC
@ BradC, tudo depende de como você escolhe implementar a tarefa.
MD XF
Isso significa que existem duas respostas válidas para [a[b]2c[d]2e]2? Você obtém abbcddeabbcddeexpandindo be dprimeiro, mas ababcdbcdedbabcdbcdedeexpandindo a[be d]2eprimeiro.
BradC

Respostas:

13

Gema , 17 caracteres

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

Exemplo de execução:

bash-4.4$ gema '[#]?=@repeat{?;#}' <<< '[three[two[one]1]2]3'
threetwoonetwoonethreetwoonetwoonethreetwoonetwoone
homem a trabalhar
fonte
Uau, fale sobre como encontrar o idioma certo para o trabalho!
MD XF
Ou o trabalho certo para o idioma. Muitos desafios tiveram que ser ignorados porque o argumento recursivo não era suficientemente flexível.
Manatwork
Aceitando isso por enquanto, não vejo como está sendo vencido, mas será inaceitável no caso improvável de que isso aconteça.
MD XF
8

Retina , 24 23 22 bytes

+`\[([^][]*)](.)
$2*$1

Experimente online! Isso é praticamente um recurso interno da Retina 1. Editar: salvou 1 byte graças a @Kobi. 47 45 bytes na Retina 0.8.2:

].
]$&$*¶
{+`\[([^][]*)]¶
$1[$1]
\[([^][]*)]

Experimente online!

Neil
fonte
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)

Experimente online! Em vez de usar expressão regular como a maioria das outras respostas, isso implementa um analisador recursivo.

-5 bytes graças ao BMO !

Laikoni
fonte
4
Uma declaração de fixidez para (%)você economiza 1 byte e ['1'..d]economiza outros 4, veja isso .
ბიმო
3
@BMO Nice, eu não esperava que uma declaração de fixação fosse útil para o código de golfe. Eu acho que você deve adicionar isso à pergunta das dicas.
Laikoni
7

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

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

Experimente online!

Reduza-o com a ajuda de @Shaggy e @TonHospel.

Xcali
fonte
3
Eu não sei pérola, mas refazer parece lindo!
officialaimm
Eu acho que você deve conseguir salvar um byte não escapando do ].
Salsicha
1
Eu não sei Perl, mas isso parece funcionar para 30 + 1 bytes.
Salsicha
2
Estes 29 + 1 também funcionam: perl -pe 's/.([^[]*?)](.)/$1x$2/e&&redo'eperl -pe 's/.([^][]*)](.)/$1x$2/e&&redo'
Ton Hospel
5

Japonês v2 , 21 20 19 bytes

Guardado 2 bytes graças a @Shaggy

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

Teste online!

eé substituição recursiva, que faz uma substituição por vez até que não haja mais correspondências. Nesse caso, as correspondências da regex /\[([^[]*?)](\d)/gsão substituídas por <texto interno> repetidas vezes <dígito> até que não haja mais correspondências.

De acordo com o que planejei ( aqui ), esse regex deve ser pelo menos 3 2 bytes mais curto:

‹[“⁽[»₋”]“.›
ETHproductions
fonte
2
À medida que " pode-se supor que cada um colchete de fechamento ]tem um dígito depois que " você deve ser capaz de substituir (\dcom (..
Salsicha
Você também pode substituir \[por.
Salsicha
@ Shaggy Nice, obrigado!
ETHproductions
4

JavaScript, 71 67 66 bytes

Eu tinha uma solução de 54 bytes, mas ela foi atrapalhada pelo segundo caso de teste! :(

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

Casos de teste

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>

Shaggy
fonte
4

Python 3 , 110 93 92 bytes

import re
f=lambda s:f(re.sub(r'\[([^][]+)\](.)',lambda m:m[1]*int(m[2]),s))if'['in s else s

Experimente online!

-17 bytes graças a pizzapants184 -1 byte graças a Kevin Cruijssen

Gábor Fekete
fonte
1
-17 bytes no Python 3 com indexação re.match e verificação de substring usando in.
precisa saber é o seguinte
1
-1 byte, alterando (\d)para (.), porque sabemos que um colchete ]é sempre seguido por um dígito.
9117 Kevin Crijssen em 01/02
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))}

Experimente online!

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))
}

Solução antiga

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))}

Experimente online!

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))
}

Onde l é a lista de strings que iremos processar.

Obrigado Kevin Cruijssen por -1 byte

Passou de 212 para 199 removendo um parâmetro não utilizado, não prestou atenção.

Shikkou
fonte
4
Bem-vindo ao PPCG! Experimente o intérprete scala de tio em tio.run/#scala e veja se você pode enviar um link para a resposta, para que outros possam experimentá-lo online. :)
officialaimm
2
Obrigado! Eu editei a resposta para incluir o link. Espero que esteja tudo bem como o cabeçalho, o código e o rodapé são declarados para serem uma apresentação adequada.
Shikkou 31/01
1
Olá, seja bem-vindo ao PPCG! Ótima primeira resposta, +1 de mim. Eu acho que você pode economizar 1 byte mudando (\d)para (.), porque sabemos que um colchete ]é sempre seguido por um dígito.
9117 Kevin Crijssen em 01/02
3

Empilhados , 39 38 bytes

Economizou 1 byte graças a Shaggy, jogou golfe no regex!

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

Experimente online!

Simplesmente recursivamente substitui um regex '\[([^[\]]+)](.)'pela regra de repetição.

Conor O'Brien
fonte
Eu acho que você pode salvar um byte não escapando do último ].
Salsicha
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

Experimente Online

Agradecimentos ao HyperNeutrino e Mego por -47 bytes e user202729 por -4 bytes.

Manish Kundu
fonte
Torná-lo um one-liner para salvar um casal 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))

Edit: regex atualizado com a recomendação de Shaggy

Snippet:

max890
fonte
2
Bem-vindo ao PPCG! Você pode reduzir isso para 70 bytes , ajustando seu RegEx.
Salsicha
Sim, 72 bytes, obviamente, desculpe; Eu estava esquecendo de contar o f=!
Shaggy
2

QuadR com o argumento, 30 28 bytes

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

Experimente online!

\[[^[]+?]. substitua " caráter [não [material ]" por

¯2↓⍵M soltar os dois últimos caracteres do H atch ( " ]dígitos ')
1↓ deixar cair o primeiro caracter (' [")
 encerram a ser tratado como um todo
(... )⍴r eshape de comprimento:
⌽⍵M inverter a M atch
 escolher o primeiro (o dígito)
 avaliar
ε nlist ( aplainar)

 repita até que não ocorram mais alterações


A função Dyalog APL equivalente é de 47 bytes:

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

Experimente online!

Adão
fonte
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 graças a @JonathanFrech (o código contém dois caracteres ASCII não imprimíveis agora, que podem ser vistos no link TIO abaixo).

Suspiro ... Java com regex é tão limitado .. Vou apenas me citar de outra resposta aqui:

Substituir WWWWpor 222Wé fácil em Java, mas 4Wnão .. Se ao menos Java tivesse uma maneira de usar o grupo de captura de expressão regular para obter alguma coisa ... Adquirir o comprimento "$1".length(), substituir a própria correspondência por "$1".replace(...), converter a correspondência em um número inteiro com new Integer("$1")ou usar algo semelhante a Retina ( s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))ou JavaScript (ou seja s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))) seria minha coisa número 1 que eu gostaria de ver em Java no futuro para beneficiar o codegolfing ..>.> Acho que é a décima vez que odeio que Java não possa fazer qualquer coisa com a correspondência do grupo de captura.
Cite aqui.

Explicação:

Experimente online.

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
Kevin Cruijssen
fonte
1
Eu acho que você pode usar um caractere verdadeiramente ASCII embora não imprimível para salvar dois bytes . (Sua solução realmente leva 241 bytes, 239 caracteres.)
Jonathan Frech
@JonathanFrech Thanks! Estava procurando um caractere de 1 byte fora do intervalo ASCII imprimível. Não pensou em usar um impublicável ..
Kevin Cruijssen
2

C, 407 368 bytes

Obrigado a Jonathan Frech por salvar bytes.

golfed (arquivo bracket.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;}

ungolfed com o 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 com o gcc 5.4.1, gcc bracket.c

Tsathoggua
fonte
1
368 bytes .
Jonathan Frech 31/01
387 com a inclusão necessária (para realloc). Farei uma atualização limpa (com a versão não destruída) mais tarde. Obrigado
Tsathoggua
Se você usa o GCC, acho que o compilador tentará adivinhar a definição de ambos malloce realloc, inclusive stdlib.hpor conta própria.
11136 Jonathan Frech
Eu não sabia disso. Bom recurso para o código de golfe. Obrigado.
Tsathoggua 02/02
2

Vermelho , 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]

Ungolfed:

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
]

Comecei a aprender o dialeto do Parse de Red apenas ontem, então tenho certeza de que meu código pode ser melhorado ainda mais. O Parse é incomparavelmente mais detalhado que o regex, mas é muito claro, flexível e legível e pode ser misturado livremente com o restante do idioma vermelho.

Experimente online!

Galen Ivanov
fonte
1

Gelatina , 30 bytes

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

Experimente online!


Explicação.


œṡ”]µḢ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.
user202729
fonte
1

C, 381 bytes

Versão 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;}

Versão 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;
}
raphchar
fonte
3
Bem-vindo ao PPCG!
Salsicha
1
Bem vindo ao site! Observe que os envios em C precisam ser programas ou funções completos, não apenas trechos.
MD XF
1

Python, 80 bytes

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

Experimente online!

s("[Foo[Bar]3]2") Converte [Foo[Bar]3]2 para ''+('Foo'+('Bar')*3+'')*2+''e avalia.

Falha na entrada com aspas entre colchetes (por exemplo [']3)

Ugoren
fonte
A resposta foi negativa, pois a pergunta exige o manuseio de qualquer ASCII imprimível na entrada, e essa resposta não. Notifique-me se você o corrigir, e eu ficarei feliz em retirar meu voto.
caird coinheringaahing