Bracket-Erweiterung!


36

Ihre Herausforderung besteht darin, einige Klammern in der Eingabe eines Programms wie folgt zu erweitern:

  1. Suchen Sie eine Zeichenfolge s zwischen zwei übereinstimmenden Klammern [und ]mit einer einzelnen Ziffer n nach der schließenden Klammer.
  2. Entfernen Sie die Halterungen.
  3. Ersetzen Sie s durch sich selbst n- mal wiederholt . (Wenn n 0 ist, entferne einfach s .)
  4. Fahren Sie mit Schritt 1 fort, bis die Eingabe keine übereinstimmenden Klammern mehr enthält.

Zusätzliche Regeln und Erläuterungen:

  • Sie nehmen Input und geben Output mit allen erlaubten Mitteln.
  • Ein Zeilenumbruch in der Ausgabe ist zulässig.
  • Sie müssen nur druckbares ASCII in der Eingabe behandeln.
  • Sie können davon ausgehen, dass alle Klammern übereinstimmen, dh Sie erhalten niemals die Eingabe []]]]oder [[[[].
  • Sie können davon ausgehen, dass ]hinter jeder schließenden Klammer eine Ziffer steht.

Testfälle:

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

Da dies , gewinnt die kürzeste Antwort in jeder Sprache. Viel Glück!



13
Sie sollten eine weitere Herausforderung veröffentlichen, um eine Zeichenfolge wieder auf das kürzeste Format zu komprimieren
Jo King

Lohnt es sich ausdrücklich zu erwähnen, dass Ihre Zeichenkette sniemals andere Klammern enthalten sollte? Der Versuch, eine Lösung [Foo[Bar]3]2durch Foo[BarFoo[BarFoo[BarFoo[Bar]2
dreimaliges

@BradC Das hängt davon ab, wie Sie die Aufgabe implementieren.
MD XF

Bedeutet das, dass es zwei gültige Antworten gibt [a[b]2c[d]2e]2? Sie erhalten, abbcddeabbcddeindem Sie sich ausdehnen bund dzuerst, aber, ababcdbcdedbabcdbcdedeindem Sie sich ausdehnen a[bund d]2ezuerst.
BradC

Antworten:


13

Gema , 17 Zeichen

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

Probelauf:

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

Wow, reden Sie darüber, die richtige Sprache für den Job zu finden!
MD XF

Oder der richtige Job für die Sprache. Viele Herausforderungen mussten übersprungen werden, weil das rekursive Argument nicht flexibel genug war.
Manatwork

Akzeptiere dies jetzt, weil ich nicht sehe, wie es schlagen wird, aber es wird in dem unwahrscheinlichen Fall, dass es dies tut, nicht akzeptiert.
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)

Probieren Sie es online! Anstatt reguläre Ausdrücke wie die meisten anderen Antworten zu verwenden, wird ein rekursiver Parser implementiert.

-5 Bytes dank BMO !


4
Eine Fixity-Deklaration für (%)sichert Ihnen 1 Byte und ['1'..d]sichert Ihnen weitere 4, siehe hierzu .
30.

3
@BMO Nizza, ich hatte nicht erwartet, dass eine Festigkeitserklärung jemals für das Code-Golfen nützlich sein würde. Ich denke, Sie sollten das zur Frage der Tipps hinzufügen.
Laikoni

7

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

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

Probieren Sie es online!

Reduzieren Sie es mit Hilfe von @Shaggy und @TonHospel.


3
Ich kenne keine Perle, aber Redo scheint großartig!
Amtszeit

Ich denke, Sie sollten in der Lage sein, ein Byte zu speichern, indem Sie das nicht entkommen ].
Shaggy

1
Ich kenne Perl nicht, aber das scheint für 30 + 1 Bytes zu funktionieren.
Shaggy

2
Diese 29 + 1 funktionieren auch: perl -pe 's/.([^[]*?)](.)/$1x$2/e&&redo'undperl -pe 's/.([^][]*)](.)/$1x$2/e&&redo'
Ton Hospel

5

Japt v2 , 21 20 19 Bytes

2 Bytes dank @Shaggy gespart

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

Online testen!

eist rekursives Ersetzen, dh es wird jeweils ein Ersatz erstellt, bis keine Übereinstimmungen mehr vorhanden sind. In diesem Fall werden Übereinstimmungen des regulären Ausdrucks /\[([^[]*?)](\d)/gdurch <innerer Text> ersetzt, die <Ziffern> Male wiederholt werden, bis keine Übereinstimmungen mehr vorhanden sind.

Nach meinem Plan ( hier ) sollte dieser reguläre Ausdruck mindestens 3 bis 2 Byte kürzer sein:

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

2
Wie wir „ annehmen können , dass jeder Schließbügel ]eine Ziffer nach hat es sollten Sie in der Lage sein , zu ersetzen“ (\dmit (..
Shaggy

Sie können auch ersetzen \[mit.
Shaggy

@ Shaggy Schön, danke!
ETHproductions

4

JavaScript, 71 67 66 Bytes

Ich hatte eine 54-Byte-Lösung, aber sie wurde durch den zweiten Testfall beschädigt! :(

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

Testfälle

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

Probieren Sie es online!

Erweitert:

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

Alte Lösung

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

Probieren Sie es online!

Erweitert:

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

Wobei l die Liste der Zeichenfolgen ist, die wir verarbeiten werden.

Vielen Dank an Kevin Cruijssen für -1 Byte

Ging von 212 bis 199 durch Entfernen eines nicht verwendeten Parameters, achtete nicht darauf.


4
Willkommen bei PPCG! Probieren Sie den Scala-Interpreter von tio unter tio.run/#scala aus und sehen Sie, ob Sie einen Link für die Antwort einreichen können, damit andere ihn online ausprobieren können. :)
offiziell am

2
Danke! Ich habe die Antwort so bearbeitet, dass sie den Link enthält. Hoffentlich ist es in Ordnung, wie der Header, der Code und die Fußzeile deklariert werden, um eine ordnungsgemäße Einreichung zu gewährleisten.
Shikkou

1
Hallo, willkommen bei PPCG! Tolle erste Antwort, +1 von mir. Ich glaube , Sie 1 Byte speichern können , indem (\d)an (.), weil wir eine Block-Halterung wissen ]immer gefolgt von einer Ziffer wird.
Kevin Cruijssen

3

Gestapelt , 39 38 Bytes

Dank Shaggy 1 Byte gespart, Regex golfen!

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

Probieren Sie es online!

Ersetzt einfach rekursiv einen regulären Ausdruck '\[([^[\]]+)](.)'durch die Wiederholungsregel.


Ich denke, Sie können ein Byte sparen, indem Sie das letzte nicht entkommen ].
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

Probieren Sie es online

Danke an HyperNeutrino und Mego für -47 Bytes und user202729 für -4 Bytes.


Machen Sie es zu einem 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
Einzeiler

3

JavaScript - 77 75 72 Bytes

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

Bearbeiten: Regex mit Shaggys Empfehlung aktualisiert

Snippet:


2
Willkommen bei PPCG! Sie können dies auf 70 Bytes reduzieren, indem Sie Ihren RegEx optimieren.
Shaggy

Ja, 72 Bytes, offensichtlich, sorry; Ich vergaß das zu zählen f=!
Shaggy

2

QuadR mit dem Argument, 30 28 Bytes

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

Probieren Sie es online!

\[[^[]+?]. Ersetzen Sie " [non- [stuff ]character" durch

¯2↓⍵M die letzten beiden Zeichen des Tropfens M atch ( „ ]digit‚)
1↓ fallen das erste Zeichen (‘ [“)
 einschließen als Ganzes behandelt zu werden
(... )⍴r eshape auf Länge:
⌽⍵M Umkehren der M atch
 die erste (die Ziffer) Wählen
 auszuwerten
ε nlist ( ebnen)

 Wiederholen, bis keine Änderungen mehr vorgenommen werden


Die äquivalente Dyalog APL-Funktion ist 47 Bytes:

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

Probieren Sie es 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 dank @JonathanFrech (Code enthält jetzt zwei nicht druckbare ASCII-Zeichen, die im TIO-Link unten zu sehen sind).

Seufz ... Java mit Regex ist so verdammt begrenzt. Ich zitiere mich einfach aus einer anderen Antwort hier:

Ersetzen WWWWmit 222Wist in Java einfach, aber 4Wnicht. Wenn nur Java die Möglichkeit hätte, die Regex-Erfassungsgruppe für etwas zu verwenden. Ermitteln der Länge mit "$1".length(), Ersetzen der Übereinstimmung durch "$1".replace(...), Konvertieren der Übereinstimmung in eine Ganzzahl mit new Integer("$1")oder Verwenden von Etwas Ähnliches wie Retina (dh s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))oder JavaScript (dh s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0)))) wäre meine Nummer 1, die ich in Zukunft gerne in Java sehen würde, um das Codegolfing zu fördern alles mit dem Capture-Group-Match ..
Zitat von hier.

Erläuterung:

Probieren Sie es online aus.

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
Ich denke, Sie können ein echtes ASCII-Zeichen verwenden, obwohl es nicht druckbar ist, um zwei Bytes zu sparen . (Ihre Lösung dauert wirklich 241 Bytes, 239 Zeichen.)
Jonathan Frech

@ JonathanFrech Danke! Suchte nach einem 1-Byte-Zeichen außerhalb des druckbaren ASCII-Bereichs. Ich habe nicht daran gedacht, eine nicht druckbare zu verwenden.
Kevin Cruijssen


2

C 407 368 Bytes

Vielen Dank an Jonathan Frech für das Speichern von Bytes.

golfed (dateiklammer.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 mit programm:

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

Kompiliert mit gcc 5.4.1, gcc bracket.c



387 mit dem benötigten Include (für Realloc). Ich werde später ein sauberes Update (mit der ungolfed Version) machen. Vielen Dank
Tsathoggua

Wenn Sie GCC verwenden, wird der Compiler meines Erachtens versuchen, die Definition von beiden mallocund realloc, auch stdlib.hvon sich aus, zu erraten .
Jonathan Frech

Ich wusste das nicht. Nettes Feature zum Code-Golfen. Vielen Dank.
Tsathoggua

2

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

Ich habe erst gestern angefangen, Reds Parse-Dialekt zu lernen, daher bin ich sicher, dass mein Code weiter verbessert werden kann. Parse ist unvergleichlich ausführlicher als Regex, aber es ist sehr klar, flexibel und lesbar und kann frei mit dem Rest der roten Sprache gemischt werden.

Probieren Sie es online!


1

Gelee , 30 Bytes

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

Probieren Sie es online!


Erläuterung.


œṡ”]µḢ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

Kompakte Version:

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

Vollversion:

#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
Willkommen bei PPCG!
Shaggy

1
Willkommen auf der Seite! Beachten Sie, dass es sich bei C-Einsendungen um vollständige Programme oder Funktionen handeln muss, nicht nur um Snippets.
MD XF

1

Python, 80 Bytes

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

Probieren Sie es online!

s("[Foo[Bar]3]2")Konvertiert [Foo[Bar]3]2zu ''+('Foo'+('Bar')*3+'')*2+''und wertet aus.

Eingabe mit Anführungszeichen in Klammern schlägt fehl (z. B. [']3)


Ich habe diese Antwort abgelehnt, da die Frage die Behandlung von druckbarem ASCII in der Eingabe erfordert, und diese Antwort nicht. Benachrichtigen Sie mich, wenn Sie das Problem beheben, und ich werde meine Abstimmung gerne widerrufen.
Caird Coinheringaahing
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.