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!



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

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


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 !


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.


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:

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

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>



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.


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.


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.


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:


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!


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

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



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!


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.

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

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)


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.