Rozszerzenie wspornika!

36

Twoim wyzwaniem jest rozszerzenie niektórych nawiasów w danych wejściowych programu, jak pokazano:

  1. Znajdź ciąg s między dwoma pasującymi nawiasami [i ]za pomocą jednej cyfry n po nawiasie zamykającym.
  2. Usuń wsporniki.
  3. Zamień s na siebie powtórzone n razy. (Jeśli n wynosi 0, po prostu usuń s .)
  4. Przejdź do kroku 1, aż na wejściu nie będzie pasujących nawiasów.

Dodatkowe zasady i wyjaśnienia:

  • Przyjmiesz dane wejściowe i wydasz dane wyjściowe dowolnymi dozwolonymi środkami.
  • Końcowy znak nowej linii w danych wyjściowych jest dozwolony.
  • Musisz tylko obsługiwać ASCII do wydruku na wejściu.
  • Możesz założyć, że wszystkie nawiasy pasują do siebie, tzn. Nigdy nie otrzymasz danych wejściowych []]]]lub [[[[].
  • Możesz założyć, że po każdym nawiasie zamykającym ]jest cyfra.

Przypadki testowe:

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

Ponieważ jest to , wygrywa najkrótsza odpowiedź w każdym języku. Powodzenia!

MD XF
źródło
13
Powinieneś opublikować kolejne wyzwanie spakowania łańcucha z powrotem do jego najkrótszego formatu
Jo King
Czy warto jednoznacznie stwierdzić, że ciąg snie powinien nigdy zawierać innych nawiasów? Na przykład próba rozwiązania [Foo[Bar]3]2przez Foo[Bar3-krotne rozwinięcie łańcucha spowoduje niepoprawny stanFoo[BarFoo[BarFoo[Bar]2
BradC
@BradC, że wszystko zależy od tego, jak zdecydujesz się na wdrożenie zadania.
MD XF
Czy to oznacza, że ​​istnieją dwie prawidłowe odpowiedzi [a[b]2c[d]2e]2? Dostajesz abbcddeabbcdde, rozwijając się bi dpierwszy, ale ababcdbcdedbabcdbcdederozwijając się a[bi d]2epierwszy.
BradC

Odpowiedzi:

13

Gema , 17 znaków

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

Przykładowy przebieg:

bash-4.4$ gema '[#]?=@repeat{?;#}' <<< '[three[two[one]1]2]3'
threetwoonetwoonethreetwoonetwoonethreetwoonetwoone
człowiek w pracy
źródło
Wow, porozmawiaj o znalezieniu odpowiedniego języka do pracy!
MD XF
Lub właściwa praca dla języka. Wiele wyzwań musiało zostać pominiętych, ponieważ argument rekurencyjny nie był wystarczająco elastyczny.
manatwork
Akceptując to na razie, ponieważ nie widzę żadnego sposobu, aby go pokonać, ale będzie to nieakceptowane w mało prawdopodobnym przypadku.
MD XF
8

Retina , 24 23 22 bajtów

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

Wypróbuj online! Jest to praktycznie wbudowane w Retina 1. Edycja: Zapisano 1 bajt dzięki @Kobi. 47 45 bajtów w Retina 0.8.2:

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

Wypróbuj online!

Neil
źródło
7

Haskell , 101 96 bajtów

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)

Wypróbuj online! Zamiast używać wyrażeń regularnych, jak większość innych odpowiedzi, implementuje to parser rekurencyjny.

-5 bajtów dzięki BMO !

Laikoni
źródło
4
Deklaracja poprawności dla (%)oszczędza 1 bajt i ['1'..d]oszczędza kolejne 4, zobacz to .
ბიმო
3
@BMO Fajnie, nie spodziewałem się, że deklaracja poprawności będzie przydatna podczas gry w golfa. Myślę, że powinieneś dodać to do pytania ze wskazówkami.
Laikoni
7

Perl 5 , 34 33 29 + 1 ( -p) = 30 bajtów

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

Wypróbuj online!

Ogranicz to przy pomocy @Shaggy i @TonHospel.

Xcali
źródło
3
Nie znam perły, ale ponowne wykonanie wydaje się wspaniałe!
officialaimm
Myślę, że powinieneś być w stanie uratować bajt, nie uciekając przed ].
Kudłaty
1
Nie wiem, Perl, ale to wydaje się do pracy dla 30 + 1 bajtów.
Kudłaty
2
Te 29 + 1 działa również: perl -pe 's/.([^[]*?)](.)/$1x$2/e&&redo'iperl -pe 's/.([^][]*)](.)/$1x$2/e&&redo'
Ton Hospel
5

Japt v2 , 21 20 19 bajtów

Zaoszczędzono 2 bajty dzięki @Shaggy

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

Przetestuj online!

ejest zastępowaniem rekurencyjnym, co powoduje jedną zamianę na raz, dopóki nie będzie więcej dopasowań. W takim przypadku dopasowania wyrażenia regularnego /\[([^[]*?)](\d)/gsą zamieniane na <tekst wewnętrzny> powtarzane <cyfra> razy, aż nie będzie już żadnych dopasowań.

Zgodnie z tym, co zaplanowałem ( tutaj ), wyrażenie regularne powinno ostatecznie być co najmniej 3 2 bajty krótsze:

‹[“⁽[»₋”]“.›
ETHprodukcje
źródło
2
Jak my „ może przyjąć, że każda klamra zamykająca ]ma cyfrę po ” powinien być w stanie wymienić (\dz (..
Kudłaty
Można również wymienić \[z.
Kudłaty
@Shaggy Nice, dzięki!
ETHproductions
4

JavaScript, 71 67 66 bajtów

I miał rozwiązanie 54 bajtów, ale został wkręcony przez drugi przypadek testowy! :(

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

Przypadki testowe

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>

Kudłaty
źródło
4

Python 3 , 110 93 92 bajty

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

Wypróbuj online!

-17 bajtów dzięki pizzapantom 184 bajty -1 dzięki Kevinowi Cruijssenowi

Gábor Fekete
źródło
1
-17 bajtów w Pythonie 3 z indeksowaniem re.match i sprawdzaniem podciągów za pomocą in.
pizzapants184
1
-1 bajt, zmieniając (\d)na (.), ponieważ wiemy, że po nawiasie blokowym ]zawsze występuje cyfra.
Kevin Cruijssen
4

Scala , 173 bajtów

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

Wypróbuj online!

Rozszerzony:

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

Stare rozwiązanie

Scala , 219 215 213 212 199 bajtów

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

Wypróbuj online!

Rozszerzony:

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

Gdzie l jest listą łańcuchów, które będziemy przetwarzać.

Dzięki Kevin Cruijssen za -1 bajt

Przeszedł z 212 do 199, usuwając nieużywany parametr, nie zwracał uwagi.

Shikkou
źródło
4
Witamy w PPCG! Wypróbuj interpreter scala tio na tio.run/#scala i sprawdź, czy możesz przesłać link do odpowiedzi, aby inni mogli go wypróbować online. :)
officialaimm
2
Dziękuję Ci! Zredagowałem odpowiedź, aby dołączyć link. Mamy nadzieję, że ok, w jaki sposób nagłówek, kod i stopka są zadeklarowane, są poprawne.
Shikkou
1
Cześć, witamy w PPCG! Świetna pierwsza odpowiedź, +1 ode mnie. Myślę, że możesz zaoszczędzić 1 bajt, zmieniając (\d)na (.), ponieważ wiemy, że po nawiasie blokowym ]zawsze występuje cyfra.
Kevin Cruijssen
3

Skumulowane , 39 38 bajtów

Zaoszczędził 1 bajt dzięki Kudłatemu, zagrał w regex!

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

Wypróbuj online!

Po prostu rekurencyjnie zastępuje wyrażenie regularne '\[([^[\]]+)](.)'regułą powtarzania.

Conor O'Brien
źródło
Myślę, że możesz uratować bajt, nie uciekając przed ostatnim ].
Kudłaty
3

Python 3, 155 148 101 97 bajtów

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

Wypróbuj online

Dzięki HyperNeutrino i Mego za -47 bajtów i user202729 za -4 bajty.

Manish Kundu
źródło
Zrób z jednego 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
linijki,
3

JavaScript - 77 75 72 bajtów

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

Edycja: zaktualizowano wyrażenie regularne z zaleceniem Kudłaty

Skrawek:

max890
źródło
2
Witamy w PPCG! Możesz zmniejszyć to do 70 bajtów , modyfikując swój RegEx.
Kudłaty
Tak, 72 bajty, oczywiście, przepraszam; Zapomniałem policzyć f=!
Kudłaty
2

QuadR z argumentem, 30 28 bajtów

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

Wypróbuj online!

\[[^[]+?]. zamień „ [non- [stuff ]character” na

¯2↓⍵M upuść dwa ostatnie znaki z M Atch ( „ ]cyfrowy«)
1↓ spadnie pierwszy znak (» [”),
 załączyć należy traktować jako całość
(... )⍴r eshape do długości:
⌽⍵M odwrotnej M Atch
 wybrać pierwszą (cyfrę)
 ocenia
ε nlist ( spłaszczyć)

 powtarzaj, aż nie będą już więcej zmian


Równoważna funkcja Dyalog APL ma 47 bajtów:

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

Wypróbuj online!

Adám
źródło
2

Java 8, 250 249 241 239 bajtów

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 bajty dzięki @JonathanFrech (kod zawiera teraz dwa niedrukowalne znaki ASCII, które można zobaczyć w łączu TIO poniżej).

Westchnienie ... Java z regexem jest tak cholernie ograniczona .. Po prostu zacytuję się z innej odpowiedzi tutaj:

Wymiana WWWWze 222Wjest łatwy w Javie, ale 4Wnie .. Jeśli tylko Java miał drogę do korzystania z regex capture-grupę czegoś .. Uzyskanie długość z "$1".length()zastępując sam mecz z "$1".replace(...), przekształcając meczu na liczbę całkowitą z new Integer("$1"), lub przy użyciu coś podobnego do Retina (tj. s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))JavaScript (tj. s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))) byłoby moją pierwszą rzeczą, którą chciałbym zobaczyć w Javie w przyszłości, aby skorzystać z kodowania golfa ..>.> Myślę, że to już 10 + raz, którego nienawidzę Java nie może zrobić cokolwiek z dopasowaniem grupy przechwytywania ..
Cytat stąd.

Wyjaśnienie:

Wypróbuj 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
źródło
1
Myślę, że możesz użyć prawdziwie ASCII, choć niedrukowalnego znaku, aby zaoszczędzić dwa bajty . (Twoje rozwiązanie naprawdę zajmuje 241 bajtów, 239 znaków.)
Jonathan Frech
@JonathanFrech Thanks! Szukał znaku 1-bajtowego poza zakresem wydruku ASCII. Nie myślałem o użyciu niedrukowalnego ..
Kevin Cruijssen
2

DO, 407 368 bajtów

Podziękowania dla Jonathana Frecha za oszczędność bajtów.

golfed (file brack.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;}

bez udziału programu:

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

Skompilowany z gcc 5.4.1, gcc bracket.c

Tsathoggua
źródło
1
368 bajtów .
Jonathan Frech
387 z potrzebnymi włączeniami (dla realokacji). Zrobię czystą aktualizację (z wersją bez golfa) później. Dzięki
Tsathoggua
Jeśli używasz GCC, myślę, że kompilator spróbuje odgadnąć definicję obu malloci realloc, w tym stdlib.hsamodzielnie.
Jonathan Frech
Nie wiedziałem tego Przyjemna funkcja do gry w golfa kodowego. Dzięki.
Tsathoggua
2

Czerwony , 147 bajtów

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]

Nie golfowany:

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
]

Zacząłem uczyć się dialektu Red's Parse dopiero wczoraj, więc jestem pewien, że mój kod można jeszcze ulepszyć. Parsowanie jest nieporównanie bardziej szczegółowe niż wyrażenie regularne, ale jest bardzo jasne, elastyczne i czytelne i można je dowolnie mieszać z resztą języka czerwonego.

Wypróbuj online!

Galen Iwanow
źródło
1

Galaretka , 30 bajtów

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

Wypróbuj online!


Wyjaśnienie.


œṡ”]µḢ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.
użytkownik202729
źródło
1

C, 381 bajtów

Wersja kompaktowa:

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

Pełna wersja:

#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
źródło
3
Witamy w PPCG!
Shaggy
1
Witamy na stronie! Pamiętaj, że przesyłanie w C musi być pełnymi programami lub funkcjami, a nie tylko fragmentami.
MD XF
1

Python, 80 bajtów

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

Wypróbuj online!

s("[Foo[Bar]3]2")Konwertuje [Foo[Bar]3]2na''+('Foo'+('Bar')*3+'')*2+'' i ocenia.

Nie można wprowadzić danych z cudzysłowami w nawiasach (np. [']3)

ugoren
źródło
Poparłem tę odpowiedź, ponieważ pytanie wymaga obsługi wejściowego ASCII do wydruku, a ta odpowiedź nie. Powiadom mnie, jeśli to naprawisz, a ja chętnie wycofam mój głos.
caird coinheringaahing