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!



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

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


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 !


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.


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:

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

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>



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.


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.


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.


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:


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!


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

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



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!


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.

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

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)


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.